Skip to content

Instantly share code, notes, and snippets.

@scottkellum
Created November 13, 2020 18:22
Show Gist options
  • Save scottkellum/0c29c4722394c72d311c5045a30398e5 to your computer and use it in GitHub Desktop.
Save scottkellum/0c29c4722394c72d311c5045a30398e5 to your computer and use it in GitHub Desktop.
Query interpolation proposal

Query interpolation proposal

Based on @mirisuzanne’s container query proposal.

Sometimes hard breakpoints aren’t ideal in that we might want to add fluidity to how things are adjusted across screen sizes. Like Goldilocks and the three bears, we often end up with values that are too big or too small and a lot of breakpoints are required to get things just right. We have things like clamp() now but it lacks easing funcitonality, user text scaling breaks reliability, and it only works to add fluidity to length measurements. This is a problem when adjusting font styles, variable font settings, color, opacity, and other values you might want to manupulate across varying widths. The lack of easing means control, especially at smaller sizes, is severly limited.

Below is an example based on Miriam’s work that includes interpolation of media queries.

<section>
	<div class="media-object">content</div>
</section>

And let’s add a context, along with specifying the easing that should be applied to queries. It can be applied globally to all media queries on the root element as well. This value will cascade.

section {
	contain: size;
	
	/* Proposal to interpolate keyframes when specified */
	context-ease: ease-in-out;
}
html {
	context-ease: ease-out;
}

Now, to add a media query that allows for interpolation. These are essentually anchor points that apply across all widths or heights until another anchor point is added. Only transitionable properties will interpolate, all other properties will behave as if this is a min-width query.

The following will have a font-size of 2rem at all sizes.

@container (interpolate-width: 45em) {
	.media-object {
		font-size: 2rem;
	}
}

The following will transition the font size from 1rem to 2rem and the color will shift fluidly, but the grid-template will only change at a width of 60em. The transition between these two queries will shift along the easing curve specified.

@container (interpolate-width: 15em) {
	.media-object {
		font-size: 1rem;
		color: blue;
	}
}
@container (interpolate-width: 60em) {
	.media-object {
		font-size: 2rem;
		color: green;
		grid-template: 'img content' auto / auto 1fr;
	}
}

As a result, you can define more styles across fiewer breakpoints. Currently many websites use numerous breakpoints to scale text and this can eliminate all of those breakpoints.

I have prototyped a similar technique and the result of container queires + interpolation is a 65% to 90% reduciton in text styles (font size, line height, etc) and the advantages go beyond styling text.

@mirisuzanne
Copy link

mirisuzanne commented Nov 13, 2020

I love what you're going for here - but I'm not sure the interpolation belongs inside the query @-rule syntax.

My first thought was to treat @container blocks as "keyframes" for interpolate-able values, and add a transition-like syntax for moving between them more smoothly. That only works if every container-query can be interpolated… but I think that might be true? Something like:

html {
  font-size: 100%;
  container-transition: font-size ease-in-out;
}

@container (width > 30) { html { font-size: 120%; } }
@container (width > 60) { html { font-size: 160%; } }

Another approach would be to give the entire thing a more @keyframes-like syntax of it's own:

/* <custom-ident> (<observable-value>) */
@container-keyframes typography (width) {
  30em { font-size: 120%; }
  60em { font-size: 160%; }
}

html {
  font-size: 100%;
  container-animation: typography ease-in-out;
}

That's more like the direction you were heading in your CSSWG issue: w3c/csswg-drafts#4343

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment