Good day, colleagues!
It has long been wondered how to optimize and make more convenient code using the
@media screen
. For code
body{font-size: 1em;} @media screen and (max-width: 1024px){ body{font-size: 0.8em;} }
creates quite large files.
Of course, you can write a mixin like respond-to (tablet), many use it and it looks nicer and more convenient than the above described option, but it does not solve the main problem. In large projects, we get a lot of
@include
and it's not that difficult to figure out, but we have to do a lot of carouseling around the file, looking for the right class or attachment.
')
And how can we get a readable one, well, or at least a file in two or even three times less? I asked myself this question and came to the answer:
“Make it possible to register all permissions in one line, i.e. don't duplicate values. "
The result should be something like
body{font-size: [1em, 0.8em]}
where the first value [1em] is for all screens, and the second one [0.8em] for screens less than 1024px. Agree, this option greatly simplifies life and reduces the file at times, it is easy to describe the rule for all permissions.
The answer to the first question is found. But another question, how to achieve this? The first thought was to write a module for Gulp, which would transfer the values ​​from [] to the
@media screen
... But this option is not very good, because firstly, it is a rather complicated process. It is necessary to think a lot, to be able to do non-conflicting modules, in general, in my case this is problematic. Secondly, no idea will accept such a syntax, and such antics will be underlined in red, which is not good either.
So I decided that
@mixin
in Sass is a suitable option, although not as elegant and readable as using []. And so, here's what I got:
$screens: (all, 1024, 640); @mixin media($property, $values){ @for $i from 1 through length($values) { @if nth($values, $i) != ''{ @if nth($screens, $i) == 'all'{ #{$property}: unquote(#{nth($values, $i)}); } @else { @media screen and (max-width: nth($screens, $i) + 'px') { #{$property}: unquote(#{nth($values, $i)}); } } } } }
Now you can call mixin like this:
body{ @include media(font-size, (1em, 0.8em)); }
CSS:
body{font-size: 1em;} @media screen only (max-width: 1024px){ body{font-size: 0.8em;} }
It seems to be how they got the desired result, but it only seems so, it hasn't done without additional modules for Gulp. When I described a few rules
body{ @include media(font-size, (1em, 0.8em, 0.6em)); @include media(color, (black, green, red)); } .class{ @include media(display, (none, block, none)); }
I ended up with not the best CSS:
body{font-size: 1em;} @media screen only (max-width: 1024px){ body{font-size: 0.8em;} } @media screen only (max-width: 640px){ body{font-size: 0.6em;} } body{color: black;} @media screen only (max-width: 1024px){ body{color: green;} } @media screen only (max-width: 640px){ body{color: red;} } .class{display:none;} @media screen only (max-width: 1024px){ .class{display:block;} } @media screen only (max-width: 640px){ .class{display:none;} }
You need to get rid of the duplication of
@media screen only (max-width: 1024px)
. For this, I installed a module for Gulp -
gulp-group-css-media-queries , a description of the installation
hereResult:
body{font-size: 1em;} body{color: black;} .class{display: none;} @media screen only (max-width: 640px){ body{font-size: 0.6em;} body{color: red;} .class{display: none;} } @media screen only (max-width: 1024px){ body{font-size: 0.8em;} body{color: green;} .class{display: block;} }
So much better, but still not good, since each value is described again with a new body element. The
gulp-minify-css module, the description
here , helped me in solving this problem.
And voila:
body{ font-size: 1em; color: black; } .class{display: none;} @media screen only (max-width: 640px){ body{ font-size: 0.6em; color: red; } .class{display: none;} } @media screen only (max-width: 1024px){ body{ font-size: 0.8em; color: green; } .class{display: block;} }
We get the perfect css using a minimum of lines in Sass. I use Gulp + Sass, but for fans of Less + Webpack or Sass + Compass, or in any other bundle, I think there will be no problem rewriting the mixin and finding the necessary modules.
I myself immediately tested my version on a not-so-large project, but I still had to edit quite a lot, and as a result I was pleased with the process. The only thing that is not very convenient, when using a large number of permissions, this kind of code appears:
.class{ @include media(color, (red, '', '', '', green, black)); @include media(width, (50%, '', '', '', '', 100%)); }
In this case, at first you get lost a little and it is not always clear for which screen you are correcting, but this was not a problem or inconvenience for me (opened, checked, changed). If you have 2-3 resolutions, everything will look readable and succinct, though not familiar at first.
Conclusion
With this mixin, I achieved the desired result, all the screen options are in one line. Of course, the code is damp, and perhaps something similar has already been written by someone much better than I did, but I did not find it, maybe I looked badly. In any case, I will be glad to hear your opinion on this method. Maybe someone knows something better, or knows how to embellish this method, write. Maybe I wrote a complete heresy, and you will never use this method because ... In this case, please justify why it is important for me to understand how useful / useful this method can be.
PS
For those who decided to try it out, I want to clarify that if you use abbreviated properties of the type
rgin: 0 auto;
, then “0 auto” must be quoted, otherwise you will get a
margin: 0;
Thank you all for your attention, and in advance for your comments!