CSS quantity queries or pseudo-selectors are a lot more powerful than I thought they were. I mainly use them to select a certain element when there many. A simple example of this is getting the first or the last or the nth child element. CSS makes it easy to apply styling just to those elements - like the first one. But what about some things are a bit more complicated? I want to write them out in plain English just so you can see thes kind of complicated “math” that CSS can do (that I had no idea it could!). You’ll notice, some of them are if statements with operators, which CSS does not have - there’s a way to do it though. Check the written-out versions and then check below for examples.
- If only 1 specific element exists
- If there is more than 1 specific element
- If there are 8 elements, target the first element
- If there are 8 elements, target all the elements
- If there are 9 or more elements, target the 9th and above
Two Boxes
Just for illustration purposes, I’m making this layout where one of the boxes is a button. I needed to do this so that there are 2 different types of elements in here. This example will be if only 1 element exists. :only-of-type
only applies if there is one of that element.
<div class="container">
<button>1</button>
<div>2</div>
</div>
This is the CSS that I’ll be using for all examples to illustrate Flexbox:
.container{
display: flex
}
.container div, .container button{
width: 50%;
background: gray;
margin: 0 10px;
padding: 20px;
font-size: 40px;
color: white;
display: flex;
justify-content: center;
align-items: center;
}
.container button:only-of-type{
border: none;
background-color: green;
}
And this is what it looks like:
If they were both buttons, this is what we get. Notice that it doesn’t style the button tags because there are 2 button tags.
<div class="container">
<button>1</button>
<button>2</button>
</div>
And what if we swap that around to check to see if there is more than one? Which is this one if there is more than 1 element:
.container button:not(:only-of-type){
border: none;
background-color: green;
}
Which will get us the below. Because the button tag does exist, it doesn’t do it.
<div class="container">
<button>1</button>
<div>2</div>
</div>
But if we add more than one button tag, it correct targets both:
<div class="container">
<button>1</button>
<button>2</button>
</div>
Multiple Boxes
So, what we want to do is to change the grid box sizes based on how many boxes there are in the grid. We come across this sometimes where a grid will have an odd number of columns and could leave a hanging box at the end. This looks kinda funky and we try to avoid it when we can, but we can use quantity queries to change the sizes of the boxes to fit whatever extra there is.
Let’s start with the basics, though, and go with how we can change the grid if there are a certain amount of elements.
Here’s the CSS and HTML I’m using:
.container{
display: flex;
flex-wrap: wrap;
}
.container div, .container button{
width: calc(25% - 20px);
background: gray;
margin: 10px;
padding: 20px;
font-size: 40px;
color: white;
display: flex;
justify-content: center;
align-items: center;
}
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
And now let’s do If there are 8 elements, target the first element.
.container div:nth-last-child(8):first-child{
background-color: green;
}
And if you want to target all the elements if there are 8, you would just add this line on to get this:
.container div:nth-last-child(8):first-child ~ div{
background-color: green;
}
Now, what if we don’t have that nice even number divisible by 4, which would give us some extra boxes at the bottom that don’t fit or leave open space (If there are 9 or more elements, target the 9th and above)? Let’s target those and change the size!
.container div:nth-child(n+9){
width: calc(33.33% - 20px);
background-color: green;
}
And now we have a grid that fits nicely for this example. Of course, this won’t work in all cases but it’s a good intro to how quantity queries can really help shape a layout with flexbox.