- Sass and Media Queries
- Media queries
- selector. This dictates the size of the font until the screen width drops below a breakpoint of 900px, at which point the media queries kicks in and adjusts the font size to 24px. One media query tends to be set for each breakpoint and that one query contains all the CSS rules that need to be adjusted. This is all well and good and media queries established in this way have served me well. However, my media queries are often located quite a long way from the CSS rules they are adapting. Imagine that the h1 rule above is located near the top of the CSS document, say around line 15. If the document were several hundred lines long and the media query located at the bottom, perhaps around line 250, it would be tricky to navigate quickly between the two. I often find myself scrolling up and down, having looked at a rule in the media query, trying to find the original code further up the document.
- Sass and media queries
- An issue
- Mixins to the rescue!
- Multiple media queries
- Summary
- Директива @media
- CSS At-Rules
- SCSS Syntax
- Sass Syntax
- CSS Output
- SCSS Syntax
- Sass Syntax
- CSS Output
- @media @media permalink
- SCSS Syntax
- Sass Syntax
- CSS Output
- SCSS Syntax
- Sass Syntax
- CSS Output
- SCSS Syntax
- Sass Syntax
- CSS Output
- @supports @supports permalink
- SCSS Syntax
- Sass Syntax
- CSS Output
- @keyframes @keyframes permalink
- SCSS Syntax
- Sass Syntax
- CSS Output
Sass and Media Queries
Ensuring websites and applications are responsive so that they are usable and visually appealing across all devices is one of the cornerstones of modern web development. Writing media queries in CSS is the most commonly used technique for ensuring our products are responsive and using media queries in conjunction with Sass makes them all the easier to work with. In this article, I will give a brief overview of how media queries are used to ensure sites and applications are responsive and then how they can be used with the Sass preprocessing language. An example of these ideas in practice can be found here.
Media queries
A media queries can be applied in CSS to enable different values to be given to properties of selectors based upon the width of the viewport.
h1 font-size: 26px; > @media only screen and (max-width: 900px) h1 font-size: 24px; > >
The above example contains a CSS rule that sets a value of 26px for the
selector. This dictates the size of the font until the screen width drops below a breakpoint of 900px, at which point the media queries kicks in and adjusts the font size to 24px. One media query tends to be set for each breakpoint and that one query contains all the CSS rules that need to be adjusted. This is all well and good and media queries established in this way have served me well. However, my media queries are often located quite a long way from the CSS rules they are adapting. Imagine that the h1 rule above is located near the top of the CSS document, say around line 15. If the document were several hundred lines long and the media query located at the bottom, perhaps around line 250, it would be tricky to navigate quickly between the two. I often find myself scrolling up and down, having looked at a rule in the media query, trying to find the original code further up the document.
Sass and media queries
h1 font-size: 26px; @media (max-width: 900px) font-size: 24px; > >
This removes the need the name the CSS rule twice, making the code more succinct. It also ensures that all the code related to this particular rule is located in the same place. No more scrolling up and down, hunting for two (or three or four – if multiple media queries affect the h1 rule) associated blocks of code.
An issue
Writing media queries in this way presents a new problem – instead of having a media query defined in one place, there might be as many smaller media queries as there are rules within the CSS document. This would be a problem if in the future you needed to adjust the breakpoint value from, say, 900px to 950px. It would be necessary to scroll through the entire codebase, hunting down dozens of media queries.
Mixins to the rescue!
Luckily, mixins can solve this issue by allowing us to define the media query in one location and to then apply it around the codebase wherever it is needed.
@mixin respond-medium @media (max-width: 900px) @content > >
The content directive – @content – allows us to pass a block of code into the mixin. Once the mixin is set up, we can apply it:
h1 font-size: 26px; @include respond-medium font-size: 24px; > >
Multiple media queries
We can go one step further to establish one mixin that handles multiple media queries, allowing us to set different breakpoints easily.
@mixin respond($breakpoint) @if($breakpoint == medium) @media (max-width: 900px) @content > > @if($breakpoint == small) @media (max-width: 600px) @content > > >
Here we have established a variable called $breakpoint . Depending upon what is passed in for this variable (medium or small), the correct media query is set. With this done, we can easily apply multiple media queries:
h1 font-size: 26px; @include respond(medium) font-size: 24px; > @include respond(small) font-size: 20px; > >
This example would ensure that the h1 font-size, normally 26px, would be 24px in viewports less than 900px wide and 20px in viewports less than 600px wide.
Summary
Take a look at this example of media queries in Sass implemented in a real-world example. Thanks to Sass’s ability to nest items within a CSS rule, media queries can be more closely linked to the CSS rule, resulting in a codebase that is more user-friendly and understandable. This, coupled with the use of mixins (using @content and @if directives) has completely changed how I will be using media queries in the future.
Директива @media
Директива @media работает так же, как и стандартное правило CSS, только с дополнительными возможностями: директива может вкладываться в правила CSS. Если директива вложена в css-правило, то при компиляции она будет поднята наверх таблицы стилей, а все селекторы в которых была директива переместятся внутрь @media . Такой метод позволяет легко добавлять правила в @media без повторения селекторов или нарушения потока таблицы стилей. Например:
.sidebar width: 300px; @media screen and (orientation: landscape) width: 500px; > >
.sidebar width: 300px @media screen and (orientation: landscape) width: 500px
.sidebar width: 300px; > @media screen and (orientation: landscape) .sidebar width: 500px; > >
@media запросы могут вкладываться друг в друга. После компиляции эти @media будут объединены оператором and .
@media screen .sidebar @media (orientation: landscape) width: 500px; > > >
@media screen .sidebar @media (orientation: landscape) width: 500px
@media screen and (orientation: landscape) .sidebar width: 500px; > >
Ну и, наконец, @media запросы могут содержать в себе все возможности SassScript (включая переменные, функции и операторы) в именах компонентов и различных значений. Например:
$media: screen; $feature: -webkit-min-device-pixel-ratio; $value: 1.5; @media # and ($feature: $value) .sidebar width: 500px; > >
$media: screen $feature: -webkit-min-device-pixel-ratio $value: 1.5 @media # and ($feature: $value) .sidebar width: 500px
@media screen and (-webkit-min-device-pixel-ratio: 1.5) .sidebar width: 500px; > >
CSS At-Rules
LibSass, Ruby Sass, and older versions of Dart Sass don’t support interpolation in at-rule names. They do support interpolation in values.
Sass supports all the at-rules that are part of CSS proper. To stay flexible and forwards-compatible with future versions of CSS , Sass has general support that covers almost all at-rules by default. A CSS at-rule is written @ , @ < . >, or @ < . >. The name must be an identifier, and the value (if one exists) can be pretty much anything. Both the name and the value can contain interpolation.
SCSS Syntax
@namespace svg url(http://www.w3.org/2000/svg); @font-face font-family: "Open Sans"; src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"); > @counter-style thumbs system: cyclic; symbols: "\1F44D"; >
Sass Syntax
@namespace svg url(http://www.w3.org/2000/svg) @font-face font-family: "Open Sans" src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2") @counter-style thumbs system: cyclic symbols: "\1F44D"
CSS Output
@charset "UTF-8"; @namespace svg url(http://www.w3.org/2000/svg); @font-face font-family: "Open Sans"; src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"); > @counter-style thumbs system: cyclic; symbols: "👍"; >
If a CSS at-rule is nested within a style rule, the two automatically swap positions so that the at-rule is at the top level of the CSS output and the style rule is within it. This makes it easy to add conditional styling without having to rewrite the style rule’s selector.
SCSS Syntax
.print-only display: none; @media print display: block; > >
Sass Syntax
.print-only display: none @media print display: block
CSS Output
.print-only display: none; > @media print .print-only display: block; > >
@media @media permalink
LibSass and older versions of Dart Sass and Ruby Sass don’t support media queries with features written in a range context. They do support other standard media queries.
SCSS Syntax
@media (width 700px) body background: green; > >
Sass Syntax
@media (width = 700px) body background: green
CSS Output
@media (width ) body background: green; > >
The @media rule does all of the above and more. In addition to allowing interpolation, it allows SassScript expressions to be used directly in the feature queries.
SCSS Syntax
$layout-breakpoint-small: 960px; @media (min-width: $layout-breakpoint-small) .hide-extra-small display: none; > >
Sass Syntax
$layout-breakpoint-small: 960px @media (min-width: $layout-breakpoint-small) .hide-extra-small display: none
CSS Output
@media (min-width: 960px) .hide-extra-small display: none; > >
When possible, Sass will also merge media queries that are nested within one another to make it easier to support browsers that don’t yet natively support nested @media rules.
SCSS Syntax
@media (hover: hover) .button:hover border: 2px solid black; @media (color) border-color: #036; > > >
Sass Syntax
@media (hover: hover) .button:hover border: 2px solid black @media (color) border-color: #036
CSS Output
@media (hover: hover) .button:hover border: 2px solid black; > > @media (hover: hover) and (color) .button:hover border-color: #036; > >
@supports @supports permalink
The @supports rule also allows SassScript expressions to be used in the declaration queries.
SCSS Syntax
@mixin sticky-position position: fixed; @supports (position: sticky) position: sticky; > > .banner @include sticky-position; >
Sass Syntax
@mixin sticky-position position: fixed @supports (position: sticky) position: sticky .banner @include sticky-position
CSS Output
.banner position: fixed; > @supports (position: sticky) .banner position: sticky; > >
@keyframes @keyframes permalink
The @keyframes rule works just like a general at-rule, except that its child rules must be valid keyframe rules ( % , from , or to ) rather than normal selectors.
SCSS Syntax
@keyframes slide-in from margin-left: 100%; width: 300%; > 70% margin-left: 90%; width: 150%; > to margin-left: 0%; width: 100%; > >
Sass Syntax
@keyframes slide-in from margin-left: 100% width: 300% 70% margin-left: 90% width: 150% to margin-left: 0% width: 100%
CSS Output
@keyframes slide-in from margin-left: 100%; width: 300%; > 70% margin-left: 90%; width: 150%; > to margin-left: 0%; width: 100%; > >