Preethi Selvam – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Mon, 31 Oct 2022 13:05:39 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.1 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 Preethi Selvam – CSS-Tricks https://css-tricks.com 32 32 45537868 The New CSS Media Query Range Syntax https://css-tricks.com/the-new-css-media-query-range-syntax/ https://css-tricks.com/the-new-css-media-query-range-syntax/#comments Mon, 31 Oct 2022 13:05:38 +0000 https://css-tricks.com/?p=374670 The Media Queries Level 4 specification has introduced a new syntax for targeting a range of viewport widths using common mathematical comparison operators, like <, >, and =, that make more sense syntactically while writing less code for responsive web design.


The New CSS Media Query Range Syntax originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
We rely on CSS Media Queries for selecting and styling elements based on a targeted condition. That condition can be all kinds of things but typically fall into two camps: (1) the type of media that’s being used, and (2) a specific feature of the browser, device, or even the user’s environment.

So, say we want to apply certain CSS styling to a printed document:

@media print {
  .element {
    /* Style away! */
  }
}

The fact that we can apply styles at a certain viewport width has made CSS Media Queries a core ingredient of responsive web design since Ethan Marcotte coined the term. If the browser’s viewport width is a certain size, then apply a set of style rules, which allows us to design elements that respond to the size of the browser.

/* When the viewport width is at least 30em... */
@media screen and (min-width: 30em) {
  .element {
    /* Style away! */
  }
}

Notice the and in there? That’s an operator that allows us to combine statements. In that example, we combined a condition that the media type is a screen and that it’s min-width feature is set to 30em (or above). We can do the same thing to target a range of viewport sizes:

/* When the viewport width is between 30em - 80em */
@media screen and (min-width: 30em) and (max-width: 80em) {
  .element {
    /* Style away! */
  }
}

Now those styles apply to an explicit range of viewport widths rather than a single width!

But the Media Queries Level 4 specification has introduced a new syntax for targeting a range of viewport widths using common mathematical comparison operators — things like <, >, and = — that make more sense syntactically while writing less code.

Let’s dig into how that works.

New comparison operators

That last example is a good illustration of how we’ve sort of “faked” ranges by combining conditions using the and operator. The big change in the Media Queries Level 4 specification is that we have new operators that compare values rather than combining them:

  • < evaluates if a value is less than another value
  • > evaluates if a value is greater than another value
  • = evaluates if a value is equal to another value
  • <= evaluates if a value is less than or equal to another value
  • >= evaluates if a value is greater than or equal to another value

Here’s how we might’ve written a media query that applies styles if the browser is 600px wide or greater:

@media (min-width: 600px) {
  .element {
    /* Style away! */
  }
}

Here’s how it looks to write the same thing using a comparison operator:

@media (width >= 600px) {
  .element {
    /* Style away! */
  }
}

Targeting a range of viewport widths

Often when we write CSS Media Queries, we’re creating what’s called a breakpoint — a condition where the design “breaks” and a set of styles are applied to fix it. A design can have a bunch of breakpoints! And they’re usually based on the viewport being between two widths: where the breakpoint starts and where the breakpoint ends.

Here’s how we’ve done that using the and operator to combine the two breakpoint values:

/* When the browser is between 400px - 1000px */
@media (min-width: 400px) and (max-width: 1000px) {
  /* etc. */
}

You start to get a good sense of how much shorter and easier it is to write a media query when we ditch the Boolean and operator in favor of the new range comparison syntax:

@media (400px <= width <= 1000px) {
  /* etc. */
}

Much easier, right? And it’s clear exactly what this media query is doing.

Browser support

This improved media query syntax is still in its early days at the time of this writing and not as widely supported at the moment as the approach that combines min-width and max-width. We’re getting close, though! Safari is the only major holdout at this point, but there is an open ticket for it that you can follow.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
10463No104TP

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
108107108No

Let’s look at an example

Here’s a layout for that’s nicely suited for larger screens, like a desktop:

A desktop layout with a logo and menu up top, a large heading in white, and an image of a silhouetted person underneath the heading, followed by a footer.

This layout has base styles that are common to all breakpoints. But as the screen gets narrower, we start to apply styles that are conditionally applied at different smaller breakpoints that are ideally suited for tablets all the way down to mobile phones:

