container-queries – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Fri, 14 Jun 2024 15:31:04 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 container-queries – CSS-Tricks https://css-tricks.com 32 32 45537868 CSS Container Queries https://css-tricks.com/css-container-queries/ https://css-tricks.com/css-container-queries/#comments Mon, 10 Jun 2024 16:12:50 +0000 https://css-tricks.com/?p=378111 The main idea of CSS Container Queries is to register an element as a “container” and apply styles to other elements when the container element meets certain conditions.


CSS Container Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>

Container queries are often considered a modern approach to responsive web design where traditional media queries have long been the gold standard — the reason being that we can create layouts made with elements that respond to, say, the width of their containers rather than the width of the viewport.

.parent {
  container-name: hero-banner;
  container-type: inline-size;

  /* or container: hero-banner / inline-size; */
}

}

.child {
  display: flex;
  flex-direction: column;
}

/* When the container is greater than 60 characters... */
@container hero-banner (width > 60ch) {
  /* Change the flex direction of the .child element. */
  .child { 
    flex-direction: row;
  }
}

Why care about CSS Container Queries?

  1. When using a container query, we give elements the ability to change based on their container’s size, not the viewport.
  1. They allow us to define all of the styles for a particular element in a more predictable way.
  1. They are more reusable than media queries in that they behave the same no matter where they are used. So, if you were to create a component that includes a container query, you could easily drop it into another project and it will still behave in the same predictable fashion.
  1. They introduce new types of CSS length units that can be used to size elements by their container’s size.

Registering Elements as Containers

.cards {
  container-name: card-grid;
  container-type: inline-size;

  /* Shorthand */
  container: card-grid / inline-size;
}

This example registers a new container named card-grid that can be queried by its inline-size, which is a fancy way of saying its “width” when we’re working in a horizontal writing mode. It’s a logical property. Otherwise, “inline” would refer to the container’s “height” in a vertical writing mode.

  • The container-name property is used to register an element as a container that applies styles to other elements based on the container’s size and styles.
  • The container-type property is used to register an element as a container that can apply styles to other elements when it meets certain conditions.
  • The container property is a shorthand that combines the container-name and container-type properties into a single declaration.

Some Possible Gotchas

Querying a Container

@container my-container (width > 60ch) {
  article {
    flex-direction: row;
  }
}
  • The @container at-rule property informs the browser that we are working with a container query rather than, say, a media query (i.e., @media).
  • The my-container part in there refers to the container’s name, as declared in the container’s container-name property.
  • The article element represents an item in the container, whether it’s a direct child of the container or a further ancestor. Either way, the element must be in the container and it will get styles applied to it when the queried condition is matched.

Some Possible Gotchas

Container Queries Properties & Values

Container Queries Properties & Values

container-name

container-name: none | <custom-ident>+;
Value Descriptions
  • none: The element does not have a container name. This is true by default, so you will likely never use this value, as its purpose is purely to set the property’s default behavior.
  • <custom-ident>: This is the name of the container, which can be anything, except for words that are reserved for other functions, including defaultnoneatno, and or. Note that the names are not wrapped in quotes.
  • Initial value: none
  • Applies to: All elements
  • Inherited: No
  • Percentages: N/A
  • Computed value: none or an ordered list of identifiers
  • Canonical order: Per grammar
  • Animation: Not animatable

container-type

container-type: normal | size | inline-size;
Value Descriptions
  • normal: This indicates that the element is a container that can be queried by its styles rather than size. All elements are technically containers by default, so we don’t even need to explicitly assign a container-type to define a style container.
  • size: This is if we want to query a container by its size, whether we’re talking about the inline or block direction.
  • inline-size: This allows us to query a container by its inline size, which is equivalent to width in a standard horizontal writing mode. This is perhaps the most commonly used value, as we can establish responsive designs based on element size rather than the size of the viewport as we would normally do with media queries.
  • Initial value: normal
  • Applies to: All elements
  • Inherited: No
  • Percentages: N/A
  • Computed value: As specified by keyword
  • Canonical order: Per grammar
  • Animation: Not animatable

container

container: <'container-name'> [ / <'container-type'> ]?
Value Definitons

If <'container-type'> is omitted, it is reset to its initial value of normalwhich defines a style container instead of a size container. In other words, all elements are style containers by default, unless we explicitly set the container-type property value to either size or inline-size which allows us to query a container’s size dimensions.

  • Initial value: none / normal
  • Applies to: All elements
  • Inherited: No
  • Percentages: N/A
  • Computed value: As specified
  • Canonical order: Per grammar
  • Animation: Not animatable

Container Length Units

Container Width & Height Units

UnitNameEquivalent to…
cqwContainer query width1% of the queried container’s width
cqhContainer query height1% of the queried container’s height

Container Logical Directions

UnitNameEquivalent to…
cqiContainer query inline size1% of the queried container’s inline size, which is its width in a horizontal writing mode.
cqbContainer query block size1% of the queried container’s inline size, which is its height in a horizontal writing mode.

Container Minimum & Maximum Lengths

UnitNameEquivalent to…
cqminContainer query minimum sizeThe value of cqi or cqb, whichever is smaller.
cqmaxContainer query maximum sizeThe value of cqi or cqb, whichever is larger.

Container Style Queries

Container Style Queries is another piece of the CSS Container Queries puzzle. Instead of querying a container by its size or inline-size, we can query a container’s CSS styles. And when the container’s styles meet the queried condition, we can apply styles to other elements. This is the sort of “conditional” styling we’ve wanted on the web for a long time: If these styles match over here, then apply these other styles over there.

CSS Container Style Queries are only available as an experimental feature in modern web browsers at the time of this writing, and even then, style queries are only capable of evaluating CSS custom properties (i.e., variables).

Browser Support

The feature is still considered experimental at the time of this writing and is not supported by any browser, unless enabled through feature flags.

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
129NoNo126TP

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
126No12618.0

Registering a Style Container

article {
  container-name: card;
}

That’s really it! Actually, we don’t even need the container-name property unless we need to target it specifically. Otherwise, we can skip registering a container altogether.

And if you’re wondering why there’s no container-type declaration, that’s because all elements are already considered containers. It’s a lot like how all elements are position: relative by default; there’s no need to declare it. The only reason we would declare a container-type is if we want a CSS Container Size Query instead of a CSS Container Style Query.

So, really, there is no need to register a container style query because all elements are already style containers right out of the box! The only reason we’d declare container-name, then, is simply to help select a specific container by name when writing a style query.

Using a Style Container Query

