
I have quite a good experience in layout - a few years.
During this time, there was a lot - both tabular layout, and custom frameworks, and IE6, and responsive design, whatever — I always tried to be near the bleeding edge, as they say.
More CSS frameworks (hello, bootstrap) and Emmet-I like preprocessors and I’ll tell you why. It may seem that my article is somewhat outdated and now everyone is using preprocessors as a matter of course, but alas, it is not. Recently, I met a man who said that he was faster to write CSS-code, rather than use preprocessors. We argued for a long time, in fact, well, for a very long time, in the end I decided to put my thoughts here, in one place.
Less or Sass?
Well, actually, this is everyone's business. I didn’t like Sass because of its slowness - Less was always performed faster, in the end, at one point I decided to switch to Less, but after a while it turned out that I lacked its power! Alas, I never found how to implement a banal mixin of
this level.
But Sass was not satisfied with the slowness, but it was at that moment when I wanted to return back to Sass, but I was tormented by doubts,
libsass was advised to
me , but since I use Grunt - it was enough for me to connect only
grunt-sass (and nothing else, for example, installing Ruby and gems). For me, the choice was clear and since then - only
libsass . The power of Sass itself and C speed - what else do you need?
I haven't tried Stylus yet, somehow later.
Why all the same preprocessors?
I will not say anything new, most likely, but I want to show why it is worth using preprocessors.
Variables
Variables are great. I was reproached for “the preprocessors were invented by a programmer, not a coder,” but how can one discard variables? A simple example that makes life much easier - since I also include a designer, all colors, font settings, etc. under the project it is enough for me to store in the
_variables.scss file
_variables.scss$white: rgb(255, 255, 255); $lightgray: rgb(238, 238, 238); $gray: rgb(153, 153, 153); $asphalt: rgb(85, 85, 85); $black: rgb(17, 17, 17); $blue: rgb(85, 164, 242); $lightblue: rgb(91, 192, 222); $green: rgb(46, 204, 113); $orange: rgb(230, 126, 34); $magenta: rgb(228, 183, 240); $red: rgb(231, 76, 60); $bgBrand: linear-gradient(to left, rgba(26,214,253,1) 0%, rgba(85,164,242,0.72) 100%) no-repeat center center fixed; $bgBlueLight: linear-gradient(rgb(26, 214, 253) 0%, rgb(29, 98, 240) 100%) no-repeat center center fixed; $bgPinkViolet: linear-gradient(#EF4DB6 0%, #C643FC 100%) no-repeat center center fixed; $bgWhiteGray: linear-gradient(#F7F7F7 0%, #D7D7D7 100%) no-repeat center center fixed;
Then, when I need it, I just specify the variable, not the full property.
background: $ bgBrand , and since I have backgrounds used in many places, it's easier for me to edit the variable property in one place, and not to do a file search or even a single file — it's still longer than editing it in one place.
')
Nesting
What could be better than nesting: hover,: after,: before,: nth-child in the parent element?
A simple, very simple example:
a { color: $blue; &:hover { color: darken($blue, 10%); } }
In it, I use variables, the inner
darken()
function, and that same nesting. It would seem a trifle, but the layout consists of such trifles. At times, it is more convenient to look at what belongs to a particular block, keeping track of what is inside it, and not what goes below. Yes, and write every time
.my-super-class:hover
is still meaningless. Proponents of the BEM approach would appreciate this opportunity, but they have their own tools there.
I needed to make a table with missing headings (I used Bootstrap).
Example .table-information { tr { th { height: 0; padding: 0; border: 0; } td { border-top: 0; border-bottom: 1px solid $lightgray; } &:last-child { td { border-bottom: 0; } } } }
Mixins, imports, etc.
The main advantage of preprocessors is in mixins, extensions, etc. These are like functions in a normal language — you can use an infinite number of times, connecting when necessary. Personally, I don't use myxines so often, but because I make up with the mobile first approach, one little mixin helps me a lot, which I have already mentioned:
@mixin responsive($media) { @if $media == sm { @media (min-width: 768px) { @content; } } @else if $media == md { @media (min-width: 992px) { @content; } } @else if $media == lg { @media (min-width: 1200px) { @content; } } @else if $media == xlg { @media (min-width: 1700px) { @content; } } }
It is used quite simply as @ media-queries:
@include responsive(sm) { background-color: red }
and this, together with the nesting of the elements.
Imports exist in CSS, but not in the way we would like. Because we are talking about preprocessors, in the end, all connected files are collected into one - and this is useful, because only one request is made to the server. In order to keep the project architecture in certain modules or just blocks, imports are quite useful.
“I can't figure out the generated code”
When I heard this argument, I did not quite understand what was being said. Then they explained to me (a person works on freelancing) - a project with Sass or Less comes to him, but the generated code is terrible, you cannot figure it out. And this is the wrong approach, because preprocessors are for people, so that it is convenient to develop, to keep the project architecture in a normal state. If a person writes normally, the output CSS is optimized, on this side there is no difference what was written on - CSS or Sass, Sass only helps the developer, not the browser. For browser support, there are
Source maps , which are supported in normal Grunt tools out of the box.
Example

Not so long ago I was developing one project in which I needed social networking buttons - not so many, 5 pieces, but it was then that I thought about creating a library using Sass, where a huge number of buttons would be stored. Of course, doing this on CSS would be inconvenient, which is why I decided to use Sass. The person with whom we argued, in the end, noted the elegance of the decision.
In order to make
Brand Buttons , it took me quite a bit:
As a result, there are 3 files in which I used a small, but powerful part of the Sass capabilities: variables, imports, mixins, internal functions like
each / @ for.
The final CSS is 687 lines.
In order to add a new button to this project, it is enough for
me to insert one line
brand: color into
_variables.scss and run
grunt build
, and not create new classes manually.
Preprocessors are the story of how little things like variables can greatly increase performance. The preprocessors, perhaps, are written by programmers, but at the same time they do not introduce anything difficult, they only improve life: the code remains readable, even more so - it becomes smaller, it becomes more slender. In this article I didn’t talk about many possibilities, but I had a desire to show why I use preprocessors and what advantages they give to those who do decide.