Side-by-side screenshots of the mobile and tablet layouts with their CSS Grid tracks overlaid.

To see what’s happening, here’s a how the layout responds between the two smaller breakpoints. The hidden nav list getting displayed as well as title in the main gets increased in font-size.

That change is triggered when the viewport’s changes go from matching one media’s conditions to another:

/* Base styles (any screen size) */
header {
  display: flex;
  justify-content: center;
}

header ul {
  display: none;
}

.title p {
  font-size: 3.75rem;
}

/* When the media type is a screen with a width greater or equal to 768px */
@media screen and (width >= 768px) {
  header {
    justify-content: space-between;
  }

  header ul {
    display: flex;
    justify-content: space-between;
    gap: 3rem;
  }

  .title p {
    font-size: 5.75rem;
  }
}

We’ve combined a few of the concepts we’ve covered! We’re targeting devices with a screen media type, evaluating whether the viewport width is greater than or equal to a specific value using the new media feature range syntax, and combining the two conditions with the and operator.

Diagram of the media query syntax, detailing the media type, operator, and range media feature.

OK, so that’s great for mobile devices below 768px and for other devices equal to or greater than 768px. But what about that desktop layout… how do we get there?

As far as the layout goes:

  • The main element becomes a 12-column grid.
  • A button is displayed on the image.
  • The size of the .title element’s font increases and overlaps the image.

Assuming we’ve done our homework and determined exactly where those changes should take place, we can apply those styles when the viewport matches the width condition for that breakpoint. We’re going to say that breakpoint is at 1000px:

/* When the media type is a screen with a width greater or equal to 1000px  */
@media screen and (width >= 1000px) {
  /* Becomes a 12-column grid */
  main {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    grid-template-rows: auto 250px;
  }

  /* Places the .title on the grid */
  .title {
    grid-row: 1;
  }

  /* Bumps up the font-size */
  .title p {
    font-size: 7.75rem;
  }

  /* Places .images on the grid */
  .images {
    grid-row: 1 / span 2;
    align-self: end;
    position: relative;
  }

  /* Displays the button */
  .images .button {
    display: block;
    position: absolute;
    inset-block-end: 5rem;
    inset-inline-end: -1rem;
  }
}
Showing the CSS grid tracks for a desktop layout using a CSS media query with the new range syntax.

Have a play with it:

Why the new syntax is easier to understand

The bottom line: it’s easier to distinguish a comparison operator (e.g. width >= 320px) than it is to tell the difference between min-width and max-width using the and operator. By removing the nuance between min- and max-, we have one single width parameter to work with and the operators tell us the rest.

Beyond the visual differences of those syntaxes, they are also doing slightly different things. Using min- and max- is equivalent to using mathematical comparison operators:

  • max-width is equivalent to the <= operator (e.g. (max-width: 320px) is the same as (width <= 320px)).
  • min-width is equivalent to the >= operator (e.g. (min-width: 320px) is the same as (width >= 320px)).

Notice that neither is the equivalent of the > or < operators.

Let’s pull an example straight from the Media Queries Level 4 specification where we define different styles based on a breakpoint at 320px in the viewport width using min-width and max-width:

@media (max-width: 320px) { /* styles for viewports <= 320px */ }
@media (min-width: 320px) { /* styles for viewports >= 320px */ }

Both media queries match a condition when the viewport width is equal to 320px. That’s not exactly what we want. We want either one of those conditions rather than both at the same time. To avoid that implicit changes, we might add a pixel to the query based on min-width:

@media (max-width: 320px){ /* styles for viewports <= 320px */ }
@media (min-width: 321px){ /* styles for viewports >= 321px */ }

While this ensures that the two sets of styles don’t apply simultaneously when the viewport width is 320px, any viewport width that fall between 320px and 321px will result in a super small zone where none of the styles in either query are applied — a weird “flash of unstyled content” situation.

One solution is to increase the second comparison scale value (numbers after the decimal point) to 320.01px:

@media (max-width: 320px) { /* styles for viewports <= 320px */ }
@media (min-width: 320.01px) { /* styles for viewports >= 320.01px */ }

