繁体   English   中英

Flexbox:柔性流柱; flex-basis 100% 在没有明确高度的情况下无法工作

[英]Flexbox: flex-flow column; flex-basis 100% not working without explicit height

我正在为自己构建一个具有两列内容布局的网站,其中列的纵横比为 1:2,并且我试图避免将 Grid 用于我认为 Flexbox 可以轻松处理的内容。 但是,我所有尝试使用flex-basis: 100%;强制从窄左列到宽右列的换行。 如果没有为父元素设置显式的非百分比高度,则无法工作。 我不知道该怎么办。 我已经使用了这篇文章并参考了多个问题的解决方案,但实际上没有任何效果。

我正在使用 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。

恕我直言,grid 和 mediaquerie 是管理从 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>

我能够使用 javascript 找出一个骇人听闻的解决方法。 这可能是我的用例所独有的,因此我不会将其标记为已接受的答案,但我会在此处发布它以防有人需要它用于自己的用途:此 hack 适用于完全相同的 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(e|ium) 之间会出现一个小的视觉错误。 elt.getBoundingClientRect()并计算所有数字时,Firefox 不考虑边距。 铬(e | ium)可以。 我选择仅适用于 Firefox 并接受页面底部多余的装订线,因为将容器高度设置得稍微太高比稍微太低更可取,并且让东西相互重叠,我想做的最后一件事就是与浏览器嗅探。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM