css at-rules and logical operators in media-queries

2020-06-19

 | 

~4 min read

 | 

707 words

Yesterday, when I was writing about adding drop caps with css, I stumbled on two new features within CSS:

  1. The css at-rule @supports
  2. Conditional Media Queries

Now, if you’d asked me before I looked, I would have said the only time I’d ever seen the @ in CSS was for media-queries which leverage the @media rule. For example, this site uses an adaptive design to scale the width of the blog based on the device used.1

After looking at the full list, I realize I have seen @keyframes before, though I admit that I have not yet mastered the power embedded within (not like the keyframe.rs that’s for sure!). The full list, per MDN, iis:

  • @charset — Defines the character set used by the style sheet.
  • @import — Tells the CSS engine to include an external style sheet.
  • @namespace — Tells the CSS engine that all its content must be considered prefixed with an XML namespace.
  • Nested at-rules — A subset of nested statements, which can be used as a statement of a style sheet as well as inside of conditional group rules:

    • @media — A conditional group rule that will apply its content if the device meets the criteria of the condition defined using a media query.
    • @supports — A conditional group rule that will apply its content if the browser meets the criteria of the given condition. _ @document — A conditional group rule that will apply its content if the document in which the style sheet is applied meets the criteria of the given condition. (deferred to Level 4 of CSS Spec)* > _ @page — Describes the aspect of layout changes that will be applied when printing the document. _ @font-face — Describes the aspect of an external font to be downloaded. _ @keyframes — Describes the aspect of intermediate steps in a CSS animation sequence. _ @viewport — Describes the aspects of the viewport for small screen devices. _(currently at the Working Draft stage) > _ @counter-style — Defines specific counter styles that are not part of the predefined set of styles. _(at the Candidate Recommendation stage, but only implemented in Gecko as of writing)* > _ @font-feature-values (plus @swash, @ornaments, @annotation, @stylistic, @styleset and @character-variant) — Define common names in font-variant-alternates for feature activated differently in OpenType. _(at the Candidate Recommendation stage, but only implemented in Gecko as of writing)*

The second discovery is potentially more useful. It has to do with conditional at-rules (i.e. using logical operators).

Whereas it often makes sense to only apply CSS when a query is true, yesterday’s example with Drop Caps provides a perfect example of when that isn’t quite true.

Instead of “undoing” CSS in the future as Jason Pamental suggested in his post, which felt like a waste, I wondered if there wasn’t a way to only apply CSS in certain situations. 2 It turns out that’s exactly what the @selector is for!

Using styled-components, my final solution looked something like:

drop-caps.js
import styled, { css } from "styled-components"

const classicFirstLetterStyle = css`
  float: left;
  font-size: 3.5em;
  font-weight: bold;
  margin: 0 0.2em 0 0;
  line-height: 0.75;
`

const modernFirstLetterStyle = css`
  -webkit-initial-letter: 3 2;
  initial-letter: 3 2;
`

const Wrapper = styled.div`
  padding: 0 0.5em;

  & > p:first-of-type::first-letter {
    color: rgb(70, 70, 70);
    font-family: Georgia, serif;
    text-transform: lowercase;
    @supports not (initial-letter: 1 and -webkit-initial-letter: 1) {
      ${classicFirstLetterStyle}
    }

    @supports (initial-letter: 1) or (-webkit-initial-letter: 1) {
      ${modernFirstLetterStyle}
    }
  }
`

The highlighted lines are the interesting bit. The first is checking if both initial-letter:1 and -webkit-initial-letter:1 are not considered valid CSS by the browser. The latter is asking if either is valid.

For more on the logical operators and how they work, see MDN on using media queries.

Footnotes

  • 1 Wondering what the difference between Adaptive and Responsive web design is? This CSS-Tricks article does a pretty good job of detailing it!
  • 2 I’d like to emphasize just how much I learned from Jason. This particular decision was likely for the sake of simplicity, but it offered me an opportunity to learn something new so I took it!

Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!