But that’s getting silly and overly complicated. That’s why the new media feature range syntax is a more appropriate approach:

@media (width <= 320px) { /* styles for viewports <= 320px */ }
@media (width > 320px) { /* styles for viewports > 320px */ }

Wrapping up

Phew, we covered a lot of ground on the new syntax for targeting viewport width ranges in CSS Media Queries. Now that the Media Queries Level 4 specification has introduced the syntax and it’s been adopted in Firefox and Chromium browsers, we’re getting close to being able to use the new comparison operators and combining them with other range media features besides width, like height and aspect-ratio

And that’s just one of the newer features that the Level 4 specification introduced, alongside a bunch of queries we can make based on user preferences. It doesn’t end there! Check out the Complete Guide to CSS Media Queries for a sneak peek of what might be included in Media Queries Level 5.


The New CSS Media Query Range Syntax originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/the-new-css-media-query-range-syntax/feed/ 11 374670
Using Grid Named Areas to Visualize (and Reference) Your Layout https://css-tricks.com/using-grid-named-areas-to-visualize-and-reference-your-layout/ https://css-tricks.com/using-grid-named-areas-to-visualize-and-reference-your-layout/#comments Fri, 26 Aug 2022 13:44:49 +0000 https://css-tricks.com/?p=372634 Whenever we build simple or complex layouts using CSS Grid, we’re usually positioning items with line numbers. Grid layouts contain grid lines that are automatically indexed with positive and negative line numbers (that is unless we explicitly name them). …


Using Grid Named Areas to Visualize (and Reference) Your Layout originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Whenever we build simple or complex layouts using CSS Grid, we’re usually positioning items with line numbers. Grid layouts contain grid lines that are automatically indexed with positive and negative line numbers (that is unless we explicitly name them). Positioning items with line numbers is a fine way to lay things out, though CSS Grid has numerous ways to accomplish the same with an undersized cognitive encumbrance. One of those ways is something I like to think of as the “ASCII” method.

The ASCII method in a nutshell

The method boils down to using grid-template-areas to position grid items using custom-named areas at the grid container level rather than line numbers.

When we declare an element as a grid container using display: grid, the grid container, by default, generates a single-column track and rows that sufficiently hold the grid items. The container’s child elements that participate in the grid layout are converted to grid items, irrespective of their display property.

For instance, let’s create a grid by explicitly defining columns and rows using the grid-template-columns and grid-template-rows properties.

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(3, 200px);
}

This little snippet of CSS creates a 3×2 grid where the grid items take up equal space in the columns, and where the grid contains three rows with a track size of 200px.

We can define the entire layout with named grid areas using the grid-template-areas property. According to the spec, the initial value of grid-template-areas is none.

grid-template-areas = none | <string>+

<string>+ is listing the group of strings enclosed with a quote. Each string is represented as a cell, and each quoted string is represented as a row. Like this:

grid-template-areas: "head head" "nav main" "foot foot";

The value of grid-template-areas describes the layout as having four grid areas. They are,

  • head
  • nav
  • main
  • foot

head and foot span two column tracks and one row track. The remaining nav and main each span one column track and one row track. The value of grid-template-areas is a lot like arranging ASCII characters, and as Chris suggested a while back, we can get a visualization of the overall structure of the layout from the CSS itself which is the most trouble-free way to understand it.

(Full size GIF)

OK, so we created our layout with four named grid areas: head, nav, main, foot.

Now, let’s start to position the grid items against named grid areas instead of line numbers. Specifically, let’s place a header element into the named grid area head and specify the named grid area head in the header element using the grid-area property.

Named grid areas in a grid layout are called idents. So, what we just did was create a custom ident named head that we can use to place items into certain grid tracks.

header { grid-area: head; }

We can other HTML elements using other custom idents:

nav { grid-area: nav; }
main { grid-area: main; }
footer { grid-area: foot; }

Writing named area values

According to CSS Grid Layout Module Level 1, all strings must be defined under the following tokens:

  • Named cell token: This represents the named grid area in the grid. For instance, head is a named cell token.
  • Null cell token: This represents the unnamed grid area in the grid container. For instance, an empty cell in the grid is a null cell token.
  • Trash token: This is a syntax error, such as an invalid declaration. For instance, a disparate number of cells and rows compared to the number of grid items would make a declaration invalid.

