Tag: Layout

Auto Layout lands in Figma

Here’s a fresh update to my favorite design tool that is thoroughly exciting: Auto layout! That means we can make frames that resize based on the size of the content within it. That’s particularly useful for buttons in a design system where you want to drop a button on the page and then keep its left and right padding equal.

However! The other exciting part of this update is that content can now be nudged down based on the content above it, too — just like on a webpage. If you’re interested in trying out this feature then I’d recommend just booting up Figma where you can immediately hop over to a playground that explains how this game-changing new feature works with a handy step-by-step tutorial.

Direct Link to ArticlePermalink

CSS-Tricks

, , ,

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]

Techniques for a Newspaper Layout with CSS Grid and Border Lines Between Elements

I recently had to craft a newspaper-like design that featured multiple row and column spans with divider lines in between them. Take a look at the mockup graphic here and see if it makes you sweat at all. If you’re like me, you have been around a while and know just how difficult this would have been with old layout techniques.

Newspaper design with line dividers between cells

The project came with a few requirements:

  • Show the outlines of the grid
  • Columns can be wider, or longer than others
  • Divider lines must be shown between the various blocks

CSS Grid: Teaching an old layout new tricks

Newspaper layouts can cause headaches because everyday CSS is one-dimensional, meaning that elements flow on either a horizontal or vertical axis. Even modern flexbox layout is still uni-directional.

For a layout like this, we would almost want the properties that good ol’ HTML tables once provided: things like row and column spans to stretch cells in all directions. We would also want the benefits of modern day CSS, with all the responsiveness and flexible boxes that can grow to fill available space.

CSS grid combines the best of tables with the best of flexible boxes. In fact, grid’s even better because it provides the grid-gap property for creating gutters between cells while taking available space into account. Powerful as this may be, how can we create divider-lines exactly in the middle of those gutters?

Let’s look at three techniques to make that happen.

What we’ll create

First, we will build a simplified version of the newspaper design that’ll help illustrate the crux of the three different techniques that we’re going to cover. A deceptively easy design, one would say.

Column and row spans in a CSS grid layout

Technique 1: The faux column

This solution creates “faux” columns that allow us to draw vertical lines, and then place a grid on top. Horizontal dividers are painted if needed. The “faux” columns are created by using pseudo selectors in the grid container.

<div class="frontpage">   <div class="fp-cell fp-cell--1">     <div class="fp-item">1</div>   </div>   <div class="fp-cell fp-cell--2">     <div class="fp-item">2</div>   </div>   <div class="fp-cell fp-cell--3 fp-cell--border-top">     <div class="fp-item">3</div>   </div>   <div class="fp-cell fp-cell--4 fp-cell--border-top">     <div class="fp-item">4</div>   </div> </div>

See the Pen
Newspaper-design, ‘faux-column’ technique
by Marco Troost (@marco-troost)
on CodePen.

Setting up the lines between the columns

Let’s create a three-column container using display: grid and pseudo-selectors (:before and :after) to create two columns that fill 100% of the container’s height.

.frontpage {   position: relative;   display: grid;   /* Three columns */   grid-template-columns: 1fr 1fr 1fr;   grid-column-gap: 32px;   border: 1px solid transparent;   border-top: 1px solid #DADCE0;   border-bottom: 1px solid #DADCE0;   overflow: hidden; }  /* Two faux columns */ .frontpage:before, .frontpage:after {   position: absolute;   top: 0;   height: 100%;   content: '';   width: calc(33.3% - 4px); }  .frontpage:before {   left: 0;   border-right: 1px solid #DADCE0; }  .frontpage:after {   right: 0;   border-left: 1px solid #DADCE0; }

Note: 33% of the container doesn’t take the gutter width into account, so you’ll have to compensate accordingly.

This is calculated as:

33% minus (gutter-width divided by (amount of gutters times amount of gutters)) divided by amount of gutters)

Or, with actual numbers:

33% - (32 / (2* 2)) / 2 = 4

We could use one pseudo-selector instead:

