In the authoring style sheets, a key selector should only be written once.
This allows us to search for a key-selector in the code base and find a single source of truth for our selector. Thanks to the use of an extended CSS syntax, everything that happens to that key selector can be encapsulated in a single rule block.
Overrides to the key selector are handled by nesting and referencing the key selector with the parent selector. More of which shortly.
Consider this example:
.key-Selector { width: 100%; @media (min-width: $M) { width: 50%; } .an-Override_Selector & { color: $color-grey-33; } }
That would yield the following in the CSS:
.key-Selector { width: 100%; } @media (min-width: 768px) { .key-Selector { width: 50%; } } .an-Override_Selector .key-Selector { color: #333; }
In the authoring style sheets, the key selector (.key-Selector
) is never repeated at a root level. Therefore, from a maintenance point of view, we only have to search for .key-Selector
in the code base and we will find everything that could happen to that key selector described in a single location; a single source of truth.
In all these instances the eventualities for that key selector are nested within that single rule block. This means that any possible specificity issues are entirely isolated within a single set of curly braces.
Let's look at overrides in further detail next.
In the prior example, there was a demonstration of how to deal with an override to a key selector. We nest the overriding selector inside the rule block of the key selector and reference the parent with the &
symbol. The &
symbol, as in the Sass language, is a parent selector. It might help you to think of it as being roughly equivalent to this
in JavaScript.
To test rules using the parent selector I recommend http://sassmeister.com
Consider this example:
.ip-Carousel { font-size: $text13; /* The override is here for when this key-selector sits within a ip-HomeCallouts element */ .ip-HomeCallouts & { font-size: $text15; } }
This would yield the following CSS:
.ip-Carousel { font-size: 13px; } .ip-HomeCallouts .ip-Carousel { font-size: 15px; }
This results in a font-size
increase for the ip-Carousel
when it is inside an element with a class of ip-HomeCallouts
.
Let's consider another example, what if we need to provide an override when this element gets an additional class? We should do that like this:
.ip-Carousel { background-color: $color-green; &.ip-ClassificationHeader { background-color: $color-grey-a7; } }
That would yield this CSS:
.ip-Carousel { background-color: #14805e; } .ip-Carousel.ip-ClassificationHeader { background-color: #a7a7a7; }
Again, the override is contained within the rule block for the key selector.
Finally let's consider the eventuality where we need to provide an override for a key selector inside another element that also has an additional class present:
.ip-Carousel { background-color: $color-green; .home-Container &.ip-ClassificationHeader { background-color: $color-grey-a7; } }
That would yield the following CSS:
.ip-Carousel { background-color: #14805e; } .home-Container .ip-Carousel.ip-ClassificationHeader { background-color: #a7a7a7; }
We have used the parent selector here to reference our key selector between an override above (.home-Container
) and alongside another class (.ip-ClassificationHeader
).
Finally, let's consider overrides with media queries. Consider this example:
.key-Selector { width: 100%; @media (min-width: $M) { width: 50%; } }
That would yield this CSS:
.key-Selector { width: 100%; } @media (min-width: 768px) { .key-Selector { width: 50%; } }
Again, all eventualities contained within the same rule. Note the use of a variable for the media query width? We will come to that shortly.
Any and all media queries should be contained in the same manner. Here's a more complex example:
.key-Selector { width: 100%; @media (min-width: $M) and (max-width: $XM) and (orientation: portrait) { width: 50%; } @media (min-width: $L) { width: 75%; } }
That would yield this CSS:
.key-Selector { width: 100%; } @media (min-width: 768px) and (max-width: 950px) and (orientation: portrait) { .key-Selector { width: 50%; } } @media (min-width: 1200px) { .key-Selector { width: 75%; } }
With all the nesting of overrides we have just looked at, you may think it makes sense to nest child elements too? You are wrong. Very wrong. This would be a very, very bad thing to do. We'll look at why next.