Flexbox: колонна flex-flow; flex-base 100% не работает без явной высоты - PullRequest
0 голосов
/ 01 мая 2020

Я создаю для себя веб-сайт с макетом содержимого из двух столбцов, где столбцы имеют соотношение сторон 1: 2, и я стараюсь избегать использования Grid для чего-то, что, по моему мнению, Flexbox может более чем легко обработать. Однако все мои попытки принудительного переноса из узкого левого столбца в широкий правый столбец с использованием flex-basis: 100%; не работают без явной, non процент высоты, установленной для родительского элемента. Я не знаю что делать Я уже использовал эту статью и ссылался на несколько вопросов для решения, и буквально ничего не помогло.

Я использую Firefox 72, и это должно работать в последних версиях Firefox.

:root {
  --bodywidth: 80vw;
  --flexbasis: calc(var(--bodywidth) / 8);
  --spacebasis: calc(var(--flexbasis) / 12);
  --columnwidth: calc(var(--bodywidth) / 3);
}


/* https://tobiasahlin.com/blog/flexbox-break-to-new-row/ */

hr.break {
  border: none;
  margin: 0;
  padding: 0;
  flex-basis: 100%;
  flex-grow: 1;
}

hr.row.break {
  height: 0;
}

hr.col.break {
  width: 0;
}

main {
  display: flex;
  flex-flow: column wrap;
  /* height: 100%; /* << DOES NOT WORK */
  /* height: 100vw; /* << Works perfectly fine, but NOT ideal */
}


/* vv As a bonus, these rules somehow make everything 2 column widths wide when only the stuff AFTER the break should be that wide */

main :not(.break) {
  min-width: var(--columnwidth);
  width: 100%;
}

main hr.break+* {
  width: calc(var(--columnwidth) * 2);
}
<main>
  <section>
    <h1>About</h1>
    <p>Blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah.</p>
  </section>

  <section>
    <h1>Disclaimer</h1>
    <p>Here there be naughty things!!!</p>
  </section>

  <!-- The amount of content on both sides of the break varies, as do the dimensions of the sections -->
  <hr class="col break" />

  <article class="blog">
    <h1>Blog Entry</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eleifend molestie orci. Donec pellentesque viverra magna, nec viverra velit laoreet non. Etiam blandit erat nulla, semper faucibus eros rhoncus vel.</p>
  </article>

</main>

Если мне нужно, я могу держать нос и использовать Grid и заставить его работать, но это не идеально для любого натяжения воображения и потребует много лишних CSS чтобы все заработало. Я бы предпочел использовать Flexbox, если у кого-то есть решения.

Ответы [ 2 ]

1 голос
/ 02 мая 2020

grid и mediaquer ie - это, имхо, хороший способ управления переключением с макета из 1 столбца в макет из 2 столбцов.

Демонстрация идеи:

:root {
/* possible use of var here */
--col1 : 1fr;
--col2 : 2fr;
}
main {
  display: grid;
  grid-template-columns: var(--col1) var(--col2);
}
main> * {
  border:solid 1px;
  margin:2px;
}
section {
  grid-column:1;
}
article {
  grid-column:2;
  grid-row:1 / 10;
}

/* breakpoint at 768px */
@media screen and (max-width: 768px) {
  main {
    display: flex;
    flex-flow: column;
  }
  main section + section {/* best is to use an id */
    order: 1;
  }
}
<main>
  <section>
    <h1>About</h1>
    <p>Blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah.</p>
  </section>
  <section><! -- that one might deserve an id to easy reorder its position -->
    <h1>Disclaimer</h1>
    <p>Here there be naughty things!!!</p>
  </section>
  <article class="blog">
    <h1>Blog Entry</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eleifend molestie orci. Donec pellentesque viverra magna, nec viverra velit laoreet non. Etiam blandit erat nulla, semper faucibus eros rhoncus vel.</p>
  </article>

</main>
0 голосов
/ 02 мая 2020

