Tag: Flexbox

Using Flexbox and text ellipsis together

You can truncate a single line of text with an ellipsis (…) fairly easily with text-overflow and a few friends. But, as you might expect, that truncation happens at the end of the line of text. What if you want to truncate content in the middle?

Leonardo Faria details good use cases for this, like in an operating system window listing files. The line of text is a file name and a file extension. When that line truncates, it truncates just the name, always leaving the extension at the end. The trick is a flexbox parent so you can use overflow on just the file name part, but have to make sure to reset the min-width, as the natural value there is min-content, which prevents the truncation which is confusing.

Direct Link to ArticlePermalink


The post Using Flexbox and text ellipsis together appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , ,

Posters! (for CSS Flexbox and CSS Grid)

Any time I chat with a fellow web person and CSS-Tricks comes up in conversation, there is a good chance they’ll say: oh yeah, that guide on CSS flexbox, I use that all the time!

Indeed that page, and it’s cousin the CSS grid guide, are among our top trafficked pages. I try to take extra care with them making sure the information on them is current, useful, and the page loads speedily and properly. A while back, in a round of updates I was doing on the guides, I reached out to Lynn Fisher, who always does incredible work on everything, to see if she’d be up for re-doing the illustrations on the guides. Miraculously, she agreed, and we have the much more charismatic illustrations that live on the guides today.

In a second miracle, I asked Lynn again if she’d be up for making physical paper poster designs of the guides, and see agreed again! And so they live!

Here they are:

You better believe I have it right next to me in my office:

They are $ 25 each which includes shipping anywhere in the world.

The post Posters! (for CSS Flexbox and CSS Grid) appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Grid for layout, flexbox for components

When should we reach for CSS grid and when should we use flexbox? Rachel Andrew wrote about this very conundrum way back in 2016:

Flexbox is essentially for laying out items in a single dimension – in a row OR a column. Grid is for layout of items in two dimensions – rows AND columns.

Ahmad Shadeed wrote a post where he gives the same advice, but from a different angle. He argues we should use grid for layout and flexbox for components:

Remember that old layout method might be perfect for the job. Overusing flexbox or grid can increase the complexity of your CSS by time. I don’t mean they are complex, but using them correctly and in the right context as explained from the examples in this article is much better.

Speaking of which, there’s so many great layout examples in this post, too.

Direct Link to ArticlePermalink

The post Grid for layout, flexbox for components appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

Chromium lands Flexbox gap

I mentioned this the other day via Michelle Barker’s coverage, but here I’ll link to the official announcement. The main thing is that we’ll be getting gap with flexbox, which means:

.flex-parent {   display: flex;   gap: 1rem; } .flex-child {   flex: 1; }

That’s excellent, as putting space in between flex items has been tough in the past. We have justify-content: space-between, which is nice sometimes, but that doesn’t allow you to explicitly tell the flex container how much space you want. For that, we’d typically use margin, but that means avoiding setting the margin on the first or last element depending on the direction of the margin — which is annoying gets complicated.

We have gap in CSS Grid and it’s way better. It’s great to have it in flexbox.

But it’s going to get weird for a minute. Safari doesn’t support it yet (nor stable Chrome) so we can’t just plop it out there and expect it to work with flexbox. But shouldn’t we be able to do an @supports query these days?

/* Nope, sorry. This "works" but it doesn't     actually tell you if it works in *flexbox* or not.    This works in grid in most browsers now, so it will pass. */ @supports (gap: 1rem) {   .flex-parent {      gap: 1rem;   } }

That got weird because grid-gap was dropped in favor of just gap. I’m sure grid-gap will be supported forever because that’s generally how these things go, but we’re encouraged to use gap instead. So, you might say gap is a little overloaded, but that should shake out over time (a year?). It’s complicated a smidge more by the fact that column-gap is now going to gap as well. gap has a whole bunch of jobs.

I’d say I’m still in favor of the change, despite the overloading. Simpler mental modals are important for the long-term, and there isn’t exactly anything coming up to challenge CSS for styling in the browser. I’d bet my 2-year old daughter writes some CSS in her lifetime.

Direct Link to ArticlePermalink

