Debug panel

Close debug panel
Roma’s Unpolished Posts

Named Container Presence Check

Published on:
Last updated on:
Categories:
CSS Containers, CSS 88
Current music:
Haisuinonasa
Shower
Current drink:
Cappuccino

The Task

I was doing some styling recently, and I wanted to know if my element was inside a certain container.

.my-container {
	container-type: inline-size;
}
<div class="my-container">
	<div class="some-element">
		Where am I?
	</div>
</div>

<div class="some-element">
	And me, what about me?
</div>

While I could reuse the same selector that I used to apply the container with, this did not feel right: what if I were to apply the same container via a different selector? Or have a version of that element where the container is removed via some modifier?

Given I already had container-type: inline-size, and I literally wanted to know if this exact containment from this exact element was applied, as a way to differentiate between it and the viewport, using a named container to check this was pretty obvious.

Checking Named Containers

Generally, named containers — ones with the container-name property — are used for differentiating between them. What if you have multiple containers around an element, and you need to check the dimensions on a specific container? Is this a query for a card, or for content?

Usually, you’d use these containers to query either elements’ dimensions, or, with style container queries, values of custom properties on them.

For my purpose, I don’t care about any specific values: I only need to know about the presence of some named container. For different types of them, we can do this differently.

Querying a Size Container

For size containers things are pretty simple: if we have an established size container, we can add a container-name to it (or join the name with its type into a container shorthand), and then query it in an always-positive way alongside its name:

Where am I?
And me, what about me?
.my-container {
	container: --my-container / inline-size;
}

@container --my-container (min-width: 0) {
	.some-element {
		outline: 3px solid var(--GREEN);
	}
}
Example showing a green outline around an element inside a container. A containerless element does not have any outlines.

Some notes:

  • I am setting the name for our container using the shorthand. I am also using a dashed ident for it, even though containers allow any custom idents. I wrote a post about why I am doing this two years ago: Dashed Idents for Everything.

  • A container cannot have a negative width, so a min-width: 0 check will always match, but only if there is a --my-container somewhere in the tree around our some-element.

  • This will work only if we apply any container-type on our container: both size and inline-size will work for min-width, and if we’d want to check if our container is specifically size container, we’d need to check min-height: 0.

Style Querying any Container

Container style queries are almost here: Firefox should get them pretty soon. For querying styles of custom properties, we don’t need to have any containment, thus with container style queries we will be able to just name any element, and then query if we have this specific container somewhere in our element’s ancestors.

Where am I?
And me, what about me?
.my-styletainer {
	container-name: --my-styletainer;
}

@container --my-styletainer not (
	style(--a:a) and style(--a:b)
) {
	.my-element {
		outline: 3px solid var(--BLUE);
	}
}
Example showing blue outline around an element inside a container. A containerless element does not have any outlines.

In order to match a style container regardless of what its styles are, we can use a not (style(--a:a) and style(--a:b)) condition: it will be always truthy, as it is not possible to have some custom property that has two different values at the same time.

Why Not Regular Style Queries?

One could ask a question: couldn’t we just use style queries and then check some custom property like --container-name: --my-styletainer instead?

If we wanted to check if that container is the closest to our element — sure, that would be the way. However, what we want is to check if the container is present at all, without checking for its proximity.

Aren’t Those Hacky?

While the size containment check is pretty simple, we still have to establish the size containment. As for style queries, the check is very verbose. We could try to simplify it as not style(--\-) — use a name that will unlikely be present in our document, but it won’t be guaranteed.

Currently, @container --my-container {} won’t ever do anything: the follow-up condition is required. But what if we could use this simple notation to check for the named container’s presence? It will be pretty straighforward and simple.

I opened a CSSWG issue about this. If you have any use cases for this, write about them in this issue, otherwise, if you think it is a good idea — please, upvote it!

And — that’s it for today’s post! As it often goes: I thought it will be a simple one, but then ended up filling a Firefox bug and a CSSWG issue. Even more: this post was actually a side effect from starting to write another post, in which I used this “technique”, so I wanted to first briefly explain it in a separate post.

Update

After I published this post, Miriam noted that CSSWG already resolved on this 2 years ago, and Rune Lillesveen contributed WPT tests a year ago, which, as also tested by me, are still not passing.

I closed the issue I created as a duplicate. Now, I guess, the onus is on browsers: this feels like a very low-hanging fruit, as all necessary for verifying the presence of a container should be already done, this new feature is only excluding some of the checks browsers do when there is a query present.

Please share your thoughts about this on Mastodon!