CSS Preprocessor: Review, Selection, Application

Absolutely all experienced layout designers use preprocessors. There are no exceptions. If you want to succeed in this activity, do not forget about these programs. At first glance, they can cause quiet horror in a beginner - this is too similar to programming! In fact, you can understand all the capabilities of CSS preprocessors in about a day, and if you try, then in a couple of hours. They will make your life much easier in the future.

How CSS preprocessors came to be

To better understand the features of this technology, let’s briefly dive into the history of the development of visual presentation of web pages.

When mass use of the Internet first began, no style sheets existed. The execution of documents depended solely on browsers. Each of them had their own styles that were used to handle certain tags. Accordingly, the pages looked different depending on which browser you opened them in. The result is chaos, confusion, and problems for developers.

In 1994, Norwegian scientist Haakon Lie developed a style sheet that could be used to design appearance pages separate from the HTML document. The idea attracted the attention of representatives of the W3C consortium, who immediately began to refine it. A few years later, the first version of the CSS specification was released. Then it was constantly improved and refined... But the concept remained the same: each style is given certain properties.

Usage CSS tables always caused some problems. For example, layout designers often had difficulties with sorting and grouping properties, and with inheritance, not everything is so simple.

And then came the two thousandths. Professional front-end developers increasingly began to engage in markup, for whom flexibility and dynamic work with styles. The CSS that existed at that time required prefixing and tracking support for new browser features. Then JavaScript and Ruby experts got down to business, creating preprocessors - add-ons for CSS that add new features to it.

CSS for Beginners: Features of Preprocessors

They perform several functions:

  • unify browser prefixes and hacks;
  • simplify the syntax;
  • make it possible to work with nested selectors without errors;
  • improve styling logic.

In short: the preprocessor adds programming logic to the CSS capabilities. Now styling is performed not by the usual enumeration of styles, but by using several simple techniques and approaches: variables, functions, mixins, loops, conditions. In addition, it became possible to use mathematics.

Seeing the popularity of such add-ons, the W3C began gradually adding features from them into the CSS code. For example, this is how it appeared in the specification calc function(), which is supported by many browsers. It is expected that soon it will be possible to set variables and create mixins. However, this will happen in the distant future, and preprocessors are already here and already working perfectly.

Popular CSS preprocessors. Sass

Developed in 2007. Initially it was a component of Haml, an HTML template engine. New management options CSS elements Ruby on Rails developers liked it and began to distribute it everywhere. Appeared in Sass great amount features that are now included in any preprocessor: variables, nesting of selectors, mixins (at that time, however, it was impossible to add arguments to them).

Declaring Variables in Sass

Variables are declared using the $ sign. You can store properties and their sets in them, for example: “$borderSolid: 1px solid red;”. In this example, we declared a variable called borderSolid and stored the value 1px solid red in it. Now, if in CSS we need to create a red border 1px wide, we simply specify this variable after the property name. Once declared, variables cannot be changed. Several built-in functions are available. For example, let's declare a $redColor variable with the value #FF5050. Now in the CSS code, in the properties of some element, we use it to set the font color: p ( color: $redColor; ). Want to experiment with color? Use the darken or lighten functions. This is done like this: p ( color: darken($redColor, 20%); ). This will make redColor 20% lighter.

Nesting

Previously, it was necessary to use long and awkward constructs to indicate nesting. Let's imagine that we have a div containing p, and it, in turn, contains a span. For div we need to set the font color to red, for p - yellow, for span - pink. In regular CSS this would be done like this:

By using CSS preprocessor everything is made simpler and more compact:

Elements are literally “nested” one into another.

Preprocessor Directives

You can import files using the @import directive. For example, we have a file fonts.sass, which declares styles for fonts. We include it in the main style.sass file: @import ‘fonts’. Ready! Instead of one large file with styles we have several that can be used to quickly and easy access to the required properties.

Hagfishes

One of the most interesting ideas. Makes it possible to set a whole set of properties in one line. They work as follows:

@mixin largeFont (

font-family: 'Times New Roman';

font-size: 64px;

line-height: 80px;

font-weight:bold;

To apply a mixin to an element on the page, use the @include directive. For example, we want to apply it to the h1 header. The result is the following construction: h1 ( @include: largeFont; )

All properties from the mixin will be assigned to the h1 element.

Preprocessor Less

Sass syntax is reminiscent of programming. If you're looking for an option that's more suitable for beginner CSS learners, check out Less. It was created in 2009. main feature- native support so that it will be easier for layout designers unfamiliar with programming to master it.

Variables are declared using the @ symbol. For example: @fontSize: 14px;. Nesting works on the same principles as in Sass. Mixins are declared as follows: .largeFont() ( font-family: 'Times New Roman'; font-size: 64px; line-height: 80px; font-weight: bold; ). To connect, you don't need to use preprocessor directives - just add a freshly created mixin to the properties of the selected element. For example: h1 ( .largeFont; ).

Stylus

Another preprocessor. Created in 2011 by the same author who gave the world Jade, Express and other useful products.

Variables can be declared in two ways - explicitly or implicitly. For example: font = 'Times New Roman'; - this is an implicit option. But $font = ‘Times New Roman’ is explicit. Mixins are declared and included implicitly. The syntax is: redColor() color red. Now we can add it to the element, for example: h1 redColor();.

At first glance, Stylus may seem confusing. Where are the “native” parentheses and semicolons? But once you dive into it, everything becomes much clearer. However, keep in mind that long-term development with this preprocessor may unlearn you from using classic CSS syntax. This sometimes causes problems when you need to work with “pure” styles.

Which preprocessor should I choose?

It really... doesn't matter. All options provide approximately the same capabilities, just the syntax is different for each. We recommend doing the following:

  • if you are a programmer and want to work with styles as code, use Sass;
  • if you are a layout designer and want to work with styles as with regular layout, pay attention to Less;
  • if you like minimalism, use Stylus.

For all options, a huge number of interesting libraries are available that can further simplify development. Sass users are advised to check out Compass, a powerful tool with a lot of built-in capabilities. For example, after installing it, you will never have to worry about vendor prefixes. Makes working with meshes easier. There are utilities for working with colors and sprites. A number of already announced mixins are available. Dedicate a couple of days to this product - thereby you will save a lot of effort and time in the future.

If we consider preprocessors together with CSS, we get a clearer picture than considering the concept of a preprocessor separately.

Definition

CSS preprocessor(from the English CSS preprocessor) is a CSS add-on that adds previously unavailable capabilities to CSS using new syntactic constructs.

The main task of the preprocessor is to provide convenient syntactic structures for the developer to simplify, and thereby speed up the development and support of styles in projects.

CSS preprocessors convert code written using a preprocessor language into clean and valid CSS code.

With preprocessors, you can write code that targets:

  • Human readability
  • Structured and logical
  • Performance

And this is only a small part of what the preprocessor can give you. But don't get ahead of yourself.

Syntactic sugar

Before we look further at CSS preprocessors, let's update our vocabulary with a new concept: syntactic sugar.

Syntactic sugar(from the English syntactic sugar) are additions to the syntax of a programming language that do not introduce any significant changes or new features, but make the language more readable for humans.

Syntactic sugar introduces into the language alternative options records of constructions embedded in this language. By alternative recording options we mean shorter or more convenient constructions for humans, which will ultimately be converted by the preprocessor into the source language, without syntactic sugar.

If we try to apply this concept to CSS preprocessors, then it general case, fully describes their essence. Let me remind you once again that the main task of preprocessors is to simplify and speed up development, but how else can this be done if you do not introduce alternative recording options?

What types of CSS preprocessors are there?

It's time to move on to more specific examples, namely to the CSS preprocessors themselves. At the time of writing, there are three popular preprocessors:

  • Sass (SCSS)
  • Stylus

And a few minor players for us:

  • Closure Stylesheets
  • CSS Crush

We will talk about the first three separately a little lower, but we won’t talk about the last two at all, due to their unpopularity. If desired, descriptions of these preprocessors can be easily found in a search engine.

What's the point of using preprocessors?

As I noted above, the main advantages are code readability, structuring and increased productivity.

There are also other reasons to start using a preprocessor today. I want to draw attention to this, since developers in the past, and many even now, refuse to use preprocessors, finding them complex, incomprehensible and unnecessary.

CSS is hard

Standard CSS is difficult. The non-nesting syntax that CSS preprocessors offer is simply hard to read. In addition, you need to remember the parent name when nesting. The lack of normal variables and "functions" makes CSS code messy and narrow-minded.

Available documentation

Gone are the days when documentation from preprocessors was available only to people “in the know.” Now anyone can as soon as possible master any of the preprocessors, and with minimal costs strength

Ease of use

Using preprocessors is easier than before, and much easier. To do this, you just need to install a program that will monitor the files intended for the preprocessor, and when they change, will compile the contents of these files into pure CSS code.

For more advanced users there are special project builders. Don't think that just because you're using a preprocessor program rather than a project builder that you're not cool enough. In fact, such faucets offer full control and advanced settings, but do not make you a Jedi.

Code structure and consistency

The most popular feature offered by any CSS preprocessor is the ability to nest selectors within each other. I won’t give an example now, since a corresponding part of the book will be written about Less’s capabilities, including nesting. At this point, all you should know is that when using preprocessors, you can nest one selector inside another, and another inside another, resulting in something similar to the table of contents of a book:

1. Parent selector 1.1. Nested selector 1.2. Nested selector 1.2.1. Nested selector 1.3. Nested selector

Of course, in real life selectors cannot begin with numbers, however, to draw a parallel between nesting and table of contents, I think such an omission is appropriate here.

Impurities

To put it very briefly, using impurities(from the English Mixins), you can make the code reusable. This helps to avoid helper classes in the markup or duplication of properties from selector to selector.

Modularity

Another bonus that would persuade me to start using a CSS preprocessor right now would be the ability to nest files within files, that is, in other words, to concatenate files in a given sequence. Yes, this can be arranged on pure CSS, but coupled with other features it turns out to be a very powerful tool.

At the same time, we get the opportunity to share modules (mixin libraries) that we created for our needs and found useful for other people. It turns out that any developer can download your library and use it for their own purposes, calling the mixins you wrote as needed.

Why not wait for CSS to evolve?

The development of CSS is taking very small and uncertain steps, as the W3C prioritizes the speed of CSS response (performance). On the one hand, this is correct and very important, but on the other hand, it is a lack of convenience for developers.

As an example, I’ll use one of the CSS4 specifications, which was introduced under pressure from developers - the parent selector. Such a long path from the idea to the decision was due to the fact that the W3C considered such a selector to be slow and its further use on sites would lead to wild slowdowns. Of course, we are talking about the widespread use of this selector, and not about isolated cases.

So don’t expect revolutions and changes in the near future that could overshadow the functionality and capabilities of CSS preprocessors.

Types of preprocessors

Of course, as in any other area, there is always competition, and in the preprocessor market there are now three main, warring camps:

  • Sass (SCSS)
  • Stylus

I call them hostile, because each adherent of one of the preprocessors considers it his duty to throw impurities at representatives of other, let’s say, faiths. This hostility is especially common among fans of the Sass preprocessor, which is considered the oldest and most powerful of all three preprocessors.

For the sake of completeness, I want to give a brief overview of each preprocessor:

Less

Actually, the hero of this book. The most popular preprocessor at the time of writing. Founded in 2009 by Alexis Sellier and written in JavaScript (originally written in Ruby, but Alexis made the right move at the right time). Has everything basic capabilities preprocessors and even more, but does not have conditional structures and loops in the usual sense for us. The main advantage is its simplicity, almost standard syntax for CSS and the ability to expand functionality through a system of plugins.

Sass (SCSS)

The most powerful of the CSS preprocessors. Has a fairly large developer community. Founded in 2007 as a module for HAML and written in Ruby (there is a port to C++). It has a much larger range of capabilities compared to Less. The capabilities of the preprocessor itself are expanded by the multifunctional Compass library, which allows you to go beyond CSS framework and work, for example, with sprites in automatic mode.

Has two syntaxes:

  • Sass (Syntactically Awesome Style Sheets) is a simplified CSS syntax that is identity-based. Considered obsolete.
  • SCSS (Sassy CSS) - based on standard CSS syntax.

Stylus

The youngest, but at the same time the most promising CSS preprocessor. Founded in 2010 by a well-known personality in our circles, TJ Holowaychuk. They say this is the most convenient and extensible preprocessor, and it is also more flexible than Sass. Written in JavaScript. Supports a lot of syntax options from CSS-like to simplified (missing: , ; , () and some parentheses).

CSS is an intentionally simple language. With the proliferation of complex web applications, the emergence of front-end developer positions, and the growing number of newfangled requirements, this simplicity is quickly evaporating. For the uninitiated, CSS preprocessors (particularly Sass, LESS, and Stylus) expand your styling capabilities with additional functionality like variables, nesting, and mixins—giving you much more control over big amount styles.

There is a shortage of articles promoting the use of preprocessors and providing quick guide according to them, not in recent years, and many points have already been described quite well. So let's focus on what is often overlooked and see what can be done against terminal solutions.

Introduction (optional)

As noted in the introduction, things like Sass, LESS, and Stylus provide us with additional functionality on top of CSS, but files written in these languages ​​must be compiled into CSS before the browser can try to parse anything in them. In general, the compilation process is automated in such a way as to minimize any impact on workflow.

Using any of the listed preprocessors, you can benefit from the following:

Expressiveness: Each of the preprocessors contains a set of time-saving conventions, the essence of which lies in the optionality or refusal of various punctuation rules. Depending on your preferences, styles can be freed from parentheses, semicolons, and/or regular commas. Plus, they all support nesting of selectors.

Advanced functionality: These languages, to varying degrees, offer additional possibilities for shaping our styles; This includes mixins (pieces of reusable code that can take optional arguments), extensions (class inheritance), and variable support.

Add-ons: To expand the standard arsenal, various add-ons are widely used. Sass has Compass, Stylus has Nib, and while it's a different story, Bootstrap, which needs no introduction, is built with LESS.

Real benefits

In fact, the main benefit of preprocessors lies in less effort - not physical (press keys less often), but mental. Preprocessors give you effective opportunity remove some of the tedious load on the mind and switch less between various applications, which is typical for front-end development. Do you have a frequently used color meaning? Store it in a variable instead of hunting for it around the project or storing it in your memory. Need a predictable and simple color change? SASS has a set of color operations that do nothing but eliminate the need to reach for the nearest color picker.

By implementing a preprocessor, you have the opportunity to concentrate directly on writing styles. Arithmetic responsive design works directly inside the style file, without switching to the calculator. Compass can take care of sprites for you. Separating styles into modular files and then combining them without impacting performance is seamless.

The main idea is that: these languages ​​allow you focus on problem solving, instead of being distracted by tools and context switching.

Painless compilation

The main barrier to starting using CSS preprocessors is usually not a lack of understanding of whether it is good or evil - people are scared by the offer to install a package using command line or perspective customization watch expressions. Fortunately, all these problems can be circumvented if suddenly the terminal is not your strong point.

Right in the browser

Not quite sure? Take a look at these browser implementations of preprocessors.

Harnessing the true power of the CSS preprocessor is an adventure. There are countless languages, syntaxes and functions, all ready to use right now.

In this article we will look at various possibilities and the benefits of using three different preprocessors: Sass, LESS and Stylus.

Introduction

Preprocessors create CSS that works in all browsers.

CSS3 preprocessors are languages ​​written for the sole purpose of adding cool, inventive features to CSS without breaking browser compatibility. They do this by compiling the code we write into plain CSS that can be used in any browser back to the stone age. There are thousands of features that preprocessors bring to the table, and in this article we'll look at some of the published ones and some of the un-published ones. Let's start.

Syntax

Most important part Writing code in a CSS preprocessor is about understanding the syntax. Luckily for us, the syntax is (or can be) identical to regular CSS for all three preprocessors.

SASS&LESS

Sass and LESS use standard CSS syntax. This makes conversion easier existing file CSS into the preprocessor. Sass uses the .scss extension and LESS uses the .less extension. Base file Sass or LESS can be configured like this:

/* style.scss or style.less */
h1 (
color: #0982C1;
}

As you may have noticed, this is just plain CSS that compiles fine in both Sass and LESS.

It's important to note that Sass also has an older syntax that skips semicolons and curly braces. Although this is still around, it is deprecated and we won't use it in this example. The syntax uses the .sass extension and looks like this:

/* style.sass */
h1
color: #0982c1

Stylus

The syntax for Stylus is much more verbose. By using the .styl file extension, Stylus accepts standard CSS syntax, but also accepts some other variations in which parentheses, colons, and semicolons are optional. For example:

/* style.styl */
h1 (
color: #0982C1;
}
/* omit brackets */
h1
color: #0982C1;
/* omit colons and semi-colons */
h1
color #0982C1

Using different variations within the same stylesheet is also acceptable, so the following will compile without errors.

H1 (
color #0982c1
}
h2
font-size: 1.2em

Variables

Variables can be declared and used throughout the style sheet. They can have any meaning, which is CSS value(such as colors, numbers [units included], or text.) and they can be referenced everywhere in our style sheet.

Sass

Sass variables are added with a $ character, and the value and name are separated by a semicolon, just like CSS property.

$mainColor: #0982c1;
$siteWidth: 1024px;
$borderStyle: dotted;
body (
color: $mainColor;
border: 1px $borderStyle $mainColor;
max-width: $siteWidth;
}

LESS

LESS variables are exactly the same as Sass variables, except variable names are appended with the @ symbol.

@mainColor: #0982c1;
@siteWidth: 1024px;
@borderStyle: dotted;
body (
color: @mainColor;
border: 1px @borderStyle @mainColor;
max-width: @siteWidth;
}

Stylus

Stylus variables do not require appending for them, although it does allow the use of the $ symbol. As always, the ending semicolon is not required, but there is an equals sign between the value and the variable. It should be noted that Stylus (0.22.4) compiles if we add an @ symbol to the variable name, but do not apply the value when referencing. In other words, don't do it.

MainColor = #0982c1
siteWidth = 1024px
$borderStyle = dotted
body
color mainColor
border 1px $borderStyle mainColor
max-width siteWidth

Compiled CSS

Each of the above files will be compiled with the same CSS. You can use your imagination to see how useful variables are. No longer will we need to change one color and repeat it twenty times, or want to change the width of our site and have to search around to find it. Here is the CSS after compilation:

Body (
color: #0982c1;
border: 1px dotted #0982c1;
max-width: 1024px;
}

The attachment

If we need to reference multiple elements with the same parent in our CSS, it can be tedious to keep writing the parent over and over again.

Section (
margin: 10px;
}
section nav (
height: 25px;
}
section nav a (
color: #0982C1;
}
section nav a:hover (
text-decoration: underline;
}

Instead, using a preprocessor, we can write the child selectors inside the parent's parentheses. Additionally, & denotes the parent selector.

Sass, LESS and Stylus

All three preprocessors have the same syntax for nesting selectors.

Section (
margin: 10px;
nav(
height: 25px;
a (
color: #0982C1;
&:hover (
text-decoration: underline;
}
}
}
}

Compiled CSS

This is the compiled CSS from the code above. It's exactly the same as when we started - how convenient!

Section (
margin: 10px;
}
section nav (
height: 25px;
}
section nav a (
color: #0982C1;
}
section nav a:hover (
text-decoration: underline;
}

Mixins

Mixins are functions that allow us to reuse properties in our stylesheet. Instead of going through our entire stylesheet and changing the property multiple times, we can now simply change it inside our mixin. This can be really useful for specific element style and vendor prefixes. When mixins are called from a CSS selector, the mixin's arguments are recognized and the styles within the mixin are applied to the selector.

Sass

/* Sass mixin error with (optional) argument $borderWidth which defaults to 2px if not specified */
@mixin error($borderWidth: 2px) (
border: $borderWidth solid #F00;
color: #F00;
}
.generic-error(
padding: 20px;
margin: 4px;
@include error(); /* Applies styles from mixin error */
}
.login-error(
left: 12px;
position: absolute;
top: 20px;
@include error(5px); /* Applies styles from mixin error with argument $borderWidth equal to 5px*/
}

LESS

/* LESS mixin error with (optional) argument @borderWidth which defaults to 2px if not specified */
.error(@borderWidth: 2px) (
border: @borderWidth solid #F00;
color: #F00;
}
.generic-error(
padding: 20px;
margin: 4px;
.error(); /* Applies styles from mixin error */
}
.login-error(
left: 12px;
position: absolute;
top: 20px;
.error(5px); /* Applies styles from mixin error with argument @borderWidth equal to 5px */
}

stylus

/* Stylus mixin error with (optional) argument borderWidth which defaults to 2px if not specified */
error(borderWidth= 2px) (
border: borderWidth solid #F00;
color: #F00;
}
.generic-error(
padding: 20px;
margin: 4px;
error(); /* Applies styles from mixin error */
}
.login-error(
left: 12px;
position: absolute;
top: 20px;
error(5px); /* Applies styles from mixin error with argument borderWidth equal to 5px */
}

Compiled CSS

All preprocessors compose the same code:

Generic-error (
padding: 20px;
margin: 4px;
border: 2px solid #f00;
color: #f00;
}
.login-error(
left: 12px;
position: absolute;
top: 20px;
border: 5px solid #f00;
color: #f00;
}

Inheritance

When writing CSS the old-fashioned way, we could use the following code to apply the same styles to multiple elements at the same time:

P,
ul,
ol (
/* styles here */
}

This works great, but if we need to further style elements individually, a different selector must be created for each one, and it can quickly become more messy and difficult to maintain. To counter this, you can use inheritance. Inheritance is the ability of others CSS selectors inherit the properties of another selector.

Sass&Stylus

.block(
margin: 10px 5px;
padding: 2px;
}
p(
@extend
border: 1px solid #EEE;
}
ul, ol (
color: #333;
text-transform: uppercase;
}

Compiled CSS (Sass &Stylus)

.block, p, ul, ol (
margin: 10px 5px;
padding: 2px;
}
p(
border: 1px solid #EEE;
}
ul, ol (
color: #333;
text-transform: uppercase;
}

LESS

LESS doesn't really support style inheritance like Sass and Stylus. Instead of adding multiple selectors to a single set of properties, it treats inheritance as a no-argument mixin and imports styles into its own selectors. The downside to this is that the properties are repeated in your compiled stylesheet. Here's how you set it up:

Block (
margin: 10px 5px;
padding: 2px;
}
p(
.block; /* Inherit styles from ".block" */
border: 1px solid #EEE;
}
ul, ol (
.block; /* Inherit styles from ".block" */
color: #333;
text-transform: uppercase;
}

Compiled CSS (LESS)

.block(
margin: 10px 5px;
padding: 2px;
}
p(
margin: 10px 5px;
padding: 2px;
border: 1px solid #EEE;
}
ul,
ol (
margin: 10px 5px;
padding: 2px;
color: #333;
text-transform: uppercase;
}

As you can see, the styles from .block have been inserted into the selectors that we would like to give inheritance. It's important to note that priority can become an issue here, so be careful.

Import

In the CSS community, importing CSS is frowned upon because it requires multiple HTTP requests. However, importing with a preprocessor works differently. If you import a file from any of the three preprocessors, it will literally include the import at compile time, creating only one file. Keep in mind that importing regular .css files compiles with @import "file.css" by default; code. Additionally, mixins and variables can be imported and used in your main stylesheet. Import makes creation separate files very useful for the organization.

Sass, LESS and Stylus

/* file.(type) */
body (
background: #EEE;
}
@import "reset.css";
@import "file.(type)";
p(
background: #0982C1;
}

Compiled CSS

@import "reset.css";
body (
background: #EEE;
}
p(
background: #0982C1;
}

Functions of color

Color functions are built into functions that convert color at compile time. This can be extremely useful for creating gradients, darker hover colors and more.

Sass

lighten($color, 10%); /* returns a color 10% lighter than $color */
darken($color, 10%); /* returns a color 10% darker than $color */
saturate($color, 10%); /* returns a color 10% more saturated than $color */
desaturate($color, 10%); /* returns a color 10% less saturated than $color */
grayscale($color); /* returns grayscale of $color */
complement($color); /* returns complement color of $color */
invert($color); /* returns inverted color of $color */
mix($color1, $color2, 50%); /* mix $color1 with $color2 with a weight of 50% */

This is just a short list of available color functions in Sass, a full list of available Sass color functions can be found by reading the Sass documentation.

Color functions can be used anywhere color is used. Here's an example:

$color: #0982C1;
h1 (
background: $color;
border: 3px solid darken($color, 50%);
}

LESS

lighten(@color, 10%); /* returns a color 10% lighter than @color */
darken(@color, 10%); /* returns a color 10% darker than @color */
saturate(@color, 10%); /* returns a color 10% more saturated than @color */
desaturate(@color, 10%); /* returns a color 10% less saturated than @color */
spin(@color, 10); /* returns a color with a 10 degree larger in hue than @color */
spin(@color, -10); /* returns a color with a 10 degree smaller hue than @color */
mix(@color1, @color2); /* return a mix of @color1 and @color2 */

A list of all LESS functions can be found by reading the LESS Documentation.

Here is an example of using the color function in LESS:

@color: #0982C1;
h1 (
background: @color;
border: 3px solid darken(@color, 50%);
}

stylus

lighten(color, 10%); /* returns a color 10% lighter than "color" */
darken(color, 10%); /* returns a color 10% darker than "color" */
saturate(color, 10%); /* returns a color 10% more saturated than "color" */
desaturate(color, 10%); /* returns a color 10% less saturated than "color" */

Full list All Stylus color features can be found by reading the Stylus documentation.

Here's an example of using the Stylus color features:

Color = #0982C1
h1
background color
border 3px solid darken(color, 50%)

Operations

Doing math in CSS is quite useful and is now entirely possible. It's simple, and here's how it's done:

Sass, LESS and Stylus

body (
margin: (14px/2);
top: 50px + 100px;
right: 100px - 50px;
left: 10 * 10;
}

Practical Applications

We've covered a lot of the functions and new capabilities that preprocessors can do, but we haven't covered anything practical or practical. Here short list applications real world, where using a preprocessor is a lifesaver.

Vendor prefixes

This is one of the reasons to use a preprocessor and for a very good reason - it saves a lot of time and tears. Creating a mixin to handle vendor prefixes is easy and saves a lot of repetition and painful editing. Here's how to do it:

Sass

@mixin border-radius($values) (
-webkit-border-radius: $values;
-moz-border-radius: $values;
border-radius: $values;
}
div(
@include border-radius(10px);
}

LESS

.border-radius(@values) (
-webkit-border-radius: @values;
-moz-border-radius: @values;
border-radius: @values;
}
div(
.border-radius(10px);
}

stylus

border-radius(values) (
-webkit-border-radius: values;
-moz-border-radius: values;
border-radius: values;
}
div(
border-radius(10px);
}

Compiled CSS

div(
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}

3D text

Faking 3D text using multiple text shadows is a smart idea. The only problem is that changing the color after the fact is difficult and cumbersome. Using mixins and color functions, we can create 3D text and change color on the fly!

Sass

@mixin text3d($color) (
color: $color;
text-shadow: 1px 1px 0px darken($color, 5%),
2px 2px 0px darken($color, 10%),
3px 3px 0px darken($color, 15%),
4px 4px 0px darken($color, 20%),
4px 4px 2px #000;
}
h1 (
font-size: 32pt;
@include text3d(#0982c1);
}

LESS

.text3d(@color) (
color: @color;
text-shadow: 1px 1px 0px darken(@color, 5%),
2px 2px 0px darken(@color, 10%),
3px 3px 0px darken(@color, 15%),
4px 4px 0px darken(@color, 20%),
4px 4px 2px #000;
}
span (
font-size: 32pt;
.text3d(#0982c1);
}

stylus

text3d(color)
color: color
text-shadow: 1px 1px 0px darken(color, 5%), 2px 2px 0px darken(color, 10%), 3px 3px 0px darken(color, 15%), 4px 4px 0px darken(color, 20%), 4px 4px 2px #000
spa
font-size: 32pt
text3d(#0982c1)

I decided to write the Stylus text shadows on one line because I omitted the curly braces.

Compiled CSS

span (
font-size: 32pt;
color: #0982c1;
text-shadow: 1px 1px 0px #097bb7,
2px 2px 0px #0875ae,
3px 3px 0px #086fa4,
4px 4px 0px #07689a,
4px 4px 2px #000;
}

Final result

Columns

Using numeric operations and variables on columns is an idea I came across when I was first playing with CSS preprocessors. By declaring the desired width in a variable, we can easily change it along the way without any mental math. Here's how it's done:

Sass

$siteWidth: 1024px;
$gutterWidth: 20px;
$sidebarWidth: 300px;
body (
margin: 0 auto;
width: $siteWidth;
}
.content(
float: left;
width: $siteWidth - ($sidebarWidth+$gutterWidth);
}
.sidebar(
float: left;
margin-left: $gutterWidth;
width: $sidebarWidth;
}

LESS

@siteWidth: 1024px;
@gutterWidth: 20px;
@sidebarWidth: 300px;
body (
margin: 0 auto;
width: @siteWidth;
}
.content(
float: left;
width: @siteWidth - (@sidebarWidth+@gutterWidth);
}
.sidebar(
float: left;
margin-left: @gutterWidth;
width: @sidebarWidth;
}

stylus

siteWidth = 1024px;
gutterWidth = 20px;
sidebarWidth = 300px;
body (
margin: 0 auto;
width: siteWidth;
}
.content(
float: left;
width: siteWidth - (sidebarWidth+gutterWidth);
}
.sidebar(
float: left;
margin-left: gutterWidth;
width: sidebarWidth;
}

Compiled CSS

body (
margin: 0 auto;
width: 1024px;
}
.content(
float: left;
width: 704px;
}
.sidebar(
float: left;
margin-left: 20px;
width: 300px;
}

Remarkable decorum

There are quite a few quirks to using a CSS preprocessor. I'm going to list some of the fun ones, but if you're really interested in finding them all, I recommend you comb through the documentation, or better yet, just start using the preprocessor in your daily coding.

Bug reports

If you've written CSS for any decent amount of time, I'm sure you've reached a point where you made a mistake somewhere and you just couldn't find it. If you're like me, you've probably spent the day pulling your hair out and commenting on various things to hunt down the bug.

CSS preprocessors report errors. It's simple. If something is wrong with your code, it tells you where, and if you're lucky: why. You can check out this blog post if you are interested in knowing how errors are reported in different preprocessors.

Today I want to talk about why and how we came to use Stylus preprocessor in the development of Yandex.Mail, and also describe the method we use for working with styles for IE. It is very easy to implement using preprocessors and makes IE support simple and convenient. We designed for this special library, which we will also share - if-ie.styl.

This is only the first article in a series of articles about using the Stylus preprocessor in Yandex.Mail, which we are preparing for publication.

How we came to use preprocessors

Although outwardly Yandex.Mail looks like a one-page application, inside it contains a huge number of various blocks, their modifications and contexts in which these blocks and modifications may appear.

In addition, it already has more than thirty design themes. There are themes with a light background and with a dark one, there are themes that differ from each other only in colors, and there are also those in which almost the entire interface is molded from plasticine by hand (http://habrahabr.ru/company/yandex/blog/110556/ ). Some topics have only one background image, and in others the background may change - randomly or depending on the time of day and weather.

Because of all this, many variations in the visual presentation of the interface appear, which forces us to approach the development process a little differently and look for tools that are more suitable for solving the problem.

When we first launched the neo2 interface, we chose a solution that was familiar to us - the Template Toolkit 2 template engine, with a somewhat non-standard scenario for using it to generate CSS rather than HTML. At first we only needed variables, but over time the topics became more complex, and in the end it turned out that such a tool was inconvenient. The cumbersome syntax, the lack of CSS-specific functions and the general feeling of using the tool for other purposes made us look for other options. We realized that we couldn't do without a preprocessor.

Preprocessor selection

We chose between three options: Sass, Less and Stylus. The process was quite simple: we took several existing blocks, and then tried to redesign them using each of the preprocessors.

There are many more very different useful things in Stylus, but it was the ones mentioned above that made us choose it in favor.

Of course, in addition to the advantages, the Stylus also has disadvantages. And the main one is flexible syntax - the authors of the preprocessor consider it its main advantage. In pursuit of flexibility, they completely implemented only the syntax based on indentation, while the “a la CSS” option is somehow screwed on top, and it won’t be possible to just take and rename .css to .styl - not all CSS writing options will work and in Stylus. But we decided that the capabilities that this preprocessor gives us make its shortcomings less significant, so we had to put up with some of the capriciousness of the parser (and start using indentation-based syntax).

Summing up the story about the choice, it is worth noting that Sass and Stylus are two almost equivalent options. Each of them has its own advantages and unique features, as well as disadvantages. If you are already using one of these preprocessors and are satisfied with everything, great, you don’t have to think about looking for a new one. But if you are just approaching the choice or you feel overwhelmed with the preprocessor you are using, try comparing all the options. The best way To do this, try each preprocessor for its own task. Having developed part of your project on each of the preprocessors, you will understand which of their capabilities are important to you and which are not. Just don’t forget that a preprocessor is not just a different syntax, but also a different approach: with such a redesign, you can at the same time refactor the code, doing something more optimal than it was with simple CSS.

However, we need to tell you about one more function that turned out to be very useful for us as part of the thematicization of Yandex.Mail. This is the rgba-ie function. In fact, this function could just be called rgba , but Stylus has a bug: functions defined in JS cannot be overridden in the same way as those defined in Stylus, so we had to create a new one.

What is she doing? Older IEs do not support color values ​​specified in rgba format. Therefore, usually developers either specify the corresponding colors twice - first for old IE in the usual hex format, and then for all normal browsers in the desired rgba - or use modernizr and, using it and the .rgba class, set the corresponding colors where needed. But for fallbacks in IE, each time we still have to calculate the approximate color of what we will degrade it into. Most often this will be the desired color overlaid on top of the page background or the middle element background, with an rgba color applied above it.

The rgba-ie function from if-ie.styl greatly simplifies this task: duplicating the capabilities of the regular rgba function, we get another optional parameter that can be passed to the function - the background color for the fallback. By default, this parameter is set to #FFF .

Simple example:

Foo color: rgba-ie(0,0,0,0.5)

In regular browsers this color will be the usual rgba(0,0,0,0.5) , but in IE it will turn into #808080 - that is, the corresponding color overlaid on top of white.

More complex example, with the target background as the last argument (and using one of the Stylus features - the ability to specify instead three digits r , g and b color in hex):

Foo background: rgba-ie(#FFDE00, .42, #19C261)

In this example, for normal browsers the color will be rgba(255,222,0,0.42) , but IE will get the correct #7ace38 .

At the same time, it is possible to set the default fallback using the $default_rgba_fallback variable.

As a result, you can greatly simplify your life if you use the rgba-ie function instead of the usual rgba - in this case you will almost not have to remember about IE.

Tags:

Add tags