Menu Search
Jump to the content X X
Smashing Conf Barcelona 2016

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Constructing CSS Quantity Queries On The Fly

Often within a project, the presentation of our content changes based on certain needs. We see this when we use media queries to change our styles based on the user device. CSS quantity queries1 follow the same concept of changing the styles based on a condition: the condition within a quantity query being the number of sibling elements.

An example would be navigation where items are 25% wide when four items are available; yet when there are five items available, the width of the navigation items changes to 20%. This is a common problem with dynamic site frameworks like WordPress or Ghost. A client might not realize the complications that could arise, for example, by adding one more menu item when the CSS is not set up to fit it in. Now, you could easily solve this problem with Flexbox2 (and many other problems3), but what about a smart fallback for browsers not supporting Flexbox — preferably with CSS alone, without JavaScript altogether? Ideally, we could use @supports4 — but you can probably guess which browsers don’t support the property.

5
You must have run into this problem in the past: you have a dynamic number of siblings, and you need to style them differently, based on the total count of siblings. It can be solved, easily, with CSS quantity queries. Image source: Quantity Queries on ALA6.

Sometimes Flexbox won’t cut it though. What if you are designing a gallery with an uneven number of items and you’d like to highlight the image in the center without tracking with JavaScript how many items fit the screen? Or what about a table in which some columns might need different styling based on how many items can be displayed at a given resolution — e.g. in an airline flight selection, or cinema tickets reservation?

The same goes for pretty much every module that could suffer from some dynamic addition or subtraction of elements. Can you avoid too many media queries and JavaScript workarounds?

Yes, you can. This is where quantity queries are best used. By being creative with CSS selectors, we can count the number of sibling items and apply styles if they meet the conditions. Using these queries, we can future-proof our designs and projects, and allow them to scale gracefully.

An Example Of A Quantity Query Link

Using CSS selectors like nth-last-child(), last-child and ~, we can craft selectors that match our requirements. If you’re interested in reading more about how they work, Lea Verou, Heydon Pickering and myself have7 written8 articles9 on the subject.

Here’s an example of a quantity query that will apply styles if there are at least five sibling elements:

ul li:nth-last-child(n+5), ul li:nth-last-child(n+5) ~ li {
  // styles go here
}

We can take this further and change the query to select all sibling elements up to a certain amount:

ul li:nth-last-child(-n+5):first-child, ul li:nth-last-child(-n+5):first-child ~ li {
  // styles go here 
}

Extending further still, we can set boundaries and apply styles if the sibling items are within a certain range.

ul li:nth-last-child(n+5):nth-last-child(-n+10):first-child, ul li:nth-last-child(-n+5):nth-last-child(-n+10):first-child ~ li {
  // styles go here
}

A Solution To Writing Quantity Queries Link

As you can see, these queries can be a bit verbose and difficult to write. This is why I created QuantityQueries.com1210: a tool I needed to help construct and demonstrate quantity queries for my own projects.

QuantityQueries.com11
Building quantity queries at QuantityQueries.com1210 (View larger screenshot13)

Written as an experiment with React14, the project evolved into a dynamic tool for our web design community to use and understand how best to apply these quantity queries.

The app allows a query to be built through three questions: the elements to be counted, the type of query, and the amount of items to count. Based on the questions, a CSS selector is created that can be used within your project, as well as a small demo that will react to your query.

Within the demo, as items are added or removed, the colour of the items will change to pink to reflect the query being applied to the demo.

qq_demoImage-opt-small15
A demo in action. (View large version16)

“But I Have To Support Browser X…” Link

Quantity queries are constructed using modern CSS properties to perform the selection. They will work in all modern browsers (both desktop and mobile, including Opera Mini 8), back to IE9. Selectors such as nth-last-child(), ~ and last-child were introduced in CSS3, and first-child was introduced by CSS2.1. Obviously you can treat them as progressive enhancement, but if you absolutely have to support legacy browsers, you can use Selectivizr17 and Modernizr18.

Using It Today Link

Feel free to bookmark the site and keep it handy in your toolbelt. Each project has different requirements and will need to be tailored to client needs, but the tool might come in handy when you need a quite complex selector and don’t want to spend hours figuring out the math. You can also use Lea Verou’s CSS3 structural pseudo-class selector tester19, CSS Tricks’ :nth tester20 and nth-test21 for testing.

If you would like to help improve the tool or you discover any bugs, you can help improve22 the app, or report any issues23. I hope that the project will be helpful for your projects!

