CSS - Layout

Rachel Andrew on why the CSS is Awesome meme is actually a good thing and how to fix it

A box with the text "CSS is awesome" overflowing out of one side.

[T]he problem highlighted by the CSS is Awesome meme […] is an issue of overflow. You have made a fixed width container and are trying to put content into that container which is too big, what do you want CSS to do here?

CSS by default will do what you see in the meme because to do anything else would cause data loss, which [in] CSS terms means that some of your content vanishes.

We try and avoid data loss because if something on your page vanishes at certain screen sizes – because of overlap, or it going off the side of the screen, you may be unaware of it. A quick eyeballing of the page may not cause something missing to jump out at you. You will tend to spot the messy overflow though.

A good example of this design pattern can be seen in the Box Alignment specification, with the safe and unsafe alignment keywords. Safe alignment, means that your chosen alignment method won’t be used if it causes data loss, unsafe means that data loss may happen.

[…]

Better ways to stop content just “honking out of the box”

The author of the meme wondered why the box didn’t grow to fit the content. However if you give something a fixed size in CSS, it will respect that size. What the author really wanted was to make the box min-content sized. With a box that has a width of min-content the box will grow as big as it needs to be to contain the content, with all soft-wrapping opportunities taken, but no bigger.

If instead, you want to make the box not wrap at all, then give it a width of max-content. The text will then display all as one line and take no soft-wrapping opportunities.

Perhaps you need to have the box that fixed width, but don’t mind if it grows taller. In that case use overflow-wrap: break-word.

Take a look at [this CodePen] for all your awesome possibilities.

A series of solutions to the "CSS is awesome" box overflow problem, allowing the boxes to fully contain the text without losing data.

Avoid Large, Complex Layouts and Layout Thrashing

Layout is where the browser figures out the geometric information for elements: their size and location in the page. Each element will have explicit or implicit sizing information based on the CSS that was used, the contents of the element, or a parent element. The process is called Layout in Chrome, Opera, Safari, and Internet Explorer. In Firefox it’s called Reflow, but effectively the process is the same.

Similarly to style calculations, the immediate concerns for layout cost are:

  1. The number of elements that require layout.
  2. The complexity of those layouts.

TL;DR

  • Layout is normally scoped to the whole document.
  • The number of DOM elements will affect performance; you should avoid triggering layout wherever possible.
  • Assess layout model performance; new Flexbox is typically faster than older Flexbox or float-based layout models.
  • Avoid forced synchronous layouts and layout thrashing; read style values then make style changes.

See the source link for details and solutions.

What forces layout/reflow: a comprehensive list by Paul Irish

All of the below properties or methods, when requested/called in JavaScript, will trigger the browser to synchronously calculate the style and layout*. This is also called reflow or layout thrashing, and is common performance bottleneck.

Generally, all APIs that synchronously provide layout metrics will trigger forced reflow / layout. Read on for additional cases and details.

Balancing on a Pivot with Flexbox

A two dimensional series of words, laid out in intersecting boxes like in a crossword puzzle.

Let me show you a way I recently discovered to center a bunch of elements around what I call the pivot. I promise you that funky HTML is out of the question and you won’t need to know any bleeding-edge CSS to get the job done.

[…]

[H]ere’s a sample of the HTML that drives this puzzle:

Code language: HTML

<div class="puzzle">
  <div class="word">
    <span class="letter">i</span>
    <span class="letter">n</span>
    <span class="letter">d</span>
    <span class="letter">i</span>
    <span class="letter pivot">g</span>
    <span class="letter">o</span>
  </div>
  <!-- MORE WORDS -->
</div>

Here’s a generalized version of the [styles]. As you can see, it’s just 15 lines of simple CSS:

Code language: CSS

.puzzle .word {
  display: flex;
}
.puzzle .word .letter:last-child {
  margin-right: auto;
}
.puzzle .word .letter {
  order: 2;
  position: relative;
  right: 50%;
}
.puzzle .word .pivot,
.puzzle .word .pivot ~ .letter {
  order: 1;
  left: 50%;
}

How to Make a Media Query-less responsive Card Component

A card component in horizontal and vertical layouts, depending on available space.

Here are the CSS ingredients we used for a media-query-less card component:

  • The clamp() function helps resolve a “preferred” vs. “minimum” vs. “maximum” value.
  • The flex-basis property with a negative value decides when the layout breaks into multiple lines.
  • The flex-grow property is used as a unit value for proportional growth.
  • The vw unit helps with responsive typography.
  • The  object-fit property provides finer responsiveness for the card image, as it allows us to alter the dimensions of the image without distorting it.

Hello subgrid!

We have had Grid Layout in browsers for two years. Long enough for us to start to find the edges, and discover things we really wish it could do. The biggest missing feature from Level 1 was subgrid, which has become the main feature for Level 2 of the specification. In this talk I’ll introduce subgrid, with use cases, example code and some thoughts on where we might see Grid going in the future.

[…]

Resources

The following resources were mentioned during the presentation or are useful additional information.

Slides and code examples can be found in the source link.

Equal height rows in CSS Grid Layout

Great answer by Michael_B on Stack Overflow:

Short Answer

If the goal is to create a grid with equal height rows, where the tallest cell in the grid sets the height for all rows, here’s a quick and simple solution:

  • Set the container to grid-auto-rows: 1fr

How it works

Grid Layout provides a unit for establishing flexible lengths in a grid container. This is the fr unit. It is designed to distribute free space in the container and is somewhat analogous to the flex-grow property in flexbox.

If you set all rows in a grid container to 1fr, let’s say like this:

grid-auto-rows: 1fr;

… then all rows will be equal height.

It doesn’t really make sense off-the-bat because fr is supposed to distribute free space. And if several rows have content with different heights, then when the space is distributed, some rows would be proportionally smaller and taller.

Except, buried deep in the grid spec is this little nugget:

7.2.3. Flexible Lengths: the fr unit

When the available space is infinite (which happens when the grid container’s width or height is indefinite), flex-sized (fr) grid tracks are sized to their contents while retaining their respective proportions.

The used size of each flex-sized grid track is computed by determining the max-content size of each flex-sized grid track and dividing that size by the respective flex factor to determine a “hypothetical 1fr size”.

The maximum of those is used as the resolved 1fr length (the flex fraction), which is then multiplied by each grid track’s flex factor to determine its final size.

So, if I’m reading this correctly, when dealing with a dynamically-sized grid (e.g., the height is indefinite), grid tracks (rows, in this case) are sized to their contents.

The height of each row is determined by the tallest (max-content) grid item.

The maximum height of those rows becomes the length of 1fr.

That’s how 1fr creates equal height rows in a grid container.


Why flexbox isn’t an option

As noted in the question, equal height rows are not possible with flexbox.

Flex items can be equal height on the same row, but not across multiple rows.

This behavior is defined in the flexbox spec:

6. Flex Lines

In a multi-line flex container, the cross size of each line is the minimum size necessary to contain the flex items on the line.

In other words, when there are multiple lines in a row-based flex container, the height of each line (the “cross size”) is the minimum height necessary to contain the flex items on the line.