The post Chromium lands Flexbox gap appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Flexbox and absolute positioning

Chen Hui Jing notes that when you absolutely position a flex item, it’s no longer part of the flex layout. Except… it kinda is a little bit. If you make the child position: absolute; but don’t apply any top/right/bottom/left properties, then flexbox alignment will still apply to it.

It’s odd to see, but it makes a certain sort of sense as well. When you apply position: absolute; to things (and nothing else), they kinda just stay where they are until you apply other positioning. Check out how this SVG icon just sits in the middle of this paragraph, and even flows with it on resize, because it doesn’t have any specific positioning instructions other than to not affect anything else.

Direct Link to ArticlePermalink

The post Flexbox and absolute positioning appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

How Auto Margins Work in Flexbox

Robin has covered this before, but I’ve heard some confusion about it in the past few weeks and saw another person take a stab at explaining it, and I wanted to join the party.

Say you have a flex container with some flex items inside that don’t fill the whole area.

See the Pen
ZEYLVEX
by Chris Coyier (@chriscoyier)
on CodePen.

Now I want to push that “Menu” item to the far right. That’s where auto margins come in. If I put a margin-left: auto; on it, it’ll push as far away as it possibly can on that row.

See the Pen
WNbRLbG
by Chris Coyier (@chriscoyier)
on CodePen.

Actually, you might consider margin-inline-start: auto; instead and start using logical properties everywhere so that you’re all set should you need to change direction.

See the Pen
gObgZpb
by Chris Coyier (@chriscoyier)
on CodePen.

Also, note that auto margins work in both directions as long as there is room to push. In this example, it’s not alignment that is moving the menu down, it’s an auto margin.

See the Pen
XWJpobE
by Chris Coyier (@chriscoyier)
on CodePen.

The post How Auto Margins Work in Flexbox appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

The Thought Process Behind a Flexbox Layout

I just need to put two boxes side-by-side and I hear flexbox is good at stuff like that.

Just adding display: flex; to the parent element lays out the children in a row.

Well, that’s cool. I guess I could have floated them, but this is easier.

They should probably take up the full space they have though. Can I just stretch the parent to 100% wide? Well, I can, but that’s apparently not going to affect the child elements.

If the parent element has more space than the children need, it doesn’t do anything to help the children fill the space alone.

Maybe I can use width: 50%; on the children? That works, but I thought the point of flexbox is that you don’t have to be all specific about width. Ah yes, flexbox has all of these ways of expressing the growy-shrinky-initial behavior of children. Looks like flex: 1; is about as easy as it gets here.

Applying flex: 1; to the children allow them to grow and fill the space.

I like how I haven’t had to do any math or hard code values so far. Can I make it a three-up pattern without touching CSS?

Nice.

Hmmm, wait. The sizing is a bit, uhhhh, flexy? Nothing is forcing these boxes to be one-third of the container all the time.

Looks like flex-basis: 33% doesn’t fix this. flex: 0 0 33%; also doesn’t do the trick. Looks like width: 33%; flex-shrink: 0; does though, if we’re really wanting to strongarm it.

Sometimes a design calls for exactly equal size boxes. This is maybe CSS Grid territory, but whatever.

The long word forcing that sizing behavior at narrow widths is perhaps an uncommon scenario. We could have also solved it with word-break: break-word; hyphens: auto; on the child.

Another thing we could do it just let the dang items wrap instead of being so strict about it. Flexbox can do that, right?

Oh hey, that reminds me how cool it is that those first two items are the same height. That’s the default stretch behavior, but it can be controlled as well. And it’s by row, which is why the second row has its own different height.

What if I want that first “Love” block to be on top instead? Looks like I can re-order it, eh? Let’s see, the default order is 0, so to be first, I do order: -1;.

Ha! That kinda worked. But I meant that I want it to take up the full width on the top row. I guess I can just kick it up to flex-basis: 100%; and the others will wrap accordingly.

It’s pretty weird to have the source order and visual order different like this. Maybe that should go in the “don’t ever do this” category.