.frontpage {   position: relative;   display: grid;   grid-template-columns: 1fr 1fr 1fr;   grid-column-gap: 32px;   border: 1px solid transparent;   border-top: 1px solid #DADCE0;   border-bottom: 1px solid #DADCE0;   overflow: hidden; }  .frontpage:before {   box-sizing: border-box;   position: absolute;   top: 0;   height: 100%;   content: '';   left: calc(33.3% - 5.3px);   width: calc(33.3% + 10.7px);   border-left: 1px solid #DADCE0;   border-right: 1px solid #DADCE0; }

See the Pen
Newsgrid-layout ‘faux-columns’ (using only :before)
by Marco Troost (@marco-troost)
on CodePen.

Note: A different calculation is needed when using only one pseudo-selector: One for positioning, and one for width.

The width is calculated as:

33% plus (amount of gutters times gutter-width) / (amount of gutters times amount of columns)

Again, with actual numbers:

33% + (2 * 32) / (2 * 3) = 10.7

The position is calculated as:

33% minus (amount of gutters times gutter-width) / (amount of gutters times amount of columns) divided by 2)

Making the grid

The design consists of four blocks of content. We’re going to place them in the container and give them a modifier class for future reference while making sure their z-index is higher than the pseudo-selectors of the grid.

<div class="frontpage">   <div class="fp-cell fp-cell--1"></div>   <div class="fp-cell fp-cell--2"></div>   <div class="fp-cell fp-cell--3"></div>   <div class="fp-cell fp-cell--4"></div> </div>

Now let’s set the background color for the cells (.fp-cell) to white. This way, the vertical lines won’t show through. We can also set the vertical padding for the cell to 16px in order to match half of the gutter.

The first and second content blocks should get their own unique spans as shown in the design. The first block spans all the way down and the second block spans the second and third columns.