In grid-template-area, every quoted string (the rows) must have the same number of cells and define the complete grid without ignoring any cell.

We can ignore a cell or leave it as an empty cell using the full-stop character (.)

.grid { 
  display: grid;
  grid-template-areas:
    "head head"
    "nav main"
    "foot .";
}

If that feels visually awkward or imbalanced to you, we can use multiple full-stop characters without any whitespaces separating them:

.grid {
  display: grid;
  grid-template-areas:
    "head head"
    "nav main"
    "foot ....";
}

A named cell token can span multiple grid cells, But those cells must form a rectangular layout. In other words, we’re unable to create “L” or “T”-shaped layouts, although the spec does hint at support for non-rectangular layouts with disconnected regions in the future.

ASCII is better than line-based placement

Line-based placement is where we use the grid-column and grid-row properties to position an element on the grid using grid line numbers that are automatically indexed by a number:

.grid-item {
  grid-column: 1 / 3; /* start at grid column line 1 and span to line 3 */
}

But grid item line numbers can change if our layout changes at a breakpoint. In those cases, it’s not like we can rely on the same line numbers we used at a specific breakpoint. This is where it takes extra cognitive encumbrance to understand the code.

That’s why I think an ASCII-based approach works best. We can redefine the layout for each breakpoint using grid-template-areas within the grid container, which offers a convenient visual for how the layout will look directly in the CSS — it’s like self-documented code!

.grid {
  grid-template-areas:
    "head head"
    "nav main"
    "foot ...."; /* much easier way to see the grid! */
}

.grid-item {
  grid-area: foot; /* much easier to place the item! */
}

We can actually see a grid’s line numbers and grid areas in DevTools. In Firefox, for example, go to the Layout panel. Then, under the Grid tab, locate the “Grid display settings” and enable the “Display line number” and “Display area names” options.

Enabling grid settings.

This ASCII approach using named areas requires a lot less effort to visualize and easily find the placement of elements.

Line-based placement versus ASCII Art placement.

Let’s look at the “universal” use case

Whenever I see a tutorial on named grid areas, the common example is generally some layout pattern containing header, main, sidebar, and footer areas. I like to think of this as the “universal” use case since it casts such a wide net.

The Holy Grail layout in rectangles.

It’s a great example to illustrate how grid-template-areas works, but a real-life implementation usually involves media queries set to change the layout at certain viewport widths. Rather than having to re-declare grid-area on each grid item at each breakpoint to re-position everything, we can use grid-template-areas to “respond” to the breakpoint instead — and get a nice visual of the layout at each breakpoint in the process!

Before defining the layout, let’s assign an ident to each element using the grid-area property as a base style.

header {
  grid-area: head;
}

.left-side {
  grid-area: left;
}

main {
  grid-area: main;
}

.right-side {
  grid-area: right;
}

footer {
  grid-area: foot;
}

Now, let’s define the layout again as a base style. We’re going with a mobile-first approach so that things will stack by default:

.grid-container {
  display: grid;
  grid-template-areas:
    "head"
    "left"
    "main"
    "right"
    "foot";
}

Each grid item is auto-sized in this configuration — which seems a little bit weird — so we can set min-height: 100vh on the grid container to give us more room to work with:

.grid-container {
  display: grid;
  grid-template-areas:
    "head"
    "left"
    "main"
    "right"
    "foot";
  min-height: 100vh;
}

Now let’s say we want the main element to sit to the right of the stacked left and right sidebars when we get to a slightly wider viewport width. We re-declare grid-template-areas with an updated ASCII layout to get that:

@media (min-width: 800px) {
  .parent {
    grid-template-columns: 0.5fr 1fr;
    grid-template-rows: 100px 1fr 1fr 100px;
    grid-template-areas:
      "head head"
      "left main"
      "right main"
      "foot foot";
  }
}

I tossed some column and row sizing in there purely for aesthetics.

As the browser gets even wider, we may want to change the layout again, so that main is sandwiched between the left and right sidebars. Let’s write the layout visually!