What if I wanna bail on the whole flexbox thing at a certain point? Part of me wants to change the direction to go vertical with flex-direction: column; and force the children to be full-width. Ah, a simple display: block; on the parent does that in one swoop.

Rather than changing all the flexbox stuff to handle a column layout, we just turn flexbox off.

Flexbox can do way more stuff! One of my favorites is how auto margins work to “push” other elements away when there is space. This is just one little journey playing with some UI and seeing the useful things flexible does along with things that can make it confusing.

The post The Thought Process Behind a Flexbox Layout appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Adaptive Photo Layout with Flexbox

Let’s take a look at a super lightweight way to create a horizontal masonry effect for a set of arbitrarily-sized photos. Throw any set of photos at it, and they will line up edge-to-edge with no gaps anywhere.

The solution is not only lightweight but also quite simple. We’ll be using an unordered list of images and just 17 lines of CSS, with the heavy lifters being flexbox and object-fit.

Why?

I have two hobbies: documenting my life with photos, and figuring out interesting ways to combine CSS properties, both old and new.

A couple of weeks ago, I attended XOXO and shot a ton of photos which I narrowed down to a nice little set of 39. Wanting to own my content, I’ve spent the past couple of years thinking about putting together a simple photo blog, but was never able to nail the layout I had in mind: a simple masonry layout where photos fill out rows while respecting their aspect ratio (think Photos.app on iOS, Google Photos, Flickr…).

I did some research to see if there were any lightweight, non-JavaScript options, but couldn’t find anything suiting my needs. Facing some delayed flights, I started playing around with some code, limiting myself to keep things as simple as possible (because that’s my definition of fun).

Basic Markup

Since I’m basically creating a list of images, I opted for an unordered list:

<ul>   <li>     <img>   </li>   <!-- ... -->   <li>     <img>   </li> </ul>

All hail flexbox

Then came a string of lightbulb moments:

  • Flexbox is great for filling up rows by determining cell width based on cell content.
  • This meant the images (landscape or portrait) all needed to have the same height.
  • I could use object-fit: cover; to make sure the images filled the cells.

In theory, this sounded like a solid plan, and it got me a result I was about 90% happy with.

ul {   display: flex;   flex-wrap: wrap; }  li {   height: 40vh;   flex-grow: 1; }  img {   max-height: 100%;   min-width: 100%;   object-fit: cover;   vertical-align: bottom; }

Note: 40vh seemed like the best initial approach for desktop browsers, showing two full rows of photos at a reasonable size, and hinting at more below. This also allowed more photos per line, which dramatically improves the aspect ratios.

Last row stretchiness

The only issue I ran into is that flexbox really wants to fill all the lines, and it did some silly things to the aspect ratios of the photos on the last row. This is probably my least favorite bit of this layout, but I had to add an empty <li> element at the end of the list.

<ul>   <li>     <img>   </li>   <!-- ... -->   <li>     <img>   </li>   <li></li> </ul>

Combined with this bit of CSS:

li:last-child {   flex-grow: 10; }

Note: There’s no science in using “10” here. In all my testing, this delivered the best results.

Demo

See the Pen
Adaptive Photo Layout
by Tim Van Damme (@maxvoltar)
on CodePen.

Viewport optimization

There are some considerations to keep in mind when working in different viewport orientations.

Portrait

If your viewport is taller than it is wide, this approach limits the amount of photos per line thus messing up their aspect ratios. To solve this, you can make the photo rows less tall with this simple media query:

@media (max-aspect-ratio: 1/1) {   li {     height: 30vh;   } }

Short Screens

To help with small devices in landscape, increasing the height of photos helps to see them as large as possible:

@media (max-height: 480px) {   li {     height: 80vh;   } }

Smaller Screens + Portrait

Most phones aren’t wide enough to allow flexbox to properly do its job without miniaturizing the photos, so here I opted to not try to fit multiple photos per line. Still, it’s worth setting a maximum height here so you’ll at least have a hint at the next photo in the list.

@media (max-aspect-ratio: 1/1) and (max-width: 480px) {   ul {     flex-direction: row;   }    li {     height: auto;     width: 100%;   }    img {     width: 100%;     max-height: 75vh;     min-width: 0;   } }

