Friday, December 2, 2022
HomeProgrammingDigging Deeper Into Container Fashion Queries | CSS-Tips

Digging Deeper Into Container Fashion Queries | CSS-Tips


I wrote up some early ideas on container fashion queries a short while again. It’s nonetheless early days. They’re already outlined within the CSS Containment Module Stage 1 specification (presently in Editor’s Draft standing) however there’s nonetheless a few excellent discussions going down.

The fundamental concept is that we will outline a container after which apply types conditionally to its descendants based mostly on its computed styling.

@container <identify>? <circumstances> {
  /* conditional types */
}

The very best instance I’ve seen to date is eradicating italics from one thing like <em>, <i>, and <q> when they’re utilized in a context the place content material is already italicized:

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

/* When the container's font-style is italic, take away italics from these parts. */
@container fashion(font-style: italic) {
  em, i, q {
    font-style: regular;
  }
}

That’s the overall concept. However should you didn’t realize it, Miriam Suzanne, who’s an editor of the spec, retains an ongoing and thorough set of private notes on container fashion queries that’s publicly accessible. It was up to date the opposite day and I spent a while in there making an attempt to wrap my head round extra nuanced facets of favor queries. It’s unofficial stuff, however I assumed I’d jot down some issues that stood out to me. Who is aware of? Possibly it’s stuff we will ultimately stay up for!

Each component is a method container

We don’t even must explictly assign a container-name or container-type to outline a method container as a result of the whole lot is a method container by default.

So, you see that instance above that removes italics? Discover it doesn’t determine a container. It jumps proper to the question utilizing the fashion() perform. So, what container is being queried? It’s going to be the direct mum or dad of the weather receiving the utilized types. And if not that, then it’s the following nearest relative container that takes priority.

I like that. It’s very CSS-y for the question to go looking up for a match, then proceed to bubble up till it finds an identical situation.

It was exhausting for my little mind to grasp why we will get away with an implicit container based mostly on types however not a lot after we’re coping with dimensional queries, like measurement and inline-size. Miriam explains it properly:

Dimensional queries require css containment on the scale, format, and elegance of the container with a purpose to stop format loops. Containment is an invasive factor to use broadly, so it was essential that authors have cautious management over what parts are (or usually are not) measurement containers.

Fashion-based queries don’t have the identical limitation. There may be already no means in CSS for descendant types to have an effect on the computed types of an ancestor. So no containment is required, and there aren’t any invasive or sudden side-effects in establishing a component as a fashion question container.

(Emphasis mine)

All of it comes all the way down to penalties — of which there are none so far as the whole lot being a method question container proper out of the field.

  • If a container is discovered: circumstances are resolved in opposition to that container.
  • If a number of containers match: the closest relative container takes priority.
  • If no matches are discovered: unknown returned.

That’s the identical “forgiving” spirit as the remainder of CSS.

A container can help each dimensional and elegance queries

Let’s say we wish outline a method question with out an specific container-name:

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

This works as a result of all parts are fashion containers, regardless of the container-type. That’s what permits us to implicitly question types and depend on the closest match. And that is completely wonderful since, once more, there aren’t any hostile unwanted effects when establishing fashion containers.

We have now to make use of an specific container-type for dimensional queries, however not a lot for fashion queries since each component is a method question. That additionally means this container is each a method and dimensional question:

.card-container {
  container: card / inline-size; /* implictly a method question container as properly */
}

Excluding a container from being queried

Maybe we don’t need a container to take part within the matching course of. That’s the place it is perhaps attainable to set container-type: none on a component.

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

Specific fashion question containers provide extra management of what will get queried

If, say, we had been to write down a method question for padding , there isn’t any dependable approach to decide the most effective matching container, no matter whether or not we’re working with an explicitly named container or the closest direct mum or dad. That’s as a result of padding just isn’t an inherited property.

So, in these cases, we ought to make use of container-name to explictly inform the browser which containers they’ll pull from. We will even give a container a number of specific names to make it match extra circumstances:

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

Oh, and container-name accepts any variety of optionally available and reusable names for a container! That’s much more flexibility in terms of serving to the browser make a selection when trying to find matches.

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

I type of surprise if that may even be thought-about a “fallback” within the occasion that one container is handed over.

Fashion queries will be mixed

The or and and operators enable us to mix wueries to maintain issues DRY:

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

/* is similar as... */
@container bubble fashion(--arrow-position: begin begin) {
  /* and so on. */
}
@container bubble fashion(--arrow-position: finish begin) {
  /* and so on. */
}

Toggling types

There’s a little bit overlap between container fashion queries and Tab Atkins’ unofficial proposal for CSS Toggles. For instance, we will cycle by two font-style values, say italic and regular:

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

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

Cool. However the proposal for CSS Toggles means that the toggle() perform can be an easier method:

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

However something past this type of binary use case is the place toggle() is much less appropriate. Fashion queries, although, are good to go. Miriam identifies three cases the place fashion queries are extra appropriate than a toggle():

/* When font-style is italic, apply background shade. */
/* Toggles can solely deal with one property at a time. */
@container fashion(font-style: italic) {
  em, i, q {
    background: lightpink;
  }
}

/* When font-style is italic and --color-mode equals mild */
/* Toggles can solely consider one situation at a time */
@container fashion((font-style: italic) and (--color-mode: mild)) {
  em, i, q {
    background: lightpink;
  }
}

/* Apply the identical question situation to a number of properties */
/* Toggles should set every one individually as separate toggles */
@container fashion(font-style: italic) {
  em, i, q {
    /* clipped gradient textual content */
    background: var(--feature-gradient);
    background-clip: textual content;
    box-decoration-break: clone;
    shade: clear;
    text-shadow: none;
  }
}

Fashion queries clear up the “Customized Property Toggle Hack”

Discover that fashion queries are a proper resolution for the “CSS customized property toggle trick”. In there, we set an empty customized property (--foo: ;) and use the comma-separated fallback methodology to “toggle” properties on and off when then customized property is about to an actual worth.

button {
  --is-raised: ; /* off by default */
  
  border: 1px strong 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:energetic {
  box-shadow: var(--is-raised, 0 1px 0.2em black inset);
}

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

That’s tremendous cool, additionally plenty of work that fashion container queries makes trivial.

Fashion queries and CSS generated content material

For generated content material produced by the content material property of ::earlier than and ::after pseudo-elements, the matching container is the component on which the content material is generated.

.bubble {
  --arrow-position: finish finish;
  container: bubble;
  border: medium strong inexperienced;
  place: relative;
}

.bubble::after {
  content material: "";
  border: 1em strong clear;
  place: absolute;
}

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

Fashion queries and net parts

We will outline an internet element as a container and question it by fashion. First, we’ve got the <template> of the element:

<template id="media-host">
  <article>
    <div half="img">
      <slot identify="img">…</slot>
    </div>
    <div half="content material">
      <slot identify="title">…</slot>
      <slot identify="content material">…</slot>
    </div>
  </article>
</template>

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

:host {
  container: media-host / inline-size;
  --media-location: earlier than;
  --media-style: sq.;
  --theme: mild;
}

Components contained in the <media-host> can question the parameters of the <media-host> component:

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

What’s subsequent?

Once more, all of the stuff I’ve jotted down right here is predicated on Miriam’s notes, and people notes usually are not an alternative to the official spec. However they’re a sign of what’s being mentioned and the place issues may land sooner or later. I respect Miriam linked up a handful of excellent discussions nonetheless going down that we will comply with to remain up to the mark:

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments