azangru
azangru

Reputation: 2738

text-overflow: ellipsis in a flexbox in a grid column

I am trying to achieve the following layout: a grid with several columns of fixed width, one of which has content of unknown width, which will consist of multiple span elements, will not wrap, and has to be truncated with an ellipsis.

enter image description here

A more concrete example:

enter image description here

Here's what I tried, unsuccessfully, using a 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

I also tried to use an inline grid instead of a flexbox, which didn't help either (example on jsbin).

Is there a way to make this work?

Disclaimer: I realise that variants of this question have been asked on Stack Overflow; but none of the suggested solutions worked for me. Here are the threads that I have examined:

I hope this doesn't make my question a duplicate.

Upvotes: 2

Views: 2347

Answers (4)

the Hutt
the Hutt

Reputation: 18398

We can use increasing flex-shrink on spans. Following is the minimal working example with three 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>

I don't know why the output is not interactive on stackoverflow. If you put it in local html file and use the slider you can change width of the test div.
OR Use "Run with JS" option: https://jsbin.com/fabapowumo/edit?html,output

Note: This works on chrome and edge. Don't know about other browsers.

Upvotes: -1

Rob Moll
Rob Moll

Reputation: 3453

As a start, see if this meets your needs. See code comments for changes made.

EDIT: Now either span, but only 1 span, will cause ellipsis.

EDIT 2: This does not cause the ellipsis to inherit the color of one of the spans. The ellipsis color can be set independently in .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>

Upvotes: 1

azangru
azangru

Reputation: 2738

I'll just post a baseline solution that I would love to improve. It has obvious drawbacks. And it's also kind of cheating the question, because it's backing away from the flexbox and using a simple display: block. On the plus side, it can truncate the text in the spans. On the minus side, however, if a child span has a style that is distinctive from the parent, the ellipsis will still have the style of the parent (seen in the example below through the use of red and black colors).

Is there a way to make this better?

.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>

Upvotes: 0

Andrew
Andrew

Reputation: 622

I provide some example:

.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>

Upvotes: 0

Related Questions