There we have it!

This approach doesn’t fully respect the aspect ratios of photos (but it’s close) and occasionally leads to some weird results, but I absolutely love the simplicity and flexibility of it all. Want to have your gallery scroll horizontally instead of vertically? A couple of tweaks will allow you to do this. Are there 1,000 photos in the gallery or just one? It’ll all look good. Unclear about aspect ratios? Flexbox is your best friend. Take another look at the demo if you haven’t yet, and let me know what you think!

Bonus

Depending on the size of these photos, a page like this can grow to multiple megabytes real quick. On the blog I’m working on, I’ve added loading="lazy" to help with this. With that attribute in place on the images, it only loads photos once you approach them while scrolling. It’s supported just in Chrome for now, but you could roll your own more supported technique.

The post Adaptive Photo Layout with Flexbox appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

IE10-Compatible Grid Auto-Placement with Flexbox

If you work on web applications that support older browsers, and have lusted after CSS Grid from the sidelines like I have, I have some good news: I’ve discovered a clever CSS-only way to use grid auto-placement in IE10+!

Now, it’s not actually CSS Grid, but without looking at the code itself, you wouldn’t be able to tell. The HTML structure looks like CSS Grid. It has a defined set of columns with an undefined amount of rows and it has gutters that support borders and shadows on the cells without hacks. But what’s actually happening behind the scenes is a combination of flexbox and margins.

In this article, I’ll walk through the approach. Here’s a demo of what we’re looking at:

See the Pen
IE10-compatible CSS-Grid-like column layout
by Brian Holt (@bholtbholt)
on CodePen.

Auto-flowing rows with flexbox wrap

Five orange rectangles in two rows with three on the first row and two on the second row.
Flexbox-created auto-placement grid

Getting the basic grid setup is very simple. If you’re at all familiar with flexbox, I’m certain you’ve already guessed flex-wrap: wrap is the trick here. And you’d be right.

Let’s get the HTML markup in place before we write any CSS. We want it to resemble the same structure as if we were using auto-placement — a .grid container and an undefined number of .grid__cells.

<div class="grid">   <div class="grid__cell">...</div>   ... </div>

We set three grid breakpoints. A single-column, two-column, and three-column layout for mobile-devices, small screens, and medium screens, respectively. I’m using the breakpoints used in Bootstrap for this article, though we’d want to define them at actual points where the layout breaks if we were working with real content.

$ screen-sm-min: 768px; $ screen-sm-max: 991px; $ screen-md-min: 992px;
Five orange rectangles stacked on top of one another.
Mobile-first grid collapses into a single column

A mobile-first approach means our single-column layout is already complete since each .grid__cell is already a block. We set .grid to become a flexbox container after the first breakpoint, and wrap cells.

@media (min-width: $ screen-sm-min) {   .grid {     display: flex;     flex-wrap: wrap;   } }

Our two- and three-column layouts need explicit widths and flex properties; otherwise they’ll cram onto a single line. While testing IE10, I experienced unexpected behavior with the flex-basis property, and found setting an explicit width with flex-basis: auto was more consistent. This didn’t seem to be a problem with IE11 though.

.grid__cell {   min-width: 0;   flex: 1 1 auto; }  // Two-column grid @media (min-width: $ screen-sm-min) and (max-width: $ screen-sm-max) {   $ width: 50%;    .grid__cell {     width: $ width;   } }  // Three-column grid @media (min-width: $ screen-md-min) {   $ width: 33.33%;    .grid__cell {     width: $ width;   } }

We don’t need to wrap .grid__cell in a media query since its flex properties won’t have the effect when the parent isn’t a flexbox container. We also define an upper-limit to the two-column media query so it doesn’t affect the three-column grid.

And that’s it! We now have a responsive, fluid, wrapping flexbox grid. The easy part is done… well, as long as we only ever have items that are multiples of two and three. With flex: 1 1 auto, the last item will always take up any remaining space in the last row.

Three rows of orange rectangles. The first two rows have two columns of boxes and the third row has one single box that spans both columns.
Two-column grid on smaller screens
Two rows of orange rectangles. The first row has three columns of rectangles and the second row has two rectnagles that span the full width.
Three-column grid on large screens