.fp-cell {   position: relative;   z-index: 2;   padding: 16px 0;   background-color: #fff; }  /* Span all the way down! */ .fp-cell--1 {   grid-row: 1 / span 2; }  /* Span the second and third columns */ .fp-cell--2 {   grid-column: 2 / span 2; }

Vertical line dividers

If you look at the design, only the last two cells need a horizontal border. We can give ’em a sweet modifier class.

<div class="frontpage">   <div class="fp-cell fp-cell--1"></div>   <div class="fp-cell fp-cell--2"></div>   <div class="fp-cell fp-cell--3 fp-cell--border-top"></div>   <div class="fp-cell fp-cell--4 fp-cell--border-top"></div> </div>
.fp-cell--border-top:before {   content: '';   position: absolute;   top: 0;   left: -16px;   right: -16px;   border-top: 1px solid #DADCE0; }

The negative margins are half of the gutter width.

Technique #2: Using background-color

Another way to create the dividers is to utilize the grid-gap property. This solution doesn’t necessarily create a “real” distance between cells, but rather leaves some blank space where the background-color of the grid can shine through. The gutter width is delegated to padding within the grid cells.

<div class="container">   <div class="frontpage">     <div class="fp-cell fp-cell--1">       <div class="fp-item">1</div>     </div>     <div class="fp-cell fp-cell--2">       <div class="fp-item">2</div>     </div>     <div class="fp-cell fp-cell--3">       <div class="fp-item">3</div>     </div>     <div class="fp-cell fp-cell--4">       <div class="fp-item">4</div>     </div>   </div> </div>
.container {   overflow-x: hidden;   border-top: 1px solid #DADCE0;   border-bottom: 1px solid #DADCE0; }  .frontpage {   position: relative;   display: grid;   grid-template-columns: 1fr 1fr 1fr;   grid-gap: 1px;   margin: 0 -16px;   background-color: #DADCE0; }  .fp-cell {   background-color: #fff;   padding: 16px; }  .fp-cell--1 {   grid-row: 1 / span 2; }  .fp-cell--2 {   grid-column: 2 / span 2; }  .fp-cell--3 {   grid-column: 2; }  .fp-item {   background-color: #efefef;   display: flex;   align-items: center;   justify-content: center;   min-height: 200px;   height: 100%; }

See the Pen
Newspaper-design, background-color technique
by Marco Troost (@marco-troost)
on CodePen.

Since all cells have an extra 16px of horizontal padding, the grid needs to be offset by just as much. A wrapper container will take care of the overflow.

<div class="container">   <div class="frontpage">   <!-- ... -->   </div> </div>
.container {   border-top: 1px solid #DADCE0;   border-bottom: 1px solid #DADCE0;   overflow-x: hidden; }  .frontpage {   position: relative;   display: grid;   grid-template-columns: 1fr 1fr 1fr;   grid-gap: 1px;   background-color: #DADCE0;   margin: 0 -16px; }

Technique #3: Creating a cell border

This solution appends a right and bottom border to each cell. Like the last example, the grid-gap is mimicked by adding padding to the cell content. That means it also needs to be wrapped in an extra container.

<div class="container">   <div class="frontpage">     <div class="fp-cell fp-cell--1">       <div class="fp-item">1</div>     </div>     <div class="fp-cell fp-cell--2">       <div class="fp-item">2</div>     </div>     <div class="fp-cell fp-cell--3">         <div class="fp-item">3</div>     </div>     <div class="fp-cell fp-cell--4">       <div class="fp-item">4</div>     </div>   </div> </div>
.container {   border-top: 1px solid #DADCE0;   overflow-x: hidden; }  .frontpage {   margin: 0 -17px 0 -16px;   position: relative;   display: grid;   grid-template-columns: 1fr 1fr 1fr; }  .fp-cell {   padding: 16px;   background-color: #fff;   border-right: 1px solid #DADCE0;   border-bottom: 1px solid #DADCE0; }  .fp-cell--1 {   grid-row: 1 / span 2; }  .fp-cell--2 {   grid-column: 2 / span 2; }  .fp-cell--3 {   grid-column: 2; }  .fp-item {   background-color: #efefef;   display: flex;   align-items: center;   justify-content: center;   min-height: 200px;   height: 100%; }

See the Pen
Newspaper-design, ‘cell-border’-technique
by Marco Troost (@marco-troost)
on CodePen.

As mentioned, each cell is given a border on the right and on the bottom. The main trick here is the use of the (asymmetrical) negative margin on the grid. This is needed to compensate for the cell’s right border.

.frontpage {   margin: 0 -17px 0 -16px;   position: relative;   display: grid;   grid-template-columns: 1fr 1fr 1fr; }

Conclusion

Occam’s razor stipulates that the simplest solution wins. In our case, that’s technique number two. But then again, the other solutions have plenty of merit and they could prove useful if, for example, access to the DOM is not possible.

All of these techniques will work. Choosing the right one depends on your use case. The first technique uses the actual grid-gap property to create the gaps, but the others are perhaps easier to understand at a glance… and perhaps easier to maintain as well.

The post Techniques for a Newspaper Layout with CSS Grid and Border Lines Between Elements 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]

Weekly Platform News: Layout Shifts, Stalled High-Bitrate Videos, Screenshots in Firefox

In this week’s roundup: fighting shifty layouts, some videos might be a bit stalled, and a new way to take screenshots in Firefox.

Let’s get into the news!

Identifying the causes of layout shifts during page load

You can now use WebPageTest to capture any layout shifts that occur on your website during page load, and identify what caused them.

Step 1: Paste a snippet

Paste the following snippet into the “Custom Metrics” on webpagetest.org in field in the Custom tab (under Advanced Settings) and make sure that a Chrome browser is selected.

[LayoutShifts] return new Promise(resolve => {   new PerformanceObserver(list => {     resolve(JSON.stringify(list.getEntries().filter(entry => !entry.hadRecentInput)));   }).observe({type: "layout-shift", buffered: true}); });

Step 2: Inspect entries

After completing the test, inspect the captured LayoutShifts entries on the Custom Metrics page, which is linked from the Details section.

Step 3: Check the filmstrip

Based on the "startTime" and "value" numbers in the data, use WebPageTest’s filmstrip view to pinpoint the individual layout shifts and identify their causes.

(via Rick Viscomi)

A high bitrate can cause your videos to stall

If you serve videos for your website from your own web server, keep an eye on the video bitrate (the author suggests FFmpeg and streamclarity.com). If your video has a bitrate of over 1.5 Mbps, playback may stall one or more times for people on 3G connections, depending on the video’s length.

50% of videos in this study have a bitrate that is greater than the downlink speed of a 3G connection — meaning that video playback will be delayed and contain stalls.

(via Doug Sillars)

Firefox’s :screenshot command

Firefox’s DevTools console includes a powerful command for capturing screenshots of the current web page. Like in Chrome DevTools, you can capture a screenshot of an individual element, the current viewport, or the full page, but Firefox’s :screenshot command also provides advanced options for adjusting the device pixel ratio and setting a delay.

// capture a full-page screenshot at a device pixel ratio of 2 :screenshot --fullpage --dpr 2  // capture a screenshot of the viewport with a 5-second delay :screenshot --delay 5

(via Reddit)


Read even more news in my weekly Sunday issue, which can be delivered to you via email every Monday morning.

Web Platform News: Sunday issue →

The post Weekly Platform News: Layout Shifts, Stalled High-Bitrate Videos, Screenshots in Firefox appeared first on CSS-Tricks.

CSS-Tricks

, , , , , , , , ,
[Top]

The Fight Against Layout Jank

A web page isn’t locked in stone just because it has rendered visually. Media assets, like images, can come in and cause the layout to shift based on their size, which typically isn’t known in fluid layouts until they do render. Or fonts can load and reflow layout. Or XHRs can bring in more content to be placed onto the page. We’re always doing what we can to prevent the layout from shifting around — that’s what I mean by layout jank. It’s awkward and nobody likes it. At best, it causes you to lose your place while reading; at worst, it can mean clicking on something you really didn’t mean to.

While I was trying to wrap my head around the new Layout Instability API and chatting it out with friends, Eric Portis said something characteristically smart. Basically, layout jank is a problem and it’s being fought on multiple fronts:

The post The Fight Against Layout Jank appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

Every Layout

Every Layout is a new work-in-progress website and book by Heydon Pickering and Andy Bell that explains how to make common layout patterns with CSS. They describe a lot of the issues when it comes to the design of these layouts, such as responsive problems and making sure we all write maintainable code, and then they’ve provided a handy generator at the end of each article to create our own little frameworks for dealing with these things.

They also have a complementary blog and one of the posts called “Algorithmic Design” caught my eye:

We make many of our biggest mistakes as visual designers for the web by insisting on hard coding designs. We break browsers’ layout algorithms by applying fixed positions and dimensions to our content.

Instead, we should be deferential to the underlying algorithms that power CSS, and we should think in terms of algorithms as we extrapolate layouts based on these foundations. We need to be leveraging selector logic, harnessing flow and wrapping behavior, and using calculations to adapt layout to context.

The tools for flexible, robust, and efficient web layout are there. We are just too busy churning out CSS to use them.

I’m looking forward to seeing where this project goes and how many more layouts these two end up documenting.

Direct Link to ArticlePermalink

The post Every Layout appeared first on CSS-Tricks.

CSS-Tricks

,
[Top]

A Course About CSS Layout and Animations

Christina Gorton just released a new course called CSS Layout and Animations as a part of Design+Code, which is a $ 9/month. That includes a ton of video training on everything from stuff like this to React to Sketch to iOS development… and beyond!

Christina approaches the course with my favorite way to learn this stuff: by starting from a lovely design and then pulling it off with code.

That’s Figma as the design tool, which is another tool I love.

Of course, what I really love is that:

  • The course is full of CSS trickery and modern HTML & CSS features, like using flexbox and grid in practical ways.
  • She uses CodePen to prototype everything — the perfect place to get started with a project like this, in my humble opinion.

Direct Link to ArticlePermalink

The post A Course About CSS Layout and Animations appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

A responsive grid layout with no media queries

Andy Bell made a really cool demo that shows us how to create a responsive grid layout without any media queries at all. It happens to look like this when you change the size of the browser window:

I think this is a wonderful layout technique that’s just 6 lines (!) of CSS.

.auto-grid {   --auto-grid-min-size: 16rem;   display: grid;   grid-template-columns: repeat(auto-fill, minmax(var(--auto-grid-min-size), 1fr));   grid-gap: 1rem; }

What this shows us is that we don’t have to write a million media queries to change the number of columns in a grid. Andy also proves that CSS Grid can automate so much of the tedious work of styling layouts.

I’ve seen this technique used in a couple of places (and we have a few starter grid templates to boot) but Andy’s article about how it all works finally made it all sink in just how useful grid is.

Direct Link to ArticlePermalink

The post A responsive grid layout with no media queries appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

People Digging into Grid Sizing and Layout Possibilities

Jen Simmons has been coining the term intrinsic design, referring to a new era in web layout where the sizing of content has gone beyond fluid columns and media query breakpoints and into, I dunno, something a bit more exotic. For example, columns that are sized more by content and guidelines than percentages. And not always columns, but more like appropriate placement, however that needs to be done.

One thing is for sure, people are playing with the possibilities a lot right now. In the span of 10 days I’ve gathered these links:

The post People Digging into Grid Sizing and Layout Possibilities appeared first on CSS-Tricks.

CSS-Tricks

, , , , , ,
[Top]