@container style(--bg-color: #000) {
  p { color: #fff; }
}

In this example, we’re querying any matching container (because all elements are style containers by default).

Notice how the syntax it’s a lot like a traditional media query? The biggest difference is that we are writing @container instead of @media. The other difference is that we’re calling a style() function that holds the matching style condition. This way, a style query is differentiated from a size query, although there is no corresponding size() function.

In this instance, we’re checking if a certain custom property named --bg-color is set to black (#000). If the variable’s value matches that condition, then we’re setting paragraph (p) text color to white (#fff).

Custom Properties & Variables

.card-wrapper {
  --bg-color: #000;
}
.card {
  @container style(--bg-color: #000) {
    /* Custom CSS */
  }
}

Nesting Style Queries

@container style(--featured: true) {
  article {
    grid-column: 1 / -1;
  }
  @container style(--theme: dark) {
    article {
      --bg-color: #000;
      --text: #fff;
    }
  }
}

Specification

CSS Container Queries are defined in the CSS Containment Module Level 3 specification, which is currently in Editor’s Draft status at the time of this writing.

Browser Support

Browser support for CSS Container Size Queries is great. It’s just style queries that are lacking support at the time of this writing.

  • Chrome 105 shipped on August 30, 2022, with support.
  • Safari 16 shipped on September 12, 2022, with support.
  • Firefox 110 shipped on February 14, 2023, with support.

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
106110No10616.0

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12612712616.0

Demos!

Many, many examples on the web demonstrate how container queries work. The following examples are not unique in that regard in that they illustrate the general concept of applying styles when a container element meets a certain condition.

You will find plenty more examples listed in the References at the end of this guide, but check out Ahmad Shadeed’s Container Queries Lab for the most complete set of examples because it also serves as a collection of clever container query use cases.

Card Component

In this example, a “card” component changes its layout based on the amount of available space in its container.

Call to Action Panel

This example is a lot like those little panels for signing up for an email newsletter. Notice how the layout changes three times according to how much available space is in the container. This is what makes CSS Container Queries so powerful: you can quite literally drop this panel into any project and the layout will respond as it should, as it’s based on the space it is in rather than the size of the browser’s viewport.

Stepper Component

This component displays a series of “steps” much like a timeline. In wider containers, the stepper displays steps horizontally. But if the container becomes small enough, the stepper shifts things around so that the steps are vertically stacked.

Icon Button

Sometimes we like to decorate buttons with an icon to accentuate the button’s label with a little more meaning and context. And sometimes we don’t know just how wide that button will be in any given context, which makes it tough to know when exactly to hide the icon or re-arrange the button’s styles when space becomes limited. In this example, an icon is displayed to the right edge of the button as long as there’s room to fit it beside the button label. If room runs out, the button becomes a square tile that stacks the icons above the label. Notice how the border-radius is set in container query units, 4cqi, which is equal to 4% of the container’s inline-size (i.e. width) and results in rounder edges as the button grows in size.

Pagination

Pagination is a great example of a component that benefits from CSS Container Queries because, depending on the amount of space we have, we can choose to display links to individual pages, or hide them in favor of only two buttons, one to paginate to older content and one to paginate to newer content.

Articles & Tutorials

General Information

Container Size Query Tutorials

Container Style Queries

References


CSS Container Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/css-container-queries/feed/ 2 378111
container https://css-tricks.com/almanac/properties/c/container/ Wed, 22 May 2024 20:42:56 +0000 https://css-tricks.com/?page_id=378078 The CSS container property is a shorthand that combines the container-name and container-type properties into a single declaration.

.parent {
  container: cards-grid / inline-size;

  /* Equivalent to: */
  container-name: cards-grid;
  container-type: inline-size;
}

Constituent properties

The container property is a …


container originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
The CSS container property is a shorthand that combines the container-name and container-type properties into a single declaration.

.parent {
  container: cards-grid / inline-size;

  /* Equivalent to: */
  container-name: cards-grid;
  container-type: inline-size;
}

Constituent properties

The container property is a shorthand for the following properties.

Syntax

container: <'container-name'> [ / <'container-type'> ]?
  • Initial value: none / normal
  • Applies to: All elements
  • Inherited: No
  • Percentages: N/A
  • Computed value: As specified
  • Canonical order: Per grammar
  • Animation: Not animatable

If <'container-type'> is omitted, it is reset to its initial value of normal which defines a style container instead of a size container. In other words, all elements are style containers by default, unless we explicitly set the container-type property value to either size or inline-size which allows us to query a container’s size dimensions.

Specification

The container property is defined in the CSS Containment Module Level 3 specification, which is currently in Editor’s Draft status at the time of this writing.

Browser support

Data on support for the css-container-queries feature across the major browsers from caniuse.com

More on Container Queries


container originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
378078
container-type https://css-tricks.com/almanac/properties/c/container-type/ Wed, 22 May 2024 20:21:35 +0000 https://css-tricks.com/?page_id=378062 The CSS container-type property is part of the Container Queries feature used to register an element as a container that can apply styles to other elements when it meets certain conditions.

.parent {
  container-type: inline-size;
}

@container (width < 500px) 


container-type originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
The CSS container-type property is part of the Container Queries feature used to register an element as a container that can apply styles to other elements when it meets certain conditions.

.parent {
  container-type: inline-size;
}

@container (width < 500px) {
  .child {
    flex-direction: column;
  }
}

Syntax

container-type: normal | size | inline-size;
  • Initial value: normal
  • Applies to: All elements
  • Inherited: No
  • Percentages: N/A
  • Computed value: As specified by keyword
  • Canonical order: Per grammar
  • Animation: Not animatable

Values

There are currently three types of containers that we can define in addition to CSS global keyword values:

/* Keyword values */
container-type: normal;
container-type: size;
container-type: inline-size;

/* Global Values */
container-type: inherit;
container-type: initial;
container-type: revert;
container-type: revert-layer;
container-type: unset;
  • normal: This indicates that the element is a container that can be queried by its styles rather than size. All elements are technically containers by default, so we don’t even need to explicitly assign a container-type to define a style container.
  • size: This is if we want to query a container by its size, whether we’re talking about the inline or block direction.
  • inline-size: This allows us to query a container by its inline size, which is equivalent to width in a standard horizontal writing mode. This is perhaps the most commonly used value, as we can establish responsive designs based on element size rather than the size of the viewport as we would normally do with media queries.

The container-name property sometimes requires it

Technically speaking, all elements are containers by default, only they are style containers that cannot be queried by their size. That’s because the container-type property’s default value is normal which ensures that all elements can at least be queried by their styles, even if we do not explicitly set a container-type on it.

If we want to be able to query the element by its size, however, we have to explicitly set a container-type:

.parent {
  container-type: inline-size;
}

We can register any element as a container with the container-type property alone, even if we do not give it a container-name. In this sort of case, any @container query will match the nameless container.

.parent {
  container-type: inline-size;
}

/* This matches the .parent container */
@container (width > 800px) {
  article {
    display: flex;
  }
}

That said, we absolutely need to provide a container-name if we want to query a specific container. And if we want to query that specific container by it’s size or inline-size, then we have to bring the container-type property along for the ride:

.parent {
  container-name: cards-grid;
  container-type: inline-size;
}

/* This matches the .parent container */
@container cards-grid (width > 800px) {
  article {
    display: flex;
  }
}

But if we only want to query the element’s style, then there’s no need to declare either property since all elements are style queries by default, thanks to container-type: normal being the default value.

It’s included in the container shorthand property

We can avoid having to declare both container-type and container-name separately by using the container shorthand property, which combines the two into a single declaration.

.parent {
  container: cards-grid / inline-size;

  /* Equivalent to: */
  container-name: cards-grid;
  container-type: inline-size;
}

Specification

The container-type property is defined in the CSS Containment Module Level 3 specification, which is currently in Editor’s Draft status at the time of this writing.

Browser support

Data on support for the css-container-queries feature across the major browsers from caniuse.com

More on Container Queries


container-type originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
378062
container-name https://css-tricks.com/almanac/properties/c/container-name/ Wed, 22 May 2024 19:29:24 +0000 https://css-tricks.com/?page_id=378057 The CSS container-name property is used to register an element as a container that applies styles to other elements based on the container’s size and styles.

.parent {
  container-name: cards;
  container-type: inline-size;
}

@container cards (width 800px) {
  .child {
    


container-name originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
The CSS container-name property is used to register an element as a container that applies styles to other elements based on the container’s size and styles.

.parent {
  container-name: cards;
  container-type: inline-size;
}

@container cards (width > 800px) {
  .child {
    width: 50cqi;
  }
}

In this example, we have registered a new container called cards out of elements with a class of .parent that looks at the element’s inline-size — i.e., width in a standard horizontal writing mode — and changes the .child element’s size when the container is greater than 800px when used with @container to query that specific container.

Syntax

container-name: none | <custom-ident>+;
  • Initial value: none
  • Applies to: All elements
  • Inherited: No
  • Percentages: N/A
  • Computed value: none or an ordered list of identifiers
  • Canonical order: Per grammar
  • Animation: Not animatable

Values

The container-name property accepts one value or multiple values separated by a single space.

/* No container */
container-name: none;

/* Single value */
container-name: wrapper;

/* Two values */
container-name: wrapper hero-banner;

/* Global Values */
container-name: inherit;
container-name: initial;
container-name: revert;
container-name: revert-layer;
container-name: unset;
  • none: The element does not have a container name. This is true by default, so you will likely never use this value, as its purpose is purely to set the property’s default behavior.
  • <custom-ident>: This is the name of the container, which can be anything, except for words that are reserved for other functions, including default, none, at, no, and or. Note that the names are not wrapped in quotes.

It’s used with the container-type property

That’s right, make sure to use container-name along with container-type to properly register a specific container that can be queried by its size. The name identifies it and the type creates a containment context.

.parent {
  container-name: cards;
  container-type: inline-size;
}

That said…

Naming containers is optional

An unnamed container will match any @container query that does not explicitly target a specific container name.

.parent {
  container-type: inline-size;
}

/* Matches any container, named or unnamed */
@container (width < 600px) {
  .child {
    width: 100cqi;
  }
}

It’s included in the container shorthand property

If you would rather not write out both container-name and container-type as separate declarations (and who would blame you?), then you can use the container shorthand property instead, which combines the two properties into a single declaration, separated by a forward slash (/).

.parent {
  container: cards / inline-size;

  /* Equivalent to: */
  container-name: cards;
  container-type: inline-size;
}

Working with multiple container names

Earlier, we mentioned how it’s possible to set multiple container names on an element as long as they are separated by spaces:

.parent {
  container: layout hero-banner / inline-size;

  /* Or */
  container-name: layout hero-banner;
  container-type: inline-size;
}

When we do that, we can potentially query the container when multiple conditions are true:

@container layout (width < 600px) {
  article {
    flex-direction: column;
  }
}

@container hero-banner (width > 400px) {
  article h2 {
    font-size: 2rem;
  }
}

Specification

The container-name property is defined in the CSS Containment Module Level 3 specification, which is currently in Editor’s Draft status at the time of this writing.

Browser support

Data on support for the css-container-queries feature across the major browsers from caniuse.com

More on Container Queries


container-name originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
378057
A Few Times Container Size Queries Would Have Helped Me Out https://css-tricks.com/a-few-times-container-size-queries-would-have-helped-me-out/ https://css-tricks.com/a-few-times-container-size-queries-would-have-helped-me-out/#comments Tue, 13 Dec 2022 13:53:56 +0000 https://css-tricks.com/?p=375728 CSS Container Queries are still gaining traction and many of us are getting our hands wet with them, even if it’s for little experiments or whatnot. They’ve got great, but not quite full, browser support — enough to justify using …


A Few Times Container Size Queries Would Have Helped Me Out originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
CSS Container Queries are still gaining traction and many of us are getting our hands wet with them, even if it’s for little experiments or whatnot. They’ve got great, but not quite full, browser support — enough to justify using them in some projects, but maybe not to the extent where we might be tempted to start replacing media queries from past projects with shiny new container size queries.

They sure are handy though! In fact, I’ve already run into a few situations where I really wanted to reach for them but just couldn’t overcome the support requirements. If I had been able to use them, this is how it would have looked in those situations.

All of the following demos will be best viewed in Chrome or Safari at the time of this writing. Firefox plans to ship support in Version 109.

Case 1: Card grid

You kind of had to expect this one, right? It’s such a common pattern that all of us seem to run into it at some point. But the fact is that container size queries would have been a huge time-saver for me with a better outcome had I been able to use them over standard media queries.

Let’s say you’ve been tasked with building this card grid with the requirement that each card needs to keep it’s 1:1 aspect ratio:

A four-by-three grid of card elements as a grayscale mockup.

It’s tougher than it looks! The problem is that sizing a component’s contents on the viewport’s width leaves you at the mercy of how the component responds to the viewport — as well the way any other ancestor containers respond to it. If, for example, you want the font size of a card heading to reduce when the card hits a certain inline size there’s no reliable way to do it.

You could set the font size in vw units, I suppose, but the component is still tied to the browser’s viewport width. And that can cause problems when the card grid is used other in contexts that may not have the same breakpoints.

In my real-world project, I landed on a JavaScript approach that would:

  1. Listen for a resize event.
  2. Calculate the width of each card.
  3. Add an inline font size to each card based on its width.
  4. Style everything inside using em units.

Seems like a lot of work, right? But it is a stable solution to get the required scaling across different screen sizes in different contexts.

Container queries would have been so much better because they provide us with container query units, such as the cqw unit. You probably already get it, but 1cqw is equal to 1% of a container’s width. We also have the cqi unit that’s a measure of a container’s inline width, and cqb for a container’s block width. So, if we have a card container that is 500px wide, a 50cqw value computes to 250px.

If I had been able to use container queries in my card grid, I could have set up the .card component as a container:

.card { 
  container: card / size;
}

Then I could have set an inner wrapper with padding that scales at 10% of the .card‘s width using the cqw unit:

.card__inner { 
  padding: 10cqw; 
} 

That’s a nice way to scale the spacing between the card’s edges and its contents consistently no matter where the card is used at any given viewport width. No media queries required!

Another idea? Use cqw units for the font size of the inner contents, then apply padding in em units:

.card__inner { 
  font-size: 5cqw; 
  padding: 2em;
} 

5cqw is an arbitrary value — just one that I settled on. That padding is still equal to 10cqw since the em unit is relative to the .card__inner font size!

Did you catch that? The 2em is relative to the 5cqw font size that is set on the same container. Containers work different than what we’re used to, as em units are relative to the same element’s font-size value. But what I quickly noticed is that container query units relate to the nearest parent that is also a container.

For example, 5cqw does not scale based on the .card element’s width in this example:

.card { 
  container: card / size; 
  container-name: card; 
  font-size: 5cqw; 
}

Rather, it scales to whatever the nearest parent that’s defined as a container. That’s why I set up a .card__inner wrapper.

Case 2: Alternating layout

I needed yet another card component in a different project. This time, I needed the card to transition from a landscape layout to a portrait layout… then back to landscape, and back to portrait again as the screen gets smaller.

Showing four states of a card element changing between portrait and landscape layouts at various breakpoints.

I did the dirty work of making this component go to portrait at those two specific viewport ranges (shout out to the new media query range syntax!), but again, the problem is that it is then locked to the media queries set on it, its parent, and anything else that might respond to the viewport’s width. We want something that works in any condition without worrying about wondering where the content is going to break!

Container queries would have made this a breeze, thanks to the @container rule:

.info-card {
  container-type: inline-size;
  container-name: info-card;
}

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

One query, infinite fluidity:

But hold on! There’s something you might want to watch out for. Specifically, it could be difficult to use a container query like this within a prop-based design system. For example, this .info-card component could contain child components that rely on props to change their appearance.

Why’s that a big deal? The card’s portrait layout might require the alternate styling but you can’t change JavaScript props with CSS. As such, you risk duplicating the required styles. I actually touched on this and how to work around it in another article. If you need to use container queries for a significant amount of your styling, then you may need to base your entire design system around them rather than trying to shoehorn them into an existing design system that’s heavy on media queries.

Case 3: SVG strokes

Here’s another super common pattern I’ve recently used where container size queries would have resulted in a more polished product. Say you have an icon locked up with a heading:

<h2>
  <svg>
    <!-- SVG stuff -->
  </svg> 
  Heading
</h2>

It’s pretty straightforward to scale the icon with the title’s size, even without media queries. The problem, though, is that the SVG’s stroke-width might get too thin to be noticed all that well at a smaller size, and perhaps catch too much attention with a super thick stroke at a larger size.

I’ve had to create and apply classes to each icon instance to determine its size and stroke width. That’s OK if the icon is next to a heading that’s styled with a fixed font size, I guess, but it’s not so great when working with fluid type that constantly changes.

A lockup of a hexagon icon and heading at three different sizes, from large to small.

The heading’s font size might be based on the viewport’s width, so the SVG icon needs to adjust accordingly where its stroke works at any size. You could make the stroke width relative to the heading’s font-size by setting it in em units. But if you have a specific set of stroke sizes that you need to stick to, then this wouldn’t work because it otherwise scales linearly — there’s no way to adjust it to a specific stroke-width value at certain points without resorting to media queries on the viewport width.

But here’s what I would have done if I had the luxury of container queries at that time:

.icon {
  container: icon / size; 
  width: 1em; 
  height: 1em; 
}

.icon svg {
  width: 100%; 
  height: 100%; 
  fill: none; 
  stroke: #ccc; 
  stroke-width: 0.8; 
}

@container icon (max-width: 70px) {
  .icon svg {
    stroke-width: 1.5; 
  }
}
@container icon (max-width: 35px) {
  .icon svg {
    stroke-width: 3;
  }
}

Compare the implementations and see how the container query version snaps the SVG’s stroke to the specific widths I want based on the container’s width.

Bonus: Other types of container size queries

OK, so I haven’t actually run into this on a real project. But as I was combing through information on container queries, I noticed that there are additional things we can query on a container that are related to the container’s size or physical dimensions.

Most examples I’ve seen query the width, max-width, and min-width, height, block-size, and inline-size as I’ve been doing throughout this article.

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

But MDN outlines two more things we can query against. One is orientation which makes perfect sense because we use it all the time in media queries. It’s no different with container queries:

@media screen (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

@container info-card (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

The other? It’s aspect-ratio, believe it or not:

@container info-card (aspect-ratio: 3/2) { 
  .info-card__inner {
    /* Style away! */
  }
} 

Here’s an editable demo to play around with both examples:

I haven’t really found a good use case for either of these yet. If you have any ideas or feel like it could’ve helped you in your projects, let me know in the comments!


A Few Times Container Size Queries Would Have Helped Me Out originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/a-few-times-container-size-queries-would-have-helped-me-out/feed/ 3 375728
Digging Deeper Into Container Style Queries https://css-tricks.com/digging-deeper-into-container-style-queries/ https://css-tricks.com/digging-deeper-into-container-style-queries/#comments Thu, 01 Dec 2022 13:59:06 +0000 https://css-tricks.com/?p=375607 I wrote up some early thoughts on container style queries a little while back. It’s still early days. They’re already defined in the CSS Containment Module Level 3 specification (currently in Editor’s Draft status) but there are still a couple …


Digging Deeper Into Container Style Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
I wrote up some early thoughts on container style queries a little while back. It’s still early days. They’re already defined in the CSS Containment Module Level 3 specification (currently in Editor’s Draft status) but there are still a couple of outstanding discussions taking place.

The basic idea is that we can define a container and then apply styles conditionally to its descendants based on its computed styling.

@container <name>? <conditions> {
  /* conditional styles */
}

The best example I’ve seen so far is removing italics from something like <em>, <i>, and <q> when they are used in a context where content is already italicized:

em, i, q {
  font-style: italic; /* default UA behavior */
}

/* When the container's font-style is italic, remove italics from these elements. */
@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

That’s the general idea. But if you didn’t know it, Miriam Suzanne, who is an editor of the spec, keeps an ongoing and thorough set of personal notes on container style queries that is publicly available. It was updated the other day and I spent some time in there trying to wrap my head around more nuanced aspects of style queries. It’s unofficial stuff, but I thought I’d jot down some things that stood out to me. Who knows? Maybe it’s stuff we can eventually look forward to!

Every element is a style container

We don’t even need to explictly assign a container-name or container-type to define a style container because everything is a style container by default.

So, you see that example above that removes italics? Notice it doesn’t identify a container. It jumps right to the query using the style() function. So, what container is being queried? It’s going to be the direct parent of the elements receiving the applied styles. And if not that, then it’s the next nearest relative container that takes precedence.

I like that. It’s very CSS-y for the query to search up for a match, then continue to bubble up until it finds a matching condition.

It was hard for my little brain to understand why we can get away with an implicit container based on styles but not so much when we’re dealing with dimensional queries, like size and inline-size. Miriam explains it nicely:

Dimensional queries require css containment on the size, layout, and style of the container in order to prevent layout loops. Containment is an invasive thing to apply broadly, so it was important that authors have careful control over what elements are (or are not) size containers.

Style-based queries don’t have the same limitation. There is already no way in CSS for descendant styles to have an impact on the computed styles of an ancestor. So no containment is required, and there are no invasive or unexpected side-effects in establishing an element as a style query container.

(Emphasis mine)

It all comes down to consequences — of which there are none as far as everything being a style query container right out of the box.

  • If a container is found: conditions are resolved against that container.
  • If multiple containers match: the nearest relative container takes precedence.
  • If no matches are found: unknown returned.

That’s the same “forgiving” spirit as the rest of CSS.

A container can support both dimensional and style queries

Let’s say we want define a style query without an explicit container-name:

@container style(font-style: italic) {
  em {
    font-style: normal;
  }
}

This works because all elements are style containers, no matter the container-type. That’s what allows us to implicitly query styles and rely on the nearest match. And this is totally fine since, again, there are no adverse side effects when establishing style containers.

We have to use an explicit container-type for dimensional queries, but not so much for style queries since every element is a style query. That also means this container is both a style and dimensional query:

.card-container {
  container: card / inline-size; /* implictly a style query container as well */
}

Excluding a container from being queried

Perhaps we don’t want a container to participate in the matching process. That’s where it might be possible to set container-type: none on an element.

.some-element {
  container-type: none;
}

Explicit style query containers offer more control of what gets queried

If, say, we were to write a style query for padding , there is no reliable way to determine the best matching container, regardless of whether we’re working with an explicitly named container or the nearest direct parent. That’s because padding is not an inherited property.

So, in those instances, we ought to use container-name to explictly inform the browser which containers they can pull from. We can even give a container multiple explicit names to make it match more conditions:

.card {
  container-name: card layout theme;
}

Oh, and container-name accepts any number of optional and reusable names for a container! That’s even more flexibility when it comes to helping the browser make a choice when searching for matches.

.theme {
  container-name: theme;
}
.grid {
  container-name: layout;
}
.card {
  container-name: card layout theme;
}

I sort of wonder if that might also be considered a “fallback” in the event that one container is passed over.

Style queries can be combined

The or and and operators allow us to combine wueries to keep things DRY:

@container bubble style(--arrow-position: start start) or style(--arrow-position: end start) {
  .bubble::after {
    border-block-end-color: inherit;
    inset-block-end: 100%;
  }
}

/* is the same as... */
@container bubble style(--arrow-position: start start) {
  /* etc. */
}
@container bubble style(--arrow-position: end start) {
  /* etc. */
}

Toggling styles

There’s a little overlap between container style queries and work being done to define a toggle() function. For example, we can cycle through two font-style values, say italic and normal:

em, i, q {
  font-style: italic;
}

@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

Cool. But the proposal for CSS Toggles suggests that the toggle() function would be a simpler approach:

em, i, q {
  font-style: toggle(italic, normal);
}

But anything beyond this sort of binary use case is where toggle() is less suitable. Style queries, though, are good to go. Miriam identifies three instances where style queries are more suitable than a toggle():

/* When font-style is italic, apply background color. */
/* Toggles can only handle one property at a time. */
@container style(font-style: italic) {
  em, i, q {
    background: lightpink;
  }
}

/* When font-style is italic and --color-mode equals light */
/* Toggles can only evaluate one condition at a time */
@container style((font-style: italic) and (--color-mode: light)) {
  em, i, q {
    background: lightpink;
  }
}

/* Apply the same query condition to multiple properties */
/* Toggles have to set each one individually as separate toggles */
@container style(font-style: italic) {
  em, i, q {
    /* clipped gradient text */
    background: var(--feature-gradient);
    background-clip: text;
    box-decoration-break: clone;
    color: transparent;
    text-shadow: none;
  }
}

Style queries solve the “Custom Property Toggle Hack”

Notice that style queries are a formal solution for the “CSS custom property toggle trick”. In there, we set an empty custom property (--foo: ;) and use the comma-separated fallback method to “toggle” properties on and off when then custom property is set to a real value.

button {
  --is-raised: ; /* off by default */
  
  border: 1px solid var(--is-raised, rgb(0 0 0 / 0.1));
  box-shadow: var(
    --is-raised,
    0 1px hsl(0 0% 100% / 0.8) inset,
    0 0.1em 0.1em -0.1em rgb(0 0 0 / 0.2)
  );
  text-shadow: var(--is-raised, 0 -1px 1px rgb(0 0 0 / 0.3));
}

button:active {
  box-shadow: var(--is-raised, 0 1px 0.2em black inset);
}

#foo {
  --is-raised: initial; /* turned on, all fallbacks take effect. */
}

That’s super cool, also a lot of work that style container queries makes trivial.

Style queries and CSS generated content

For generated content produced by the content property of ::before and ::after pseudo-elements, the matching container is the element on which the content is generated.

.bubble {
  --arrow-position: end end;
  container: bubble;
  border: medium solid green;
  position: relative;
}

.bubble::after {
  content: "";
  border: 1em solid transparent;
  position: absolute;
}

@container bubble style(--arrow-position: end end) {
  .bubble::after {
    border-block-start-color: inherit;
    inset-block-start: 100%;
    inset-inline-end: 1em;
  }
}

Style queries and web components

We can define a web component as a container and query it by style. First, we have the <template> of the component:

<template id="media-host">
  <article>
    <div part="img">
      <slot name="img">…</slot>
    </div>
    <div part="content">
      <slot name="title">…</slot>
      <slot name="content">…</slot>
    </div>
  </article>
</template>

Then we use the :host pseudo-element as a container to set a container-name, a container-type, and some high-level attributes on it:

:host {
  container: media-host / inline-size;
  --media-location: before;
  --media-style: square;
  --theme: light;
}

Elements inside the <media-host> can query the parameters of the <media-host> element:

@container media-host style(--media-style: round) {
  [part='img'] {
    border-radius: 100%;
  }
}

What’s next?

Again, all the stuff I’ve jotted down here is based on Miriam’s notes, and those notes are not a substitute for the official spec. But they are an indication of what’s being discussed and where things could land in the future. I appreciate Miriam linked up a handful of outstanding discussions still taking place that we can follow to stay on top of things:


Digging Deeper Into Container Style Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/digging-deeper-into-container-style-queries/feed/ 3 375607
Early Days of Container Style Queries https://css-tricks.com/early-days-of-container-style-queries/ https://css-tricks.com/early-days-of-container-style-queries/#comments Wed, 12 Oct 2022 13:06:46 +0000 https://css-tricks.com/?p=374330 We’re still in suuuuuper early days with container queries. Too early for broad browser support, but Chromium already supports it, Safari started supporting it in version 16, and Firefox is presumably not far behind.

Most early days conversations …


Early Days of Container Style Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
We’re still in suuuuuper early days with container queries. Too early for broad browser support, but Chromium already supports it, Safari started supporting it in version 16, and Firefox is presumably not far behind.

Most early days conversations revolving around container queries usually compare the syntax to media queries.

/* Stacked flex container */
.post {
  display: flex;
  flex-direction: column;
}

/* Change direction when viewport is 600px or wider */
@media(min-width: 600px) {
  .post {
    flex-direction: row;
  }
}

/* Define the container */
.posts {
  container-name: posts;
  container-type: inline-size;
}

.post {
  display: flex;
  flex-direction: column;
}

/* Query the container's min-width */
@container posts (min-width: 600px) {
  /* Change styles when `posts` container is 600px or wider */
  .post {
    flex-direction: row;
  }
}

Both of these are making queries for min-width: 600. The difference is that the media query is looking at the viewport’s width to trigger those style changes while the container query is looking at the computed width of the .posts element. Sweet!

But after listening to CSS Podcast Episode 59, Una and Adam poked at the future of container queries: style queries! The current working draft of the CSS Containment Module Level 3 spec defines container style queries:

container style query allows querying the computed values of the query container. It is a boolean combination of individual style features (<style-feature>) that each query a single, specific property of the query container.

But no examples on syntax just yet — only a brief description:

The syntax of a <style-feature> is the same as for a declaration, and its query is true if the computed value of the given property on the query container matches the given value (which is also computed with respect to the query container), unknown if the property or its value is invalid or unsupported, and false otherwise. The boolean syntax and logic combining style features into a style query is the same as for CSS feature queries. (See @supports.)

So, yes, given time we should expect to pull off something like this:

.posts {
  container-name: posts;
}

@container posts (background-color: #f8a100) {
  /* Change styles when `posts` container has an orange background */
  .post {
    color: #fff;
  }
}

That’s a pretty dumb example. One thing to note is that the container-type is no longer based on the container’s inline-size but by style. We could delcare that like so:

.posts {
  container-name: posts;
  container-type: style; /* unnecessary */
}

…but all container queries are style queries by default. Well. at least as it stands today. Miriam Suzanne has a nice outline of the possible issues that might pop up with that.

Where might querying a container’s styles come in handy? I don’t know yet! But my mind goes to a few places:

  • Custom property values: We’ve seen custom properties used like state indicators, such as the DRY-switching method Ana covered a while back. The value changes, and so do styles.
  • Alternate dark mode approach: Instead of basing it all on a body class change that re-assigns custom property values, maybe we can change an entire color palette if, say, the body background changes color.
  • More complex query conditions: Like, say, we want to apply styles when the size and style conditions for a container are met.

Una also mentioned in the CSS Podcast that container style queries could help prevent some awkward styling situations, like if we happen to have italicized text in an already italicized blockquote:

blockquote {
  container-name: quote;
}

@container quote (font-style: italic) {
  em, i, q, address {
    font-style: normal;
  }
}

Early Days of Container Style Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/early-days-of-container-style-queries/feed/ 5 374330
iShadeed’s Container Queries Lab https://css-tricks.com/ishadeeds-container-queries-lab/ https://css-tricks.com/ishadeeds-container-queries-lab/#comments Thu, 01 Sep 2022 14:29:27 +0000 https://css-tricks.com/?p=373087 Ahmad Shadeed got an early jump on container queries and has a growing collection of examples based on everyday patterns.

And, if you missed it, his latest post on container queries does a wonderful job covering how they work since …


iShadeed’s Container Queries Lab originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Ahmad Shadeed got an early jump on container queries and has a growing collection of examples based on everyday patterns.

And, if you missed it, his latest post on container queries does a wonderful job covering how they work since landing in Chrome 105 this month (we’ll see them in Safari 16 soon). Some choice highlights and takeaways:

  • Containers are defined with the container-type property. Previous demos and proposals had been using contain instead.
  • Container queries are very much like the media queries we’ve been writing all along to target the viewport size. So, rather than something like @media (min-width: 600px) {}, we have @container (min-width: 600px) {}. That should make converting many of those media queries to container queries fairly straightfoward, minus the work of figuring out the new breakpoint values.
  • We can name containers to help distinguish them in our code (e.g. container-name: blockquote).

Great job, Ahmad! And thanks for sharing!

To Shared LinkPermalink on CSS-Tricks


iShadeed’s Container Queries Lab originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/ishadeeds-container-queries-lab/feed/ 1 373087
A New Container Query Polyfill That Just Works https://css-tricks.com/a-new-container-query-polyfill-that-just-works/ https://css-tricks.com/a-new-container-query-polyfill-that-just-works/#comments Thu, 06 Jan 2022 22:28:46 +0000 https://css-tricks.com/?p=360320 There is an easy-to-use CSS container query polyfill now. You essentially conditionally load it and forget about it. Then write spec-compliant container queries code.


A New Container Query Polyfill That Just Works originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
There is now a polyfill for Container Queries that behaves as perfectly as a polyfill should:

  1. You conditionally load it when you detect the browser doesn’t support Container Queries.
  2. You write CSS as you normally would, including current-spec-compliant Container Queries syntax code.
  3. It just works.

It’s pretty great to have a container query polyfill that is this easy to use and from Chrome itself, the first-movers as far as early test implementations. Looks like Surma put it together — thanks Surma!

There was a Container Query polyfill from Jonathan Neal called cqfill that predates this. I’m not sure if it’s officially deprecated, but it required extra non-spec CSS to work and PostCSS processing, so I’d consider it deprecated in favor of this newer polyfill.

Loading the polyfill is like this:

// Support Test
const supportsContainerQueries = "container" in document.documentElement.style;

// Conditional Import
if (!supportsContainerQueries) {
  import("https://cdn.skypack.dev/container-query-polyfill");
}

You can pull it from npm or use as a <script>, but this way seems best to me to keep things light and easy.

Then you’re free to use the syntax for a container query in CSS. Say you have a weather widget in HTML. You’ll need an extra wrapper element for your queries. That’s just the rule: you can’t query the thing you style.

<div class="weather-wrap">
  <dl class="weather">
    <div>
      <dt>Sunday</dt>
      <dd>
        <b>26°</b> 7°
      </dd>
    </div>
    <div>
      <dt>Monday</dt>
      <dd>
        <b>34°</b> 11°
      </dd>
    </div>
    <!-- etc -->
  </dl>
</div>

The wrapper is instantiated as a container:

.weather-wrap {
  container: inline-size / weather-wrapper;
  /* Shorthand for: */
  /* container-type: inline-size; */
  /* container-name: weather-wrapper; */

  /* For quick testing, do this to get a resize handle on desktop: */
  /* resize: both; */
  /* overflow: hidden; */
}

Then you write any global styling for that component, as well as container query scoped styles:

.weather {
  display: flex;
}
@container weather-wrapper size(max-width: 700px) {
  .weather {
    flex-direction: column;
  }
}

Container Queries polyfill example

Here’s that slightly more fleshed-out demo of the Container Query polyfill using an actual weather widget:

I first saw this over on Bramus’ blog, and he’s got a classic card demo going with this Container Query polyfill. Scroll up and down. You’ll see a row of bear cards at the top (if your browser window is wide enough), and then similar bear cards in different layout positions below that change into nicer formats when they can, based on the container query.

Container Query polyfill browser support

The polyfill docs say:

The polyfill relies on ResizeObserverMutationObserver and :is(). Therefore, it should work in all modern browsers, specifically Chrome/Edge 88+, Firefox 78+ and Safari 14+.

There are all sorts of other minor little caveats covered in those docs, including what it does and doesn’t support. Seems like mostly niche stuff to me — the main/typical use cases are covered.

A game changer?

As I write, we’ve seen behind-flag support for Container Queries in Chrome, and it is an official spec draft now:

That’s extremely exciting and points heavily toward browsers actually shipping with Container Queries, even if the syntax changes a bit on the way (it already has a number of times). But, of course, we have no idea if/when Container Queries do ship — and when that magical threshold is crossed, we also don’t know where we can use them without much worry, like we can with flexbox and grid now.

That “just use it” date is probably a decent ways off, but if you’re into the idea of polyfilling and being careful with progressive enhancement, I’d say the date for using Container Queries could be right now-ish. Looks to me like the polyfill script comes across the wire at 2.8kb, so it’s fairly trivial in size for something so important.

I suspect this polyfill will skyrocket usage of Container Queries in this coming year.

FOUC?

The fact that your styles only correctly apply after a JavaScript file is downloaded and executed puts sites into Flash of Unstyled Content (FOUC) territory. Here’s a video recording where I can see it on my own demo. I’m not sure there is a way around this other than intentionally delaying rendering, which is generally considered a no-no. Similar to loading web fonts, FOUC is probably a good thing as it means your content is never hidden or delayed, even if the shifts aren’t ideal. The FOUC should go away once browser support lands and the polyfill stops loading at all.

Have fun polyfilling container queries! I’d love to see more demos of it.

GitHub Repo for the Container Query Polyfill


A New Container Query Polyfill That Just Works originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/a-new-container-query-polyfill-that-just-works/feed/ 7 360320
Conditional Border Radius In CSS https://css-tricks.com/conditional-border-radius-in-css/ https://css-tricks.com/conditional-border-radius-in-css/#comments Tue, 05 Oct 2021 19:18:43 +0000 https://css-tricks.com/?p=353261 Ahmad Shadeed documents a bonafide CSS trick from the Facebook CSS codebase. The idea is that when an element is the full width of the viewport, it doesn’t have any border-radius. But otherwise, it has 8px of border-radius. …


Conditional Border Radius In CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Ahmad Shadeed documents a bonafide CSS trick from the Facebook CSS codebase. The idea is that when an element is the full width of the viewport, it doesn’t have any border-radius. But otherwise, it has 8px of border-radius. Here’s the code:

.card {
  border-radius: max(0px, min(8px, calc((100vw - 4px - 100%) * 9999)));
}

One line! Super neat. The guts of it is the comparison between 100vw and 100%. Essentially, the border-radius comes out to 8px most of the time. But if the component becomes the same width as the viewport (within 4px, but I’d say that part is optional), then the value of the border-radius becomes 0px, because the equation yields a negative (invalid) number.

The 9999 multiplication means that you’ll never get low-positive numbers. It’s a toggle. You’ll either get 8px or 0px and nothing in between. Try removing that part, resizing the screen, and seeing it sorta morph as the viewport becomes close to the component size:

Why do it like this rather than at a @media query? Frank, the developer behind the Facebook choice, says:

It’s not a media query, which compares the viewport to a fixed width. It’s effectively a kind of container query that compares the viewport to its own variable width.

Frank Yan

And:

This is a more general purpose solution as it doesn’t need to know the size of the card. A media query would be dependent on the width of the card.

Naman Goel

The technique is apparently called the “Fab Four” Technique which is useful in emails.

To Shared LinkPermalink on CSS-Tricks


Conditional Border Radius In CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/conditional-border-radius-in-css/feed/ 4 353261
Container Units Should Be Pretty Handy https://css-tricks.com/container-units-should-be-pretty-handy/ https://css-tricks.com/container-units-should-be-pretty-handy/#comments Wed, 22 Sep 2021 23:09:44 +0000 https://css-tricks.com/?p=352210 Container queries are going to solve this long-standing issue in web design where we want to make design choices based on the size of an element (the container) rather than the size of the entire page. So, if a container …


Container Units Should Be Pretty Handy originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Container queries are going to solve this long-standing issue in web design where we want to make design choices based on the size of an element (the container) rather than the size of the entire page. So, if a container is 600px wide, perhaps it has a row-like design, but any narrower than that it has a column-like design, and we’ll have that kind of control. That’s much different than transitioning between layouts based on screen size.

We can already size some things based on the size of an element, thanks to the % unit. For example, all these containers are 50% as wide as their parent container.

The % here is 1-to-1 with the property in use, so width is a % of width. Likewise, I could use % for font-size, but it will be a % of the parent container’s font-size. There is nothing that lets me cross properties and set the font-size as a % of a container’s width.

That is, unless we get container units! Here’s the table of units per the draft spec:

unitrelative to
qw1% of a query container’s width
qh1% of a query container’s height
qi1% of a query container’s inline size
qb1% of a query container’s block size
qminThe smaller value of qi or qb
qmaxThe larger value of qi or qb

With these, I could easily set the font-size to a percentage of the parent container’s width. Or line-height! Or gap! Or margin! Or whatever!

Miriam notes that we can actually play with these units right now in Chrome Canary, as long as the container queries flag is on.

I had a quick play too. I’ll just put a video here as that’ll be easier to see in these super early days.

And some great exploratory work from Scott here as well:

https://twitter.com/ScottKellum/status/1436360780535025688

Ahmad Shadeed is also all over this!

Query units can save us effort and time when dealing with things like font-sizepadding, and margin within a component. Instead of manually increasing the font size, we can use query units instead.

Ahmad Shadeed, “CSS Container Query Units”

Maybe container queries and container units will drop for real at the same time. 🤷


Container Units Should Be Pretty Handy originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/container-units-should-be-pretty-handy/feed/ 3 https://css-tricks.com/wp-content/uploads/2021/09/CleanShot-2021-09-17-at-15.06.57.mp4 Container-queries Archives - CSS-Tricks nonadult 352210
Are we in a new era of web design? What do we call it? https://css-tricks.com/are-we-in-a-new-era-of-web-design-what-do-we-call-it/ https://css-tricks.com/are-we-in-a-new-era-of-web-design-what-do-we-call-it/#comments Mon, 21 Jun 2021 21:22:33 +0000 https://css-tricks.com/?p=342887 Una is calling it the new responsive. A nod to the era we were most certainly in, the era of responsive design. Where responsive design was fluid grids, flexible media, and media queries, the new responsive is those things …


Are we in a new era of web design? What do we call it? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Una is calling it the new responsive. A nod to the era we were most certainly in, the era of responsive design. Where responsive design was fluid grids, flexible media, and media queries, the new responsive is those things too, but slotted into a wider scope: user preference queries, viewport and form factor, macro layouts, and container styles.

I like the thinking and grouping here and I kinda like the name. It alludes to an evolution and extension of responsive web design rather than a rejection and replacement.

This isn’t the first crack at identifying and naming a shift between eras. Back in 2018, Jen Simmons was doing a talked called “Everything You Know About Web Design Just Changed” where she identified that responsive design was a major shift in how we did layout on the web. And yet, it was firmly defined in an era where layout tools like flexbox and grid didn’t even exist. Now, they do exist, and with them a bevy of other new features that bring more capable graphic design to the web. She called it Intrinsic Design.

I almost like Intrinsic Design more now than I did in 2018, because now, if we attempt to lump in @container queries, the name makes more intuitive sense. We (hopefully will soon) make styling choices based on the intrinsic size of elements. We make styling choices based on the intrinsic nature of the individual users we serve. We make styling choices off the intrinsic qualities of the browser.

I wouldn’t say either of the terms have really caught on though. It’s hard to make a name stick. That little burst of ideating around CSS4 sure didn’t go anywhere.

To Shared LinkPermalink on CSS-Tricks


Are we in a new era of web design? What do we call it? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/are-we-in-a-new-era-of-web-design-what-do-we-call-it/feed/ 7 342887
Media Queries in Times of @container https://css-tricks.com/media_queries_in_times_of_container/ https://css-tricks.com/media_queries_in_times_of_container/#respond Tue, 15 Jun 2021 19:51:32 +0000 https://css-tricks.com/?p=342519 Max Böck took me up on my challenge to look through a codebase and see how many of the @media queries could ultimately become @container queries.

I took the bait and had a look at some of my projects –


Media Queries in Times of @container originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Max Böck took me up on my challenge to look through a codebase and see how many of the @media queries could ultimately become @container queries.

I took the bait and had a look at some of my projects – and yes, most of what I use @media for today can probably be accomplished by @container at some point. Nevertheless, I came up with a few scenarios where I think media queries will still be necessary.

Max didn’t say exactly how many would be replaced, but I got the impression it was 50/50ish.

A combination of both techniques will probably be the best way forward. @media can handle the big picture stuff, user preferences and global styles; @container will take care of all the micro-adjustments in the components themselves.

A perfect team!

I also think there will be a big difference between what we do when refactoring an existing CSS codebase to what we do when we are building from scratch. And it will be different what we do when we first get container queries to what we do years from now when new patterns have settled in. I’ve long been bullish on components being the right abstraction for front-end development. It feels like everything lately pushes us in that direction, from JavaScript frameworks and to native components, to container queries and style scoping.

To Shared LinkPermalink on CSS-Tricks


Media Queries in Times of @container originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/media_queries_in_times_of_container/feed/ 0 342519
A Cornucopia of Container Queries https://css-tricks.com/a-cornucopia-of-container-queries/ https://css-tricks.com/a-cornucopia-of-container-queries/#respond Wed, 09 Jun 2021 20:37:00 +0000 https://css-tricks.com/?p=340967 I don’t know about y’all, but my feeds have been flooded with articles about CSS Container Queries these past few weeks. The buzz about container queries actually started back in December after Miriam Suzanne posted a proposal (picking up on …


A Cornucopia of Container Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
I don’t know about y’all, but my feeds have been flooded with articles about CSS Container Queries these past few weeks. The buzz about container queries actually started back in December after Miriam Suzanne posted a proposal (picking up on David Baron’s proposal) but it was news in a late-March tweet from Una Kravets that they dropped in Chrome Canary 91.0.4459.0 behind the #enable-container-queries flag in chrome://flags.

So much about container queries has already been covered in so many places in such a short amount of time — and the specification isn’t even final! I’m just pleased as punch to see so much excitement about a CSS feature and wanted to bottle some it up. Chris also just to happened to be collecting a pile of links on the topic, so here’s a roundup of everything that’s crossed our desks.

Container Queries Explainer & Proposal

Miriam’s article is an excellent starting point to kick things off. This is sort of like the elevator pitch that introduces the idea while providing a bunch of examples and resources that are worth checking out.

Container Queries: a Quick Start Guide

David Herron jumps right into the concept over on the Oddbird blog, which is fitting since that’s where Miriam Suzanne works as well. This is a great introduction to container queries that gets into the syntax with an example that looks at a card component.

A Primer on CSS Container Queries

Stephanie Eckles goes super deep into container queries over on Smashing Magazine. I love that the article starts off by stating what container queries solves before jumping into the syntax and how-to.

Container Queries are actually coming

Andy Bell has wanted container queries as long as anyone. He wasted no time jumping into them with a card example of his own. And hey, he can finally retire his sticker.

Say Hello To Container Queries

I always appreciate both the way Ahmed Shadeed explains things in the simplest possible terms, and that his demos go beyond common examples and into interesting use cases.

CSS Container Queries: A First Look + Demo

OK, this is cheating since Bramus published this at the end of March. But it was really after this post when I started seeing others pour in.

Next Gen CSS: @container

Yes, CSS-Tricks added to the chatter as well! Una Kravets has what might be my favorite demo of container queries so far: a calendar that adjusts everything from font sizes to layout

Container Queries in Web Components

Max Böck does what I love best: take two ideas and smash ’em together! He made a stellar demo of a web component for displaying books and integrates @container.

Component-level art direction with CSS Container Queries

Sara Soueidan shows how container queries can be used to art direct images, including gotchas that come with using the <picture> element with @container.

Susy and Sass, CSS Layers and CSS compatibility, Container Queries and CSSWG

Listen to Bruce Lawson and Vadim Makeev discuss container queries (among other things) with Miriam.

Container Queries are going to be a game changer!

Watch Kevin Powell demo how those fancy auto-fill/minmax() grids are a nice use case for components styling themselves based on how big they are at any given point.

CSS Container Queries Polyfill FIRST LOOK

Scott Tolinski looks at cqfill. Bramus does the same here in this blog post. The best part of Scott’s video is adding transitions on the changed properties.

Can We Create a “Resize Hack” With Container Queries?

Jhey Tompkins was already feeling there is too many card demos for container queries and wanted to do something super different.

Container Queries & The Future of CSS

There’s no such thing as too much when it comes to learning about containers from Miriam Suzanne. Here’s a conference video.

Container Queries for Designers

Ahmad Shadeed says designers might want to start thinking about container queries. Having a document that outlines breakpoints for a single component seems like the way to go for now.

CSS Container Queries: Use-Cases And Migration Strategies

Adrian Bece covers the basics here, and pointed out a few things I didn’t know. One, there are no DevTools for for container queries yet, making them tricky to debug.

The new responsive: Web design in a component-driven world

Una Kravets connects not just container queries, but other concepts to facilitate this component-driven world. Sounds like native scoped styles might have a bit of traction again!

All Them Switches: Responsive Elements and More

Brian Kardell’s article is more about a possible switch() function (and keyword friends) that look very useful, even independent of container queries.


Quite a bit, right? Before we sign off, Chris has a challenge for all of us he wanted to share:

A common refrain, from me included, has been that if we had container queries we’d use them for the vast majority of what we use media queries for today. The challenge is: look through your CSS codebase now with fresh eyes knowing how the @container queries currently work. Does that refrain hold up? Which media queries will you replace (once we reasonably can) and which ones have to remain? Blog that.


A Cornucopia of Container Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/a-cornucopia-of-container-queries/feed/ 0 340967
Can We Create a “Resize Hack” With Container Queries? https://css-tricks.com/can-we-create-a-resize-hack-with-container-queries/ https://css-tricks.com/can-we-create-a-resize-hack-with-container-queries/#comments Thu, 20 May 2021 14:24:12 +0000 https://css-tricks.com/?p=340715 If you follow new developments in CSS, you’ve likely heard of the impending arrival of container queries. We’re going to look at the basics here, but if you’d like another look, check out Una’s “Next Gen CSS: @container” article. …


Can We Create a “Resize Hack” With Container Queries? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
If you follow new developments in CSS, you’ve likely heard of the impending arrival of container queries. We’re going to look at the basics here, but if you’d like another look, check out Una’s “Next Gen CSS: @container” article. After we have a poke at the basics ourselves, we’re going to build something super fun with them: a fresh take on the classic CSS meme featuring Peter Griffin fussing with window blinds. ;)

So, what is a container query? It’s… exactly that. Much like we have media queries for querying things such as the viewport size, a container query allows us to query the size of a container. Based on that, we can then apply different styles to the children of said container.

What does it look like? It’s something like this:

.container {
  container-name: my-container;
  container-type: inline-size;
  /* or */
  container: my-container inline-size;
}

@container my-container (min-width: 768px) {
  .child { background: hotpink; }
}

The my-container keyword targets the container for the container query by container-name. inline-size allows users to be more specific about containment. This currently means we can only query the container’s width. With size, we are able to query the container’s height.

You can use container queries (without a polyfill) as of Chrome version 105 and Safari 16. I would definitely recommend having a quick read through the drafts over on csswg.org.

The easiest way to start playing would be to whip up a couple of quick demos that sport a resizable container element.

Try changing the container values and see how the demos respond. These demos use container-type: size which doesn’t restrict the axis. When both the height and width of the containers meet certain thresholds, the shirt sizing adjusts in the first demo. The second demo shows how the axes can work individually instead, where the beard changes color, but only when adjusting the horizontal axis.

@container (min-width: 400px) and (min-height: 400px) {
  .t-shirt__container {
    --size: "L";
    --scale: 2;
  }
}

That’s what you need to know about container queries for now. It’s really just a few new lines of CSS.

The only thing is most demos for container queries I’ve seen so far use a pretty standard “card” example to demonstrate the concept. Don’t get me wrong, because cards are a great use case for container queries. A card component is practically the poster child of container queries. Consider a generic card design and how it could get affected when used in different layouts. This is a common problem. Many of us have worked on projects where we wind up making various card variations, all catering to the different layouts that use them.

But cards don‘t inspire much to start playing with container queries. I want to see them pushed to greater limits to do interesting things. I‘ve played with them a little in that t-shirt sizing demo. And I was going to wait until there was better browser support until I started digging in further (I’m a Brave user currently). But then Bramus shared there was a container query polyfill!

And this got me thinking about ways to “hack” container queries.

⚠️ Spoiler alert: My hack didn’t work. It did momentarily, or at least I thought it did. But, this was actually a blessing because it prompted more conversation around container queries. And now there is a new container queries polyfill.

What was my idea? I wanted to create something sort of like the “Checkbox Hack” but for container queries.

<div class="container">
  <div class="container__resizer"></div>
  <div class="container__fixed-content"></div>
</div>

The idea is that you could have a container with a resizable element inside it, and then another element that gets fixed positioning outside of the container. Resizing containers could trigger container queries and restyle the fixed elements.

.container {
  container: layout size;
}

.container__resize {
  resize: vertical;
  overflow: hidden;
  width: 200px;
  min-height: 100px;
  max-height: 500px;
}

.container__fixed-content {
  position: fixed;
  left: 200%;
  top: 0;
  background: red;
}

@container(min-height: 300px) {
  .container__fixed-content {
    background: blue;
  }
}

This did work with those earlier versions of the cqfill polyfill.

Can we debunk a classic CSS meme with container queries?

Seeing this work excited me a bunch. Finally, an opportunity to create a version of the Peter Griffin CSS meme with CSS and debunk it!

You’ve probably seen the meme. It’s a knock on the Cascade and how difficult it is to manage it. I created the demo using cqfill@0.5.0… with my own little touches, of course. 😅

Moving the cord handle, resized an element which in turn affected the container size. Different container breakpoints would update a CSS variable, --open, from 0 to 1, where 1 is equal to an “open” and 0 is equal to a “closed” state.

@container (min-height: 54px) {
  .blinds__blinds {
    --open: 0.1;
  }
}
@media --css-container and (min-height: 54px) {
  .blinds__blinds {
    --open: 0.1;
  }
}
@container (min-height: 58px) {
  .blinds__blinds {
    --open: 0.2;
  }
}
@media --css-container and (min-height: 58px) {
  .blinds__blinds {
    --open: 0.2;
  }
}
@container (min-height: 62px) {
  .blinds__blinds {
    --open: 0.3;
  }
}
@media --css-container and (min-height: 62px) {
  .blinds__blinds {
    --open: 0.3;
  }
}

But…. as I mentioned, this hack isn’t possible.

What’s great here is that it prompted conversation around how container queries work. It also highlighted a bug with the container query polyfill which was fixed. I would love to see this “hack” work though.

Miriam Suzanne has been creating some fantastic content around container queries. The capabilities have been changing a bunch. That’s the risk of living on the bleeding edge. One of her latest articles sums up the current status.

Although my original demo/hack didn’t work, we can still kinda use a “resize” hack to create those blinds. Again, we can query height if we use container-type: size.

Consider this demo:

The arrow rotates as the container is resized. The trick here is to use a container query to update a scoped CSS custom property.

.container {
  container-type: size;
}

.arrow {
  transform: rotate(var(--rotate, 0deg));
}

@container(min-height: 200px) {
  .arrow {
    --rotate: 90deg;
  }
}

We‘ve kinda got a container query trick here then. The drawback with not being able to use the first hack concept is that we can’t go completely 3D. Overflow hidden will stop that. We also need the cord to go beneath the window which means the windowsill would get in the way.

But, we can almost get there.

This demo uses container query steps. At each step, a scoped custom property gets updated. This reveals Peter and opens the blinds.

The trick here is to scale up the container to make the resize handle bigger. Then I scale down the content to fit back where it’s meant to.


This fun demo “debunking the meme” isn’t 100% there yet, but, we’re getting close. Container queries are an exciting prospect. And it’ll be interesting to see how they change as browser support evolves. It’ll also be exciting to see how people push the limits with them or use them in different ways.

Who knows? The “Resize Hack” might fit in nicely alongside the infamous “Checkbox Hack” one day.


Can We Create a “Resize Hack” With Container Queries? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/can-we-create-a-resize-hack-with-container-queries/feed/ 2 340715