.grid-container {
  grid-template-columns: 200px 1fr 200px; /* again, just for sizing */
  grid-template-areas:
    "head head head"
    "left main right"
    "left main right"
    "foot foot foot";
}

Leveraging implicit line names for flexibility

According to the spec, grid-template-areas automatically generates names for the grid lines created by named grid areas. We call these implicitly-named grid lines because they are named for us for free without any additional work.

Every named grid area gets four implicitly-named grid lines, two in the column direction and two in the row direction, where -start and -end are appended to the ident. For example, a grid area named head gets head-start and head-end lines in both directions for a total of four implicitly-named grid lines.

Implicitly assigned line names.

We can use these lines to our advantage! For instance, if we want an element to overlay the main, left, and right areas of our grid. Earlier, we talked about how layouts have to be rectangular — no “T” and “L” shaped layouts allowed. Consequently, we’re unable to use the ASCII visual layout method to place the overlay. We can, however, use our implicit line names using the same grid-area property on the overlay that we use to position the other elements.

Did you know that grid-area is a shorthand property, sort of the same way that margin and padding are shorthand properties? It takes multiple values the same way, but instead of following a “clockwise” direction like, margin — which goes in order of margin-block-start, margin-inline-end, margin-block-end, and margin-inline-startgrid-area goes like this:

grid-area: block-start / inline-start / block-end / inline-end;
Showing the block and inline flow directions in a left-to-right writing mode.

But we’re talking about rows and columns, not block and inline directions, right? Well, they correspond to one another. The row axis corresponds to the block direction, and the column axis corresponds to the inline direction:

grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end;
Block and inline axis.

Back to positioning that overlay element as a grid item in our layout. The grid-area property will be helpful to position the element using our implicitly-named grid lines:

.overlay {
  grid-area: left-start / left-start / right-end / main-end;
}

Creating a minimal grid system

When we focus on layouts like the “universal” use case we just saw, it’s tempting to think of grid areas in terms of one area per element. But it doesn’t have to work like that. We can repeat idents to reserve more space for them in the layout. We saw that when we repeated the head and foot idents in the last example:

.grid-container {
  grid-template-areas:
    "head head head"
    "left main right"
    "left main right"
    "foot foot foot";
}

Notice that main, left, and right are also repeated but in the block direction.

Let’s forget about full page layouts and use named grid areas on a component. Grid is just as good for component layouts as full pages!

Here’s a pretty standard hero component that sports a row of images followed by different blocks of text:

A row of weightlifting photos above a heading, blurb, then a row of three links.

The HTML is pretty simple:

<div class="hero">
  <div class="image">
    <img src="..." alt="" />
  </div>
  <div class="text">
    <!-- ... -->
  </div>
</div>

We could do this for a real fast stacked layout:

.hero {
  grid-template-areas:
    "image"
    "text";
}

But then we have to reach for some padding, max-width or whatever to get the text area narrower than the row of images. How about we expand our ASCII layout into a four-column grid instead by repeating our idents on both rows:

.hero {
  display: grid;
  grid-template-columns: repeat(4, 1fr); /* maintain equal sizing */
  grid-template-areas:
    "image image image image"
    "text  text  text  text";
}

Alright, now we can place our grid items into those named areas:

.hero .image {
  grid-area: image;
}

.hero .text {
  grid-area: text;
}

So far, so good — both rows take up the entire width. We can use that as our base layout for small screens.

Showing grid lines on the stacked mobile version of the page.

But maybe we want to introduce the narrower text when the viewport reaches a larger width. We can use what we know about the full-stop character to “skip” columns. Let’s have the text ident skip the first and last columns in this case.

@media (min-width: 800px) {
  main {
    grid-template-columns: repeat(6, 1fr); /* increase to six columns */
    grid-template-areas:
      "image image image image image image"
      "..... text  text  text  text  .....";
  }
}

Now we have the spacing we want:

Showing grid lines for a table-sized layout of the page.

If the layout needs additional tweaking at even larger breakpoints, we can add more columns and go from there:

.hero {
  grid-template-columns: repeat(8, 1fr);
  grid-template-areas:
    "image image image image image image image image"
    "..... text  text  text  text  text  text  .....";
}

Dev tool visualization:

Showing grid lines for a large table sized layout of the page.