Aligning cells in the last row

The elusive last row is why we’re here, right? By default, each cell will stretch to the end of the row in a flexbox layout, but grid leaves a blank spot. How do we do that in flexbox? With pseudo-elements!

The trick is to add a pseudo-element to the .grid container and set it like a cell. We define the :after pseudo-element cell at each of our breakpoints with the same width as a real cell.

@media (min-width: $ screen-sm-min) {   .grid {     ...      &:after {       content: '';       display: block;       flex: 1 1 auto;     }   } }  @media (min-width: $ screen-sm-min) and (max-width: $ screen-sm-max) {   $ width: 50%;    .grid:after {     width: $ width;   } }  @media (min-width: $ screen-md-min) {   $ width: 33.33%;    .grid:after {     width: $ width;   } }

This creates a fake cell that will push against our real cells and align our two-column grid when the cells are odd. Leaving its height undefined allows it to collapse to nothing when the cells are even.

Three rows of orange rectangles. First two rows have two columns, each with a rectangle. Third row has a single rectangle and an empty column.
Two-column grid with odd cells, snapping into place

Our three-column grid is a bit more complex because we need to handle multiple states, like when there is one empty cell and when there are two empty cells.

Three column grid of orange rectangles with two rows. The second row only has one rectangle and an empty column.
Three-column grid with one empty cell

Our one empty cell state is already handled because it isn’t really any different from one empty cell in two columns. The :after cell has its width set and completes the row. The story changes when there are two empty cells though because flex: 1 1 auto rears its head again: the last cell now stretches across 50% of the width when pushed against the pseudo-element.

Three column grid of orange rectangles with two rows. The second row has one rectangle that spans half the grid width leaving an empty white space.
Three-column grid with two empty cells

Using CSS :nth-of-type selectors, we can target the first column in each row. Since our rows are multiples of three, we target them with 3n then count backwards by 2 to get the first element in each row.

@media (min-width: $ screen-md-min) {   .grid__cell {     ...      &:nth-of-type(3n-2) {       background-color: red;     }   } }
Three column grid of rectangles. The first column of rectangles is red indicating the rectangles that are selected with CSS. The other rectangles are orange.
Targeting the first cell in each three-column row

We’re broadly targeting all the cells in the first column, but we need to limit the selection to only the last row. Actually, we need to limit it to when it’s the last cell in the first column of the last row. Luckily, there’s a handy pseudo-selector for targeting the last item of its kind. We chain :last-of-type to create the logical statement.

@media (min-width: $ screen-md-min) {   .grid__cell {     ...     &:nth-of-type(3n-2):last-of-type {       background-color: red;     }   } }

Now that we have the last cell in the first column of the last row selected, we use a margin to push the :after cell to the last column and fill the middle cell.

@media (min-width: $ screen-md-min) {   .grid__cell {     ...      &:nth-of-type(3n-2):last-of-type {       margin-right: $ width;     }   } }

Here’s our flexbox-defined-auto-placement-grid-imitator in full. Look at its beautifully lined up rows. I bet you can’t even tell it’s not CSS Grid!

Three column grid with three rows of orange rectangles. The last row has a single rectangle in the first column and the other two columns are empty.
Our complete three-column grid.

Adding gutters with margins

CSS Grid’s spec has a column and row gap to provide space between each cell. Creating gutters in flexbox is much more challenging. It looks like it’s coming to flexbox, but we’re not there yet…and IE will never be.

In Daniel Tonon’s guide on CSS Grid in IE, he used an inner-cell div with negative margins, borders, a bit of padding, and overflow: hidden. While maybe a bit hacky, the effect works, but it breaks our desire to maintain CSS Grid-like HTML structure. The approach I prefer might feel a bit crude, but I also found it the easiest to read and understand. Further, it continues using :nth-of-type pseudo-selectors which makes the overall approach feel consistent.

We want gaps between the cells, but not around the outside. We also want our cells to sit flush with the container.

A three-by-two grid of orange rectangles. A block arrow is pointing at a gap between the rectangles.
Gaps between the cells, not on the outside.

