【问题标题】:text-overflow: ellipsis in a flexbox in a grid column文本溢出:网格列中弹性框中的省略号
【发布时间】:2021-12-17 00:22:54
【问题描述】:

我正在尝试实现以下布局:具有多个固定宽度列的网格,其中一个具有未知宽度的内容,它将由多个 span 元素组成,不会换行,并且必须被截断省略号。

一个更具体的例子:

这是我尝试过的,但没有成功,使用 flexbox:

.grid {
  width: 300px;
  border: 1px solid black;
  display: grid;
  grid-template-columns: [main] minmax(0, 1fr) [foo] 20px [bar] 20px
}

main {
  grid-column: main;
  white-space: nowrap;
  background: yellow;
}

.color-marker {
  height: 10px;
  width: 10px;
  background: red;
  border-radius: 50%;
}

.test {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

.test > * {
  flex: 0 0 auto;
}


.foo {
  grid-column: foo;
  height: 20px;
  width: 20px;
  background-color: orange;
}

.bar {
  grid-column: bar;
  height: 20px;
  width: 20px;
  background-color: purple;
}
<div class="grid">
  <main>
    <div class="test">
      <div class="color-marker"></div>
      
      <span>
        Lorem ipsum
      </span>

      <span>
        sed do eiusmod tempor incididunt ut labore
      </span>

    </div>
  </main>
  <div class="foo">
  </div>
  <div class="bar">
  </div>
</div>

same example on jsbin

我还尝试使用内联网格而不是 flexbox,但这也没有帮助 (example on jsbin)。

有没有办法让它工作?

免责声明:我意识到这个问题的变体已经在 Stack Overflow 上提出过;但没有一个建议的解决方案对我有用。以下是我检查过的线程:

我希望这不会使我的问题重复。

【问题讨论】:

    标签: css layout flexbox


    【解决方案1】:

    首先,看看这是否满足您的需求。请参阅代码 cmets 了解所做的更改。

    编辑:现在任何一个跨度,但只有 1 个跨度,都会导致省略号。

    编辑 2:这不会导致省略号继承其中一个跨度的颜色。省略号颜色可以在.spanContainer中独立设置。

    .grid {
      width: 300px;
      border: 1px solid black;
      display: grid;
      grid-template-columns: [main] minmax(0, 1fr) [foo] 20px [bar] 20px
    }
    
    main {
      grid-column: main;
      white-space: nowrap;
      background: yellow;
    }
    
    .color-marker {
      height: 10px;
      width: 10px;
      background: red;
      border-radius: 50%;
      align-self: center;       /*<------------ added */
      flex: 1 0 auto;           /*<------------ added */
    }
    
    .test {
      display: flex;            
      justify-content: flex-start;  /*<------------ changed */
    }
    
    /* .test > * {                <------------ removed
      flex: 0 0 auto;
    } */
    
    .spanContainer {            /*<------------ added */
      overflow: hidden;         /*<------------ added */
      white-space: nowrap;      /*<------------ added */
      text-overflow: ellipsis;  /*<------------ added */
      width: 100%;              /*<------------ added */
      color: purple;            /*<------------ added set ellipsis color here*/
    }
    
    .foo {
      grid-column: foo;
      height: 20px;
      width: 20px;
      background-color: orange;
    }
    
    .bar {
      grid-column: bar;
      height: 20px;
      width: 20px;
      background-color: purple;
    }
    
    .span1 {
      color: red;
      font-size: 1rem;
    }
    
    .span2 {
      color: green;
      font-size: 0.5rem;
    }
    <div class="grid">
      <main>
        <div class="test">
          <div class="color-marker"></div>
          <div class="spanContainer">
            <span class="span1">
              Lorem ipsum
            </span>
    
            <span class="span2">
              sed do eiusmod tempor incididunt ut labore sed do eiusmod tempor incididunt ut labore
            </span>
          </div>
        </div>
      </main>
      <div class="foo">
      </div>
      <div class="bar">
      </div>
    </div>

    【讨论】:

    • 我使用几个 span 的原因是因为它们的格式可以不同(不同的字体大小等);但它们应该表现为单行,即截断应该只从溢出父包装器的跨度开始。在您的示例中,包含“Lorem ipsum”的跨度也被截断。这不适用于我的情况。
    • @azangru - 查看编辑。
    • 啊哈,这样更好。我相信它会遇到与我在下面的答案 (stackoverflow.com/a/69812073/3925302) 相同的问题,即如果截断的跨度与父项的样式不同,则省略号仍将具有父项的样式。
    • @azangru - 它不受您提到的问题的影响。我做了另一个编辑来演示。
    • 抱歉不清楚。我的意思是,它必然适用于容器组件的样式(在您的示例中称为spanContainer)的省略号。然而,作为人类读者,您会期望省略号与恰好被截断的子文本具有相同的样式:-(
    【解决方案2】:

    我举个例子:

    .grid {
      width: 300px;
      border: 1px solid black;
      display: inline-grid;
      grid-template-columns: [main] minmax(0, 1fr) [foo] 20px [bar] 20px;
       overflow: hidden;
    }
    
    main {
      grid-column: main;
      white-space: nowrap;
      background: yellow;
    }
    
    .color-marker {
      height: 10px;
      width: 10px;
      background: red;
      border-radius: 50%;
    }
    
    .foo {
      grid-column: foo;
      height: 20px;
      width: 20px;
      background-color: orange;
    }
    
    .bar {
      grid-column: bar;
      height: 20px;
      width: 20px;
      background-color: purple;
    }
    
    .test {
        display: flex;   
         align-items: baseline;
          gap: 0.2rem;
    }
    .l {
        width: 10%;
        flex-shrink: 1;
        display: flex;
    }
    
    .m-content {    
        text-align: center;
    }
    
    .color-marker {
      height: 10px;
      width: 10px;
      background: red;
      border-radius: 50%;
    }
    <!DOCTYPE html>
    <html>
    
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>JS Bin</title>
      </head>
    
      <body>
        <div class="grid">
          <main>
            <div class="test">
              <div class="l">
                <div class="color-marker"></div>
              </div>
              <div class="m">
                <div class="m-content">
                  <span>
                    Lorem ipsum
                  </span>
                  <span>
                    sed do eiusmod tempor incididunt ut labore
                  </span></div>
              </div>
            </div>
          </main>
          <div class="foo">
          </div>
          <div class="bar">
          </div>
        </div>
    
      </body>
    
    </html>

    【讨论】:

      【解决方案3】:

      我将发布一个我希望改进的基线解决方案。它有明显的缺点。这也有点欺骗了这个问题,因为它背离了 flexbox 并使用了一个简单的display: block。从好的方面来说,它可以截断跨度中的文本。然而,不利的一面是,如果子跨度具有与父跨度不同的样式,则省略号仍将具有父跨度的样式(通过使用红色和黑色在下面的示例中看到)。

      有没有办法让它变得更好?

      .grid {
        width: 300px;
        border: 1px solid black;
        display: grid;
        grid-template-columns: [main] minmax(0, 1fr) [foo] 20px [bar] 20px
      }
      
      main {
        grid-column: main;
        white-space: nowrap;
        background: yellow;
      }
      
      .color-marker {
        display: inline-block;
        height: 10px;
        width: 10px;
        background: red;
        border-radius: 50%;
      }
      
      .test {
        overflow: hidden;
        text-overflow: ellipsis;
        color: red;
      }
      
      .text-secondary {
        font-size: 10px;
        color: grey;
      }
      
      .foo {
        grid-column: foo;
        height: 20px;
        width: 20px;
        background-color: orange;
      }
      
      .bar {
        grid-column: bar;
        height: 20px;
        width: 20px;
        background-color: purple;
      }
      <div class="grid">
        <main>
          <div class="test">
            <div class="color-marker"></div>
            
            <span>
              Lorem ipsum
            </span>
      
            <span class="text-secondary">
              sed do eiusmod tempor incididunt ut labore
            </span>
      
          </div>
        </main>
        <div class="foo">
        </div>
        <div class="bar">
        </div>
      </div>

      【讨论】:

        【解决方案4】:

        我们可以在跨度上使用增加flex-shrink。以下是三个span 的最小工作示例:

        <html>
        
        <head>
          <script>
            function changeWidth(newWidth) {
              document.getElementById("test").style.width = newWidth;
            }
          </script>
          <style media="all">
            .color-marker {
              height: 10px;
              width: 10px;
              background: red;
              border-radius: 50%;
              display: inline-block;
            }
            
            .test {
              background: yellow;
              align-items: baseline;
              width: 200px;
              white-space: nowrap;
              overflow: hidden;
              text-overflow: ellipsis;
            }
            
            .test span {
              color: red;
            }
            
            .test :nth-child(1) {
              flex-shrink: 0;
            }
            
            .test :nth-child(2) {
              flex-shrink: 1;
            }
            
            .test :nth-child(3) {
              flex-shrink: 1800;
            }
            
            .test :nth-child(4) {
              flex-shrink: 7020000;
            }
          </style>
        </head>
        
        <body>
          Slide to change width:
          <input type="range" id="shrinker" min="50" max="400" value="200" oninput="changeWidth(this.value);" />
          <br />
          <br />
          <div id="test" class="test">
            <div class="color-marker"></div>
            <span> One One One One </span>
            <span> Two Two Two</span>
            <span> Hree Hree Hree</span> Four Four
          </div>
        </body>
        
        </html>

        我不知道为什么 stackoverflow 上的输出不是交互式的。如果你把它放在本地 html 文件中并使用滑块,你可以改变 test div 的宽度。
        或使用“使用 JS 运行”选项:https://jsbin.com/fabapowumo/edit?html,output

        注意:这适用于 chrome 和 edge。其他浏览器不知道。

        【讨论】:

          猜你喜欢
          • 2022-07-19
          • 2019-06-19
          • 2017-02-11
          • 1970-01-01
          • 2015-07-06
          • 2017-05-08
          • 1970-01-01
          • 2017-04-09
          • 2018-07-22
          相关资源
          最近更新 更多