Я смог выяснить способ обхода хаки sh, используя javascript. Это, вероятно, уникально для моего варианта использования, поэтому я не собираюсь отмечать это как принятый ответ, но я публикую его здесь на тот случай, если кому-то понадобится его для собственного использования! Этот хак работает с точно таким же HTML + CSS, как указано выше:

var timerID = 0;

// This function saves CPU cycles and user sanity when resizing the browser window!
// It just destroys and creates a timeout as the resize event gets rapid fired
function resizeDelay() {
    if(timerID) clearTimeout(timerID);
    timerID = setTimeout(recomputeMainHeight,500);
}

// THIS function does all the magic!
function recomputeMainHeight(mainElts) {
    // Get the computed margins of the elements in the columns
    var margin = parseInt(window.getComputedStyle(mainElts[0]).marginBottom) * 2;

    // Find the index of the break element
    var breakIndex = 0;
    while(mainElts[breakIndex].nodeName != "HR") breakIndex++;

    /*  The height of the left column is equal to:
        The box bottom coordinate of the break's preceding sibling, MINUS
        The box top coordinate of the first child node in the container, PLUS
        The margin width of the elements in the flex TIMES the number of items BEFORE the break
    */
    var leftColContentHeight =
        mainElts[breakIndex].getBoundingClientRect().bottom -
        mainElts[0].getBoundingClientRect().top +
        margin * breakIndex;
    /*  The height of the right column is equal to:
        The box bottom coordinate of the last child node in the container, MINUS
        The box top coordinate of the break's following sibling, PLUS
        The margin width of the elements in the flex TIMES the number of items AFTER the break
    */
    var rightColContentHeight =
        mainElts[mainElts.length - 1].getBoundingClientRect().bottom -
        mainElts[breakIndex + 1].getBoundingClientRect().top +
        margin * (mainElts.length - 1 - breakIndex);

    //  Set the greater of the two values as the height of the container
    document.querySelector("main").style.height =
        (leftColContentHeight > rightColContentHeight ?
        leftColContentHeight :
        rightColContentHeight) + "px";
}

//  This function sets the widths of everything dependign on their relation to the break
function bootstrap() {
    //  Fetch a list of all fist-gen children of the container
    var mainElts = document.querySelectorAll("main > *");

    var pastBreak = false;
    //  Loop through the NodeList...
    for(elt of mainElts) {
        //  If the loop finds the break element, set the flag and continue
        if(elt.nodeName === "HR") {
            pastBreak = true;
            continue;
        }
        //  If the loop is past the break, set the width to the wide column, else the narrow column
        if(pastBreak) elt.style.width = "calc(var(--columnwidth) * 2)";
        else elt.style.width = "var(--columnwidth)";
    }

    //  Call the function that works the hack magic above
    recomputeMainHeight(mainElts);
}

//  Some event listeners
window.addEventListener('load',bootstrap);
window.addEventListener('resize',resizeDelay);

ПРЕДУПРЕЖДЕНИЯ:

  1. Я не проверял это в IE или Safari / WebKit; Я читал, что Safari / WebKit сообщает о различных значениях getComputedStyle(), поэтому, если вы хотите поддерживать Safari / WebKit, вам придется соответствующим образом адаптировать его. Вероятно, мне придется сделать это самому, когда я начну тестировать эту страницу на моем fruityPhone и fruityPad.
  2. Небольшая визуальная ошибка будет присутствовать между Firefox и Chrom (например,). Firefox НЕ учитывает поля при вызове elt.getBoundingClientRect() и вычислении всех чисел. Chrom (e | ium) ДЕЛАЕТ. Я выбрал адаптацию только для Firefox и допускаю избыток желоба в нижней части страницы, потому что установка высоты контейнера немного слишком высока предпочтительнее, чем немного слишком низкая, а вещи перекрывают друг друга, и последнее, что я хочу сделать, это боритесь с браузерным сниффингом.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...