Our mobile or single-column grid only needs a bottom margin on the cells. We add that and override the very last cell with margin-bottom: 0 so the cell fits flush against the container. Normally I’d use initial, but there’s no support in IE.

$ col-gap: 16px;  .grid__cell {   ...   margin-bottom: $ col-gap;    &:last-of-type {     margin-bottom: 0;   } }
A single column of orange rectangles in five rows.
Single-column grid with gaps between each row

Our two- and three-column grids need margins on the right of the cells, no right margins in the last column, and no bottom margins on any of the last row’s cells. Because of the margins, we’ll also need to recalculate our widths since the cells will wrap if they don’t fit.

In a two-column layout, getting the right (or second) column is fairly easy with :nth-of-type(2n) or :nth-of-type(even). I prefer an n-multiplier for consistency with our three-column grid and for calculating the last row.

Our last row is a bit more tricky. When we have odd cells our mobile-first CSS takes care of removing the bottom margins since the cell is the :last-of-type and our :after cell doesn’t have margins applied.

A two-by-three grid of orange rectangles. The last rectangle is a little taller than the others.
Two-columns with even cells

When we have even cells we need to target the second last cell, but only when it is in the first column position. If we didn’t qualify it, the second last cell will grow vertically with to match the height of the second last row. We can target it with :nth-of-type(2n-1):nth-last-of-type(2).

