Greetings
About a month ago I wrote an article in which I put forward the idea of optimizing the
@media screen
. The idea is to be able to write values for all screens in one line. For more information, please read
the link . Most of the comments - this is a criticism regarding the implementation, unfortunately no one threw ideas. But if you look at it from the other side, you can get an idea out of every criticism, so based on the opinions of the readers, I set myself the goal to write a mixin, which:
- easy to read (maximally repeating sass / scss / css syntax);
- easy to maintain (so that a year later you understand what is written there);
- flexible (support for the maximum number of
@media
descriptions);
Let's see what happened to me (
Github repository )!
Syntax')
.class{ @include media($properties, $orientation); }
Mixin
media supports two parameters $ properties and $ orientation.
$ properties - an array of css rules.
$ orientation - screen orientation (optional).
$ properties
.class{ @include media(( width: 100%; height: (lg: 800px, md: 600px, sm: 300px), transform: (all: translateX(100px) translateY(100px), sm: translateX(50px) translateY(50px)), color: (sm-md: $white, md-lg: $gray), font-size: (320: 12px, min-480: 18px, 480-md: 24px, print: 14pt) )); }
Let's take a look at the code in more detail ...
The
$ properties parameter is an array, so all properties are taken in ().
width: 100
The usual rule for all screens. compiled into
.class{ width: 100%; }
Interesting further:
height: (lg: 800px, md: 600px, sm: 300px)
Here we describe the height for screens with a maximum width of
lg ,
md and
sm (set by the developer, more on that later).
Compilation result:
@media only screen and (max-width: 1024px) { .class{ height: 800px; } } @media only screen and (max-width: 768px) { .class{ height: 600px; } } @media only screen and (max-width: 640px) { .class{ height: 300px; } }
Also pay attention to the code below:
transform: (all: translateX(100px) translateY(100px), sm: translateX(50px) translateY(50px))
In this example, there is an
all screen, I think you guessed that these are all screens. There is a fundamental difference between
all and the usual rule, like
width: 100% . But this is also a little later.
color: (sm-md: $white, md-lg: $gray)
Here I tried to maximally flex the screen ranges between
min-width
and
max-width
. Those. The code presented above will compile the minimum width of
sm (640) - the maximum width of
md (768), and for screens in this range will set the text color to white, or gray for
md (768) -
lg (1024).
Compiled version:
.class{ @media only screen and (min-width: 768px) and (max-width: 1024px) { color: gray; } } .class{ @media only screen and (min-width: 640px) and (max-width: 768px) { color: white; } }
There are also cases when we cannot rely only on given screens. Therefore, it is possible to set custom width dynamically. Also, if you suddenly need to specify the minimum width instead of the maximum width, or vice versa, this possibility is also present:
font-size: (880: 12px, min-480: 18px, 480-md: 24px, print: 14pt)
The first screen is
max-width: 880px . By default, the width is set to the maximum (just as easy to change). For this screen we get
font-size: 12px;
The second screen
min-480 indicates that we will make a start from the minimum screen width 480px (min- prefix), and as a result we get a
font-size: 18px
for all screens wider than 480px.
480-md - will create a custom minimum size of 480px and a maximum
md (768). Those. This is a variant of the range of screens, as in the previous example, only with an arbitrary value.
Please note that if we write 480-768 we get a -288px screen, i.e. the "-" sign will work as a minus. Therefore, it is worthwhile to take such an example in quotation marks “480-768”, unless of course you intend to write the operation with “-” (by the way, +, *, / will also work).
print: 14pt
print - is an immutable parameter and is intended for printing:
@media print { .class{ font-size: 14pt; } }
I hope everything is clear at this stage ... If not, I will be happy to explain in the comments.
Let's go to the $ orientation parameter
It's all much easier. There are two options for orientation of the screen
landscape and
portrait . Actually, if necessary, the second parameter is prescribed these values.
.class{ @include media(( width: 100%; height: (all: 100%, md: 50%) ), portrait); }
As a result, we get:
.class{ width: 100%; } @media only screen and (orientation:portrait){ .class{ height: 100%; } } @media only screen and (max-width: 768px) and (orientation:portrait){ .class{ height: 50%; } }
In this example, you can clearly see the difference between
all and the standard rule. In the case of
width: 100%, the rule under all circumstances falls under all screens. In the case of
all - all screens with
portrait /
landscape orientation.
Settings
Two standard variables that need to be edited are
$ breakpoints and
$ media-direction . Here is how they look by default:
$breakpoints: ( lg: 1024, md: 768, sm: 640 ) !default; //- $media-direction: max !default; - (max/min)
Those. In order to create for yourself the necessary number of screens with the necessary names, dimensions and initial direction (
min /
max ), you need to create new variables in a place convenient for you:
$breakpoints: ( desktop: 1280, ipad: 1024, tablet: 768, mobile: 640 ); $media-direction: min;
This is enough to get started.
How else can you use this mixin?If the
$ properties parameter is put into a variable, then you can get a great function. For example:
$title-style: ( line-height: (lg: 24px, md: 20px, sm: 16px), font-size: (lg: 20px, md: 16px, sm: 12px;), text-align: (all: left, sm: center) ... ) .block{ h2{ color: gray; @include media($title-style); } h3{ color: black; @include media($title-style, landscape); } }
We get a kind of
extend class. Agree, it can be very convenient.
Let's sum up
pros
- easy to read - the code repeats the syntax of CSS;
- easily supported - the screens are well-defined, and there will be no problem in understanding the code;
- flexible - we were able to describe
@media screen
for all screens, screen ranges, minimum / maximum width dynamically, at any time there is an opportunity to set custom widths, as well as adjust the rules for printing without departing from the code.
Minuses
- There is no description of the screen height. I haven’t gotten to this part yet, and if this mixin is interesting to you, I will definitely add this possibility. So do not forget to write comments so that I can understand how relevant and useful it is to you.
- There is no possibility to prescribe
@include mixin
for different screens. At the moment, this possibility is impossible in principle in the above mixin using Sass. As far as critical, I will leave you to think, decide for yourself whether to sacrifice such a function or not. For me personally, this is not critical at all, since I cannot remember that I ever ever @include mixin
inside the @media screen
.
Conclusion
I think the goal is achieved. Mixin turned out quite convenient and concise.
If you
do not agree with me, write comments. In any case, I’m happy to hear your advice on how to improve this mixin, or try to extract something useful from your criticism.
PS You can download mixin in the Github repository using the
link .
_mixin.scss is the file you need. The same
package.json file contains plugins for Gulp, which would be nice to connect:
- gulp-autoprefixer will add browser prefixes where necessary;
- gulp-group-css-media-queries perfectly group the
@media screen
; - gulp-minify-css optimizes css, we can say that this plugin is necessary.
I am sure that for the webpack or for any other collector, you can easily find analogues.
Thanks for attention!