Andrei V
Andrei V

Reputation: 7508

Ellipsis on deeply nested flex items

I believe I know how text overflowing works in general, but my deeply nested layout is proving otherwise. There are lots of resources on the internet (e.g. this well-known article) and, of course, on stackoverflow (e.g. this, this or this, to name a few) but I can't detect the issue that's preventing my text from correctly applying the ellipsis.

The text with the .text class does show the ellipsis and shrinks for a bit, but at one point it "refuses" to shrink any further and maintains its width (best seen if the window is shrank). I've checked for min-width: auto; on parent elements and I've put min-width: 0; on all elements, including the flex item itself. I've played with countless combinations of max-width: 100%; and overflow: hidden; but still can't find the culprit or a solution.

At this, point I'm thinking it might be related to a different feature of the layout and not the truncation of the text. Unfortunately, I've run out of ideas. If someone could give me a hint, it would be greatly appreciated.

(I know that there are other factors that impact a layout and I am aware my contrived example doesn't provide the full picture, but it appears to have the same effect).

Here's a JSFiddle example.

.layout-container {
  display: flex;
  flex-direction: column;
}

.trouble-container {
  align-self: flex-start;
  min-width: 0;
}

.wrapper-1 {
  max-width: 100%;
}

.wrapper-2 {
  display: flex;
  flex-direction: column;
}

.wrapper-3 {
  overflow: hidden;
}

.line {
  display: flex;
  max-width: 100%;
  flex-direction: row;
  margin-bottom: 8px;
}

.text-container {
  display: flex;
  overflow: hidden;
  flex-grow: 1;
}

.value-container {
  flex-shrink: 0;
}

.text {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin-right: 4px;
}
<div class="layout-container">
  <div>we can ignore this...</div>
  <div class="trouble-container">
    <div class="wrapper-1">
      <div class="wrapper-2">
        <div class="wrapper-3">
          <div class="wrapper-4">
            <div class="wrapper-5">
              <div class="wrapper-6">
                <div class="line">
                  <div class="text-container">
                    <p class="text">
                      this is a short text
                    </p>
                  </div>
                  <div class="value-container">
                    <p> === 12345</p>
                  </div>
                </div>
              </div>
              <div class="line">
                <div class="text-container">
                  <p class="text">
                    this is my long text that's currently giving me headaches
                  </p>
                </div>
                <div class="value-container">
                  <p> === 12345</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
</div>

Upvotes: 1

Views: 37

Answers (2)

Temani Afif
Temani Afif

Reputation: 273710

.layout-container is using a column configuration so min-width: 0 won't help you on the direct child elements, you need max-width: 100%

I also commented all the properties that you don't really need.

.layout-container {
  display: flex;
  flex-direction: column;
}

.trouble-container {
  align-self: flex-start;
  max-width: 100%;
}

.wrapper-1 {
  /*max-width: 100%;*/
}

.wrapper-2 {
  display: flex;
  flex-direction: column;
}

.wrapper-3 {
  /*overflow: hidden;*/
}

.line {
  display: flex;
  /*max-width: 100%;*/
  flex-direction: row;
  margin-bottom: 8px;
}

.text-container {
  display: flex;
  overflow: hidden; /* OR min-width: 0 which is more logical */
  flex-grow: 1;
}

.value-container {
  flex-shrink: 0;
}

.text {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin-right: 4px;
}
<div class="layout-container">
  <div>we can ignore this...</div>
  <div class="trouble-container">
    <div class="wrapper-1">
      <div class="wrapper-2">
        <div class="wrapper-3">
          <div class="wrapper-4">
            <div class="wrapper-5">
              <div class="wrapper-6">
                <div class="line">
                  <div class="text-container">
                    <p class="text">
                      this is a short text
                    </p>
                  </div>
                  <div class="value-container">
                    <p> === 12345</p>
                  </div>
                </div>
              </div>
              <div class="line">
                <div class="text-container">
                  <p class="text">
                    this is my long text that's currently giving me headaches
                  </p>
                </div>
                <div class="value-container">
                  <p> === 12345</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
</div>

Upvotes: 2

Michael Benjamin
Michael Benjamin

Reputation: 371889

The align-self: flex-start on .trouble-container is the problem. Remove it.

.layout-container {
  display: flex;
  flex-direction: column;
}

.trouble-container {
  /* align-self: flex-start; */
  min-width: 0;
}

.wrapper-1 {
  max-width: 100%;
}

.wrapper-2 {
  display: flex;
  flex-direction: column;
}

.wrapper-3 {
  overflow:hidden;
}

.line {
  display: flex;
  max-width: 100%;
  flex-direction: row;
  margin-bottom: 8px;
}

.text-container {
  display: flex;
  overflow: hidden;
  flex-grow: 1;
}

.value-container {
  flex-shrink: 0;
}

.text {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin-right: 4px;
}
<div class="layout-container">
  <div>we can ignore this...</div>
  <div class="trouble-container">
    <div class="wrapper-1">
      <div class="wrapper-2">
        <div class="wrapper-3">
          <div class="wrapper-4">
            <div class="wrapper-5">
              <div class="wrapper-6">
              <div class="line">
                  <div class="text-container">
                    <p class="text">
                      this is a short text
                    </p>
                  </div>
                  <div class="value-container">
                    <p> === 12345</p>
                  </div>
                </div>
              </div>
                <div class="line">
                  <div class="text-container">
                    <p class="text">
                      this is my long text that's currently giving me headaches
                    </p>
                  </div>
                  <div class="value-container">
                    <p> === 12345</p>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

The min-width: 0 and overflow: hidden overrides work only along the flex container's main axis. As you're using flex-direction: column (i.e., main axis is vertical), so they're not doing anything in the horizontal axis. This also means that align-self (a cross-axis property) is working along the horizontal axis, and thus packing the items to the start of the container.

more complete explanation

Upvotes: 2

Related Questions