首页  >  问答  >  正文

尝试溢出 HTML <pre><code> 标签而不是换行时,Flex 间距被破坏

我将 CSS 应用到 pre code 选择器,以便制作样式代码块,就像您在 GitHub 或其他地方看到的那样。我使用 Flexbox 进行布局,并且在“框”div 内并排有两个“面板”div,其中一个有一个代码块(这只是 <pre><code> 标签内的代码),以及“box”div 位于主“container”div 内部。

我拥有的基本 CSS 是...

.*, *:before, *:after {
    margin: 0;
    padding: 0;
    box-sizing: inherit;
}

html {
    box-sizing: border-box;
}

body {
    display: flex;
    align-items: center;
    justify-content: center;
}

pre code {
    display: inline-block;
    overflow: auto;
    white-space: pre;
    padding: 1rem;
    margin: 1rem;
}

.container {
    display: flex;
    flex-direction: column;
    margin: 1rem;
    gap: 1rem;
}

.box {
    display: flex;
    flex-direction: row;
    gap: 1rem;
}

.panel {
    display: flex;
    flex-direction: column;
    flex: 0.5;
    padding: 1rem;
}

由于 flex: 0.5,两个面板的宽度应相等,但是右侧面板会扩展以适合块,而不是块缩小以适合面板。

如果我在 pre code 上设置 white-space: pre-wrap ,我会得到所需的布局行为,但当然代码是自动换行的,这是我不想要的。

当然,如果我使用 white-space: pre 并向 pre 代码 添加专用宽度,我会得到所需的行为,其中代码块有一个水平滚动条。我无法使用专用宽度,因为我需要该块来适应其内部的任何面板。

出于某种原因,在 pre 代码 上设置 width: 100% 根本没有任何作用。

为了确保我自己不会在其他地方做一些事情而导致此错误,我将这段代码放在一起以确认我的问题(我确实添加了一些背景颜色和边距以使容器可见):

https://codepen.io/evprkr/pen/poKQXJr

P粉277464743P粉277464743218 天前371

全部回复(1)我来回复

  • P粉621033928

    P粉6210339282024-04-02 11:59:47

    CSS 问题导致您遇到问题:

    1. 在 CSS 的第一行 .*, *:before, *:after { } 中,有一个很容易错过的初始 . (点)。因此 border-box 模型仅适用于 :before:after 伪元素。显然,marginpadding 也是如此。
    2. 所有 .panel 祖先都没有设置 width 值,这样 flexbox 就无法约束子元素,并且会增长到无穷大。
    3. flex: 0.5 (默认为 flex: 0.5 1 0%)显然没有效果,因为它没有宽度 flex-basis: 50%。在这两种情况下,pre 代码 都不会被触发溢出,因此不会显示可滚动框。我无法解释原因,但这一定是由于某些 W3C 规范造成的。不过,您声明的 .panel width: 50% 最终解决了这个问题。
    4. 在调整浏览器/codepen 大小时,将 margins 与各种元素和 gap 结合使用会产生看似意外的元素重叠。即使删除了上述初始 .

    解决方案

    • 广告 1) 删除 .(点)
    • ad 2) 指定 .container 宽度:100%flexbox 提供一个可使用的约束。
    • ad 3) 删除 .panel flex: 0.5 并指定 .panel 宽度: calc(50% - 0.5rem)calc(..) 是必需的,因为 gap 会增加 .panels 的总宽度,可能导致它们在调整大小时重叠。由于您的 ngap: 1rem0.5rem 添加到两列中的每一列,因此需要从每列的 width 中减去该值。
    • 4) 与 ngap 一样,margin 会增加元素的总宽度,这需要您从元素宽度中减去左和/或右边距,以防止它们与其他元素重叠。避免在 CSS 中添加额外 calc(..) 的最简单方法是将元素的 margin 移动到其直接父元素的 padding 。并非在所有情况下都是如此,但在这种情况下,它在不改变整体布局的情况下效果很好。

    奖金

    对于响应行为

    • 允许 .box 包裹其子元素
    • 设置一些所需的最小 .panel 宽度 以强制 .box 包裹其子 .panels。在本例中我选择了 300px
    • 这需要在不包装时允许 .panel 元素增长到完整的 50%

    还有 hyphenate 文本以提高可读性...

    片段

    *, *:before, *:after {
        margin: 0;
        padding: 0;
        box-sizing: inherit;
    }
    
    html {
        box-sizing: border-box;
    }
    
    body {
        display: flex;
        align-items: center;
        justify-content: center;
    }
    
    pre code {
        background: #d7d7db;
        display: block;
        overflow: auto;
        white-space: pre;
        padding: 1rem;
    
    }
    
    .container {
        background: #0197f4;
        display: flex;
        flex-direction: column;
        padding: 1rem;
        width: 100%;
    }
    
    .box {
        background: #ff7538;
        display: flex;
        flex-flow: row wrap;
        gap: 1rem;
        padding: 1rem;
    }
    
    .panel {
        background: #fff;
        display: flex;
        flex-direction: column;
        padding: 2rem;
    
        /* Adjust for parent gap value */
        width: calc(50% - 0.5rem);
    
        /* Allow to grow and wrap when less than 300px */
        flex: 1;
        min-width: min(300px, 100%);
    }
    
    .text { hyphens: auto }
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi accumsan mattis ullamcorper. Nulla tincidunt aliquam feugiat. Sed imperdiet tellus ligula, vehicula condimentum neque venenatis ut. Aenean varius elementum nulla, vehicula laoreet erat aliquam at. Nullam venenatis ex id tincidunt fringilla. Vivamus nec tellus sit amet leo tristique luctus. Cras elementum at diam at viverra. Phasellus tristique elementum velit id tincidunt. Nullam ullamcorper fringilla nulla sed ultricies.
    function SomeFakeFunction(first_argument, second_argument) {
        if (first_argument > second_argument) {
            return "first argument is greater than second argument";
        } else if (first argument < second_argument) {
            return "first argument is less than second argument";
        }
        
        return "first argument and second argument are equal (or invalid but this is just filler code so i don't care to write anymore honestly)"
    }

    回复
    0
  • 取消回复