(og)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2015/07/quantity-ordering-with-css/
  2. 2 https://www.smashingmagazine.com/2015/03/harnessing-flexbox-for-todays-web-apps/
  3. 3 http://flexbox.io/
  4. 4 http://caniuse.com/#search=supports
  5. 5 http://alistapart.com/article/quantity-queries-for-css
  6. 6 http://alistapart.com/article/quantity-queries-for-css
  7. 7 http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/
  8. 8 http://alistapart.com/article/quantity-queries-for-css
  9. 9 https://www.smashingmagazine.com/2015/07/quantity-ordering-with-css/
  10. 10 http://quantityqueries.com
  11. 11 http://quantityqueries.com
  12. 12 http://quantityqueries.com
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2015/07/qq_largeImage-opt.jpg
  14. 14 https://facebook.github.io/react/
  15. 15 http://quantityqueries.com
  16. 16 https://www.smashingmagazine.com/wp-content/uploads/2015/07/qq_demoImage-opt.jpg
  17. 17 http://selectivizr.com/
  18. 18 http://modernizr.com/
  19. 19 http://lea.verou.me/demos/nth.html
  20. 20 https://css-tricks.com/examples/nth-child-tester/
  21. 21 http://nth-test.com/
  22. 22 https://github.com/drewminns/qqui
  23. 23 https://github.com/drewminns/qqui/issues
SmashingConf Barcelona 2016

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook

Advertisement

Drew Minns is a Developer, Designer and Educator from Toronto, Canada. Currently working as Lead Instructor and Developer for HackerYou, Drew stays on the edge of the industry to educate those around him.

  1. 1

    James Cazzetta

    July 29, 2015 4:09 pm

    Great article!
    It’s always nice to see “new” (in my case) CSS-only approaches which are actually so simple – especially in this case, I think every web designer has come across this problem.

    2
  2. 2

    Imran Bughio

    July 29, 2015 6:29 pm

    You should change your github account name, it confused me into thinking it’s my profile :)

    2
  3. 3

    Satyajit Sahoo

    July 29, 2015 6:46 pm

    I made a sass mixin so that it’s easier to use in code.

    https://gist.github.com/satya164/43950a19b23b6e2d7484

    Usage:

    @include quantity-query(“ul > li”, at-least, 5) { color: blue; };

    @include quantity-query(div, at-most, 3) { color: green; };

    @include quantity-query(section p, between, 3, 5) { color: red; };

    4
  4. 5

    PostCSS has a plugin for quantity queries:

    https://github.com/pascalduez/postcss-quantity-queries

    0
  5. 7

    The article is written in very friendly manner. By reading your content, a layman can also get some knowledge about css codes. You will love to write for evonence.com also.

    -13
  6. 8

    What a friendly words! Your css codes can increase the passion for coding. You will love to write for evonence.com also.

    -13
  7. 9

    This is a base setting in my framework, Shipwright.

    I call the class ‘listed’, and here it is:

    .listed { font-size: 0px; letter-spacing: 0px; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; clear: both; width: 100%; }
    .listed li { display: inline-block; font-size: 12px; letter-spacing: normal; width: 100% }
    .listed li:nth-last-child(n+2),
    .listed li:nth-last-child(n+2) ~ li { width: 50%; }
    .listed li:nth-last-child(n+3),
    .listed li:nth-last-child(n+3) ~ li { width: 33.33%; }
    .listed li:nth-last-child(n+4),
    .listed li:nth-last-child(n+4) ~ li { width: 25%; }
    .listed li:nth-last-child(n+5),
    .listed li:nth-last-child(n+5) ~ li { width: 20%; }
    .listed li:nth-last-child(n+6),
    .listed li:nth-last-child(n+6) ~ li { width: 16.666%; }
    .listed li:nth-last-child(n+7),
    .listed li:nth-last-child(n+7) ~ li { width: 14.285%; }
    .listed li:nth-last-child(n+8),
    .listed li:nth-last-child(n+8) ~ li { width: 12.5%; }
    .listed li:nth-last-child(n+9),
    .listed li:nth-last-child(n+9) ~ li { width: 11.1111111111%; }
    .listed li:nth-last-child(n+10),
    .listed li:nth-last-child(n+10) ~ li { width: 10%; }
    .listed li:nth-last-child(n+11),
    .listed li:nth-last-child(n+11) ~ li { width: 9.091%; }
    .listed li:nth-last-child(n+12),
    .listed li:nth-last-child(n+12) ~ li { width: 8.333333%; }

    2
  8. 10

    Party Pooper

    August 3, 2015 6:09 pm

    Does any one ask “why” anymore? Seems to me like this kind of presentation condition should live in a “view” or not at all.

    Before you say I need to get off my high horse. I once wrote an entire mock app with css conditionals http://codepen.io/meChrisReed/pen/oCByD

    Thought it was cool when I made it. Now I know better.

    0
  9. 11

    The things mentioned in the Article was nightmare at before to deal with but now seems its quit easy,

    Sincere Thanks to Drew Minns to Write this article.

    0
  10. 12

    Daniel Guilla

    August 10, 2015 7:25 pm

    Being able to see what the query is currently matching is very helpful, the build tool is a fantastic idea!

    In case you need a simple and clean way to include Quantity Queries in your Sass projects you can use this mixin library:

    https://github.com/danielguillan/quantity-queries

    0

↑ Back to top