Ben
Ben

Reputation: 624

Why does justify-items cancels 1fr in grid?

Let's consider the following HTML snippet:

<div class="container">
  <div class="longText">Lorem Ipsum Dolor Sit Amet and so on !</div>
  <div class="otherContent">*</div>
</div>

The .container has a min-width of 500px, and the .otherContent takes exactly 350px.

.longText needs to be displayed on the left of .otherContent, it cannot be smaller than 150px, and if the text is too long, it needs to make an ellipsis.

The ellipsis part is easily managed by the famous combo white-space: nowrap; overflow: hidden; text-overflow: ellipsis;.

There are many ways to solve the positioning. Let's use display: grid; with grid-template-columns: minmax(150px, 1fr) 350px; on the .container.

This works nicely.

However, if I add justify-items: start; on .container then the display breaks: when the text is too long, the .longText does not reduce, and so the ellipsis is not created (jsfiddle here, reduce the size of your browser to see the left div overlapping the right one).

.container {
  min-width: 500px;
  border: 1px #f00 solid;
  display: grid;
  grid-template-columns: minmax(150px, 1fr) 350px;

  justify-items: start;
}

.longText {
  border: 1px #00f solid;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.otherContent {
  height: 50px;
  width: 350px;
  border: 1px #0f0 solid;
}
<div class="container">
  <div class="longText">
    Lorem Ipsum Dolor Sit Amet and so on !
  </div>
  <div class="otherContent">
  *
  </div>
</div>

Why does justify-items has this effect ?

Upvotes: 1

Views: 80

Answers (1)

Temani Afif
Temani Afif

Reputation: 273649

To fix this simply add max-width:100%

.container {
  min-width: 500px;
  border: 1px #f00 solid;
  display: grid;
  grid-template-columns: minmax(150px, 1fr) 350px;

  justify-items: start;
}

.longText {
  border: 1px #00f solid;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width:100%;
}

.otherContent {
  height: 50px;
  width: 350px;
  border: 1px #0f0 solid;
}
<div class="container">
  <div class="longText">
    Lorem Ipsum Dolor Sit Amet and so on !
  </div>
  <div class="otherContent">
  *
  </div>
</div>

For the why, it's because the default value is stretch so the element don't need a width or max-width and will stretch to fill all the area.

You can find more details in the specification:

stretch

Use the inline size calculation rules for non-replaced boxes (defined in CSS 2 §10.3.3 Block-level, non-replaced elements in normal flow).

all other values

Size the item as fit-content.

So any other value different from stretch will give you a fit-content width creating the overflow unless you explicitely define a width/max-width or you use stretch.

As a side note, the 1fr is not canceled and the column width is the same in both case. Only the width of the element inside the column is changing.

Upvotes: 2

Related Questions