gpt4 book ai didi

html - 是否可以像行内文本一样使行内 block 元素换行?

转载 作者:行者123 更新时间:2023-12-03 19:10:14 25 4
gpt4 key购买 nike

CSS display: inline带有文本的元素“流动”到一行的末尾,然后当容器对它们不够大时继续下一行。

inline text wrapping at container boundry

我想实现同样的水平环绕效果,但使用可以控制宽度的 block 元素。

如果我使用 display: inline-block这使我可以控制 block 的宽度,但是它可以防止换行。

inline-block elements not wrapping at container boundry

我似乎找不到任何允许我包装和控制元素宽度的 CSS 设置。但是,这似乎应该是可能的。大概浏览器自己的布局引擎在内部计算各种文本字符串的宽度后就会这样做。

我考虑过两种变通方法,它们可以为我提供所需的视觉输出:

Correct layout via work arounds

  • 将字体设置为等宽字体,并用计算出的正确数量的文本字符填充内联元素,然后隐藏这些字符。这与文本实际上仍然存在并且可以在页面上选择的事实存在问题。
  • 当 inline-block 元素应该包装并注入(inject)两个计算大小的较小块时,使用 javascript 一个用于第一部分,一个用于其余部分。在处理大量这些 block 时,这非常慢。

  • 这些都不是很好的解决方案,如果纯CSS可以做到这一点,我很想学习如何。

    以下是交互式呈现的屏幕截图中示例的链接:

    https://jsfiddle.net/n3wzd29v/

    let tags = document.getElementsByClassName("js");

    let currentLeft = 0;
    for (let i=0; i<tags.length; i++) {
    let tag = tags[i];

    // dont know how to get the "width this would be if it was not inline cleanly".
    tag.style.display="inline-block";
    let requestedWidth = tag.offsetWidth;
    tag.style.display="inline";

    let parentWidth = tag.parentNode.offsetWidth;

    console.log("requestedWidth:" + requestedWidth);
    console.log("parentWidth:" + parentWidth);
    console.log("currentLeft:" + currentLeft);


    //FIXME: handle spanning over arbitary number of lines.
    if ((currentLeft + requestedWidth) < parentWidth) {
    // Got plenty of space for this element on this line so just make it a inline-block
    tag.style.display = "inline-block";
    currentLeft += requestedWidth;
    console.log("Just setting inline-block, its wide enough");
    } else {
    // This element needs breaking up into two elements, one for the part that fits on this
    // line, and another for the remainder on the next line.
    let part1Width = parentWidth - currentLeft;
    let part1 = document.createElement("span");
    part1.style.display = "inline-block"
    part1.style.width = part1Width + "px";
    part1.style.verticalAlign = "top";
    part1.style.height = "16px";

    let part2Width = requestedWidth - part1Width;
    let part2 = document.createElement("span");
    part2.style.display = "inline-block"
    part2.style.width = part2Width + "px";
    part2.style.verticalAlign = "top";
    part2.style.height = "16px";

    currentLeft = 0 + part2Width;

    tag.appendChild(part1);
    tag.appendChild(part2);
    console.log("Adding two fixed width children: " + part1Width + " " + part2Width);
    }
    }
    .container {
    width: 200px;
    background-color: lightblue;
    }

    span {
    word-break: break-all;
    font-family: monospace;
    }

    .bad {
    display: inline-block;
    height: 16px;
    }

    .stuffed {
    line-height:22px;
    }

    .js {
    height: 15px;
    vertical-align: top;
    }

    .color1 {
    background-color: hsl(0, 80%, 50%);
    }
    .color2 {
    background-color: hsl(20, 80%, 50%);
    }
    .color3 {
    background-color: hsl(40, 80%, 50%);
    }
    .color4 {
    background-color: hsl(60, 80%, 50%);
    }

    .color1.stuffed {
    color: hsl(0, 80%, 50%);
    }
    .color2.stuffed {
    color: hsl(20, 80%, 50%);
    }
    .color3.stuffed {
    color: hsl(40, 80%, 50%);
    }
    .color4.stuffed {
    color: hsl(60, 80%, 50%);
    }
    <html>
    <body>

    <p>Inline elements with text in them "flow" over the end of a line
    and then carry on the next line when the container isn't large enough for them.
    </p>

    <div class="container">
    <span class="good color1">These inline</span><span class="good color2">spans will wrap over</span><span class="good color3">the end of the container</span><span class="good color4">exactly how i would like them to</span>
    </div>


    <br/>

    <p>
    However i want to do the same layout but with block elements that i can set
    the width of. Using inline-block allows me to control the block width however
    it seems to prevent line-breaking from working.
    </p>

    <div class="container">
    <span class="bad color1" style="width:96px"></span><span class="bad color2" style="width:160px"></span><span class="bad color3" style="width:192px"></span><span class="bad color4" style="width:256px"></span>
    </div>


    <p>
    Obviously i can acheieve something of the same behaviour by stuffing my inline
    elements with hidden text, but that seems sub-optimal
    </p>
    <div class="container">
    <span class="stuffed color1">████████████</span><span class="stuffed color2">████████████████████</span><span class="stuffed color3">████████████████████████</span><span class="stuffed color4">████████████████████████████████</span>
    </div>

    <p>
    Finally, it is ofc also possible to fix this problem in javascript, but i'm tenative
    to do layout in javascript when the browser already clearly have a well optimised
    layout engine for doing this on text already.
    </p>

    <div class="container">

    <span class="js color1" style="width:96px"></span><span class="js color2" style="width:160px"></span><span class="js color3" style="width:192px"></span><span class="js color4" style="width:256px"></span>

    </div>

    <br/>
    <br/>
    <br/>

    </body>
    </html>

    最佳答案

    如果这只是为了视觉目的,那么您可能有一种方法可以使用跨度元素来应用多个渐变。

    这是一个不言自明的例子:

    .container {
    width: 200px;
    padding:5px;
    background-color: lightblue;
    text-align:justify;
    }

    span {
    padding:0;
    background-image:
    linear-gradient(hsl(0, 80%, 50%),hsl(0, 80%, 50%)),
    linear-gradient(hsl(20, 80%, 50%),hsl(20, 80%, 50%)),
    linear-gradient(hsl(40, 80%, 50%),hsl(40, 80%, 50%)),
    linear-gradient(hsl(60, 80%, 50%),hsl(60, 80%, 50%));
    background-size:
    100px 100%, /* 1st color width = 100px */
    280px 100%, /* 2nd color width = 280px - 100px = 180px */
    450px 100%, /* 3rd color width = 450px - 280px = 170px */
    520px 100%; /* 4th color width = 520px - 450px = 70px */
    background-repeat:no-repeat;
    }

    /* we fill the span with content */
    span::before,
    span::after{
    content:"█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █";
    color:transparent;
    }
    <div class="container">
    <span ></span>
    </div>


    这是另一个非常疯狂的想法,我将依赖列的使用:

    .container {
    height: 120px; /* this will define the visual width of container */
    column-width: 20px; /* this will define the visual height of rows*/
    display: inline-block;
    column-gap: 4px; /* gap between rows */
    /* this transformation will invert everything like we want */
    transform-origin: top left;
    transform: rotate(90deg) scaleY(-1);
    /**/
    }

    span {
    display: block;
    }

    span:hover {
    filter: invert(1);
    }
    /* all the height below will define the visual width */
    span:nth-child(1) {
    background: hsl(0, 80%, 50%);
    height: 80px;
    }

    span:nth-child(2) {
    background: hsl(20, 80%, 50%);
    height: 100px;
    }

    span:nth-child(3) {
    background: hsl(40, 80%, 50%);
    height: 80px;
    }

    span:nth-child(4) {
    background: hsl(60, 80%, 50%);
    height: 200px;
    }
    <div class="container">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    </div>

    关于html - 是否可以像行内文本一样使行内 block 元素换行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62433455/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com