Remember when 12-column and 16-column layouts were the big things in CSS frameworks? We can quickly scale up to that and maintain a nice visual ASCII layout in the code:

main {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    "image image image image image image image image image image image image"
    "..... text  text  text  text  text  text  text  text  text  text  .....";
}

Let’s look at something more complex

We’ve looked at one fairly generic example and one relatively straightforward example. We can still get nice ASCII layout visualizations with more complex layouts.

Let’s work up to this:

Three images positioned around a fancy heading.

I’ve split this up into two elements in the HTML, a header and a main:

<header>
  <div class="logo"> ... </div>
  <div class="menu"> ... </div>
</header>
<main>
  <div class="image"> ... </div>
  <h2> ... </h2>
  <div class="image"> ... </div>
  <div class="image"> ... </div>
</main>

I think flexbox is more appropriate for the header since we can space its child elements out easily that way. So, no grid there:

header {
  display: flex;
  justify-content: space-between;
  /* etc. */
}

But grid is well-suited for the main element’s layout. Let’s define the layout and assign the idents to the corresponding elements that we need to position the .text and three .image elements. We’ll start with this as our baseline for small screens:

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-areas:
    "image1 image1 .....  image2"
    "texts  texts  texts  texts"
    ".....  image3 image3 .....";
}

You can already see where we’re going with this, right? The layout is visualized for us, and we can drop the grid items into place with the custom idents:

.image:nth-child(1) {
  grid-area: image1;
}

.image:nth-last-child(2) {
  grid-area: image2;
}

.image:nth-last-child(1) {
  grid-area: image3;
}

h2 {
  grid-area: texts;
}
Showing grid lines on a mobile layout of the page.

That’s our base layout, so let’s venture into a wider breakpoint:

@media (min-width: 800px) {
  .grid {
    grid-template-columns: repeat(8, 1fr);
    grid-template-areas:
      ". image1 image1 ...... ......  ...... image2 ."
      ". texts  texts  texts  texts   texts  image2 ."
      ". .....  image3 image3 image3  image3 ...... .";
  }
}

I bet you know exactly how that will look because the layout is right there in the code!

Showing grid lines for a table-sized layout of the page.

Same deal if we decide to scale up even further:

.grid {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    ". image1 image1 .....  .....   .....  .....  .....  .....  .....  .....  ."
    ". texts  texts  texts  texts   texts  texts  texts  texts  texts  image2 ."
    ". .....  image3 image3 image3  image3 .....  .....  .....  .....  .....  .";
}
Showing grid lines for a desktop-sized layout of the page.

Here’s the full demo:

I’m using the “negative margin hack” to get the first image to overlap the heading.

Wrapping up

I’m curious if anyone else is using grid-template-areas to create named areas for the benefit of having an ASCII visual of the grid layout. Having that as a reference in my CSS code has helped de-mystify some otherwise complex designs that may have been even more complex when dealing with line numbers.

But if nothing else, defining grid layouts this way teaches us some interesting things about CSS Grid that we saw throughout this post:

  • The grid-template-areas property allows us to create custom idents — or “named areas” — and use them to position grid items using the grid-area property.
  • There are three types of “tokens” that grid-template-areas accepts as values, including named cell tokens, null cell tokens, and trash cell tokens.
  • Each row that is defined in grid-template-areas needs the same number of cells. Ignoring a single cell doesn’t create a layout; it is considered a trash token.
  • We can get a visual ASCII-like diagram of the grid layout in the grid-template-areas property value by using required whitespaces between named cell tokens while defining the grid layout.
  • Make sure there is no whitespace inside a null cell token (e.g. .....). Otherwise, a single whitespace between null cell tokens creates unnecessary empty cells, resulting in an invalid layout.
  • We can redefine the layout at various breakpoints by re-positioning the grid items using grid-area, then re-declaring the layout with grid-template-areas on the grid container to update the track listing, if needed. There’s no need to touch the grid items.
  • Custom named grid areas automatically get four implicitly assigned line names — <custom-ident>-start and <custom-ident>-end in both the column and row directions.

Using Grid Named Areas to Visualize (and Reference) Your Layout originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/using-grid-named-areas-to-visualize-and-reference-your-layout/feed/ 5 372634