Container Queries
Recap
In another blog post I have written about Grid Containers and Grid Elements. Quick refresh - this is how my components look in action.
You can try out to resize the two Elements and you will notice that their appearance does not change.
Container Queries
Now it would be interesting to let those boxes resize their text content according to the space that they have available:
The above example with below code will be our starting point for further experiments. You will find in my Svelte Code (HTML + CSS) that I target the element with a div container of class element-content
.
To the GridElement Container I have added the css container-type: inline-size;
. Similar like elements with position: absolute;
finds their parent element that has position: relative;
we need to tell the GridElement that they are parent of our div element-content
.
<GridContainer cols={10} rows={5} cellheight={50} helpers>
<GridElement
grid_row={2}
grid_column={1}
colSpan={2}
rowSpan={2}>
<div class="element-content-0">
Element 1
</div>
</GridElement>
</GridContainer>
<style>
.element-content-0 {
font-weight: 700;
text-align: center;
@container (min-width: 100px) { font-size: 1em; }
@container (min-width: 200px) { font-size: 2em; }
@container (min-width: 300px) { font-size: 3em; }
@container (min-width: 400px) { font-size: 4em; }
@container (min-width: 500px) { font-size: 5em; }
}
</style>
This approach has it’s limitations: Have a look at the example below:
Here I am overshooting the grid cell with the bigger font size. How can we solve that?
This time I combined the min-width and min-height to catch those edge cases:
.element-content-1 {
font-weight: 700;
text-align: center;
@container (min-width: 100px) { font-size: 1em; }
@container (min-width: 200px) { font-size: 2em; }
@container (min-width: 250px) and (min-height: 60px) { font-size: 3em; }
@container (min-width: 400px) and (min-height: 60px) { font-size: 4em; }
@container (min-width: 500px) and (min-height: 60px) { font-size: 5em; }
}
Next edge case - What if our grid has a different size?
Using Container Query Units
Solution: Use calculated values. Instead of hardcoding every breakpoint we can use fluid responsiveness by making use of new container query length units. They are comparable to vw, vh, etc. that are relative to the viewport.
With
<style>
.element-content-2 {
font-weight: 700;
text-align: center;
font-size: clamp(1em, 15cqi, 5em);
}
</style>
we can achieve a minimum font size of 1em and maximum of 5em, just as before. The values in between get calculated automatically depending on the width of the container.
As you can see the @container query for adjusting to the width is not necessary. We can simply use the new “15cqi” which is a relative unit based on the containers width.
Unfortunately we still have to deal with the height of the container. But this is something I will take care of another time.