@media (min-width: $ screen-sm-min) and (max-width: $ screen-sm-max) {   $ width: calc(50% - #{$ col-gap});    .grid__cell {     ...     margin-right: $ col-gap;      // Remove margin in last column     &:nth-of-type(2n) {       margin-right: 0;     }      // For when the last row is complete     // . .     // * .     &:nth-of-type(2n-1):nth-last-of-type(2) {       margin-bottom: 0;     }   } }
The same two-by-three grid as before, but with the last rectangle at an even height with the rest.
Two-columns with even cells that sit flush against the container

Our three-column gutters take the same approach. We add margin-right to all of them, remove it from the third column, and remove bottom margins from the last row. Again our last cell is handled by our mobile-first approach, but now we need to cover when there are two cells in the last row and when when there are three cells. We can qualify our selectors with nth-of-type and nth-last-of-type.

@media (min-width: $ screen-md-min) {   $ width: calc(33% - #{$ col-gap});    .grid__cell {     ...     margin-right: $ col-gap;      // Remove margin in last column     &:nth-of-type(3n) {       margin-right: 0;     }      // For when there two items in the last row     // . . .     // * .     &:nth-of-type(3n-2):nth-last-of-type(2) {       margin-bottom: 0;     }      // For when the last row is complete     // . . .     // * * .     &:nth-of-type(3n-1):nth-last-of-type(2),     &:nth-of-type(3n-2):nth-last-of-type(3) {       margin-bottom: 0;     }   } }
A three-by-three grid of orange rectangles, with the last cell empty.
Three-column grid with gutters and an empty cell

We need to adjust the margin of last cell in the last row when it’s alone because of the columns. We use 33% plus a gutter on each side.

@media (min-width: $ screen-md-min) {   $ width: calc(33% - #{$ col-gap});    .grid__cell {     ...     // When there is only one item in the last rpw     // Fill the margin so it's like the last item is     // double the width     // . . .     // *->     &:nth-of-type(3n-2):last-of-type {       margin-right: calc(33% + #{$ col-gap * 2});     }   } }

Now our gutters are installed and the grid is complete! Fill them borders, shadows, or whatever your heart desires.

A three-by-two grid of orange rectangles with the last cell empty.
Complete three-column grid with gutters using flexbox.

Wrapping up

Here’s the final result one more time:

See the Pen
IE10-compatible CSS-Grid-like column layout
by Brian Holt (@bholtbholt)
on CodePen.

I believe this technique could also support IE9 with minor adjustments, like using inline-blocks instead of flexbox. We could also expand to a four-column grid by adding another breakpoint and using the same approach as the three-column grid. Feel free to use this approach and I hope it helps!

The post IE10-Compatible Grid Auto-Placement with Flexbox appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

Quick! What’s the Difference Between Flexbox and Grid?

Let’s go rapid fire and try to answer this question with quick points rather than long explanations. There are a lot of similarities between flexbox and grid, starting with the fact that they are used for layout and much more powerful than any layout technique that came before them. They can stretch and shrink, they can center things, they can re-order things, they can align things… There are plenty of layout situations in which you could use either one to do what we need to do, and plenty of situations where one is more well-suited than the other. Let’s focus on the differences rather than the similarities:


Flexbox can optionally wrap. If we allow a flex container to wrap, they will wrap down onto another row when the flex items fill a row. Where they line up on the next row is independent of what happenned on the first row, allowing for a masonry-like look.

Grid can also optionally wrap (if we allow auto filling) in the sense that items can fill a row and move to the new row (or auto place themselves), but as they do, they will fall along the same grid lines all the other elements do.

Flexbox on top, Grid on bottom

You could think of flexbox as “one dimensional.” While flexbox can make rows and columns in the sense that it allows elements to wrap, there’s no way to declaratively control where elements end up since the elements merely push along a single axis and then wrap or not wrap accordingly. They do as they do, if you will, along a one-dimensional plane and it’s because of that single dimension that we can optionally do things, like align elements along a baseline — which is something grid is unable to do.

.parent {   display: flex;   flex-flow: row wrap; /* OK elements, go as far as you can on one line, then wrap as you see fit */ }

You could think of grid as “two dimensional in that we can (if we want to) declare the sizing of rows and columns and then explicitly place things into both rows and columns as we choose.

.parent {   display: grid;   grid-template-columns: 3fr 1fr; /* Two columns, one three times as wide as the other */   grid-template-rows: 200px auto 100px; /* Three columns, two with explicit widths */   grid-template-areas:     "header header header"     "main . sidebar"     "footer footer footer"; }  /*   Now, we can explicitly place items in the defined rows and columns. */ .child-1 {   grid-area: header; }  .child-2 {   grid-area: main; }  .child-3 {   grid-area: sidebar; }  .child-4 {   grid-area: footer; }
Flexbox on top, Grid on bottom

I’m not the world’s biggest fan of the “1D” vs. “2D” differentiation of grid vs. flexbox, only because I find most of my day-to-day usage of grid is “1D” and it’s great for that. I wouldn’t want someone to think they have to use flexbox and not grid because grid is only when you need 2D. It is a strong distinction though that 2D layout is possible with grid though in ways it is not in flexbox.


Grid is mostly defined on the parent element. In flexbox, most of the layout (beyond the very basics) happen on the children.

/*   The flex children do most of the work */ .flexbox {   display: flex;   > div {     &:nth-child(1) { // logo       flex: 0 0 100px;     }     &:nth-child(2) { // search       flex: 1;       max-width: 500px;     }     &:nth-child(3) { // avatar       flex: 0 0 50px;       margin-left: auto;     }   } }  /*   The grid parent does most of the work */ .grid {   display: grid;   grid-template-columns: 1fr auto minmax(100px, 1fr) 1fr;   grid-template-rows: 100px repeat(3, auto) 100px;   grid-gap: 10px; }

Grid is better at overlapping. Getting elements to overlap in flexbox requires looking at traditional stuff, like negative margins, transforms, or absolute positioning in order to break out of the flex behavior. With grid, we can place items on overlapping grid lines, or even right within the same exact grid cells.

Flexbox on top, Grid on bottom

Grid is sturdier. While the flexing of flexbox is sometimes it’s strength, the way a flex item is sized gets rather complicated. It’s a combination of width, min-width, max-width, flex-basis, flex-grow, and flex-shrink, not to mention the content inside and things like white-space, as well as the other items in the same row. Grid has interesting space-occupying features, like fractional units, and the ability for content to break grids, though, generally speaking, we’re setting up grid lines and placing items within them that plop right into place.


Flexbox can push things away. It’s a rather unique feature of flexbox that you can, for example, put margin-right: auto; on an element and, if there is room, that element will push everything else as far away as it can go can.


Here are some of my favorite tweets on the subject:

The post Quick! What’s the Difference Between Flexbox and Grid? appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]