Showing posts with label Sass. Show all posts
Showing posts with label Sass. Show all posts

Wednesday, October 26, 2016

Embracing Sass: Why You Should Stop Using Vanilla CSS

When I first heard about Sass and other CSS preprocessors, my exact thoughts weren’t quite enthusiastic. “Why do we need another tool for something that already works as beautifully as CSS?”. “I won’t use that”. “My CSS is ordered enough to not need it”. “A preprocessor is for people who don’t know how to write CSS, if you know how to write CSS you won’t need a preprocessor”. “After all, processors are for people who do not know how to write CSS. If they did, they wouldn’t need need a preprocessor”. And I actually avoided them for a while, until I was forced to use it in several projects.
Embrace Sass once, and you may never want to go back to vanilla CSS againEmbrace Sass once, and you may never want to go back to vanilla CSS again
I didn’t realise how much I was enjoying working with Sass until recently, when I had to switch back to vanilla CSS in a project. During that time, I learned so much that I decided to praise Sass and make this a better world, and make you a happier person!

Why Use Sass Anyway?

Organization: @import

This project that I just mentioned, a large e-commerce website, had a single CSS file with 7184 lines of uncompressed style declarations. Yes, you read it right: seven thousand one hundred and eighty four lines of CSS. I am sure this is not the biggest CSS file front-end developers had to handle in the industry, but it was big enough to be a complete mess.
This is the first reason why you need Sass: it helps you organize and modularize your stylesheets. It’s not variables, it’s not nesting. For me the key feature of Sass are partials and how it extends the CSS @import rule to allow it to import SCSS and Sass files. In practice, this means that you will be able to split your huge style.css file into several smaller files that will be easier to maintain, understand, and organize.
Sass helps you organize and modularize your stylesheetsSass helps you organize and modularize your stylesheets

The @import rule has been around for almost as long as CSS itself. However, it gained bad fame since when you use @import in your CSS files, you trigger separate HTTP requests, one for each CSS file that you are importing. This can be detrimental to the performance of your site. So what happens what you use it with Sass? If you never stopped to think about what the word “preprocessor” means, now is the time.
“A preprocessor is a program that processes its input data to produce output that is used as input to another program.” —Wikipedia
So, going back to our @import rule, this means that the @import will be handled by Sass and all our CSS and SCSS files will be compiled to a single file that will end up in our live site. The user will have to make only one request and will download a single file, while your project structure can be comprised of hundreds of modularized files. This is what the style.scss of a typical Sass project may look like:
@import “variables”;
@import “reset”;
@import “fonts”;
@import “base”;
@import “buttons”;
@import “layout”;

Don’t Repeat Yourself: Variables

Any article praising Sass will probably start by mentioning its star feature - variables. The most common use of variables is a color palette. How many times did you find several declarations of what is supposed to be the same color, ending up in the CSS as slightly different shades because nobody uses the same hex code? Sass to the rescue. In Sass, you can declare variables with almost any value. So, our color palette can be something like:
$brand: #226666;
$secondary: #403075;
$emphasis: #AA8439;
The words starting with “$” are Sass variables. What it means is that later in your stylesheets, you will be able to use those words, and they will be mapped to the values that you defined before:
body {
  background: $secondary;
}

.logo {
  color: $brand;
}

a {
  color: $emphasis;
}

a:hover {
  color: $brand;
}
Imagine how this could change our 7184 lines of CSS code, and you may start desiring Sass right now. Even better, imagine there is a redesign of the brand and you need to update all the colors in your CSS. With Sass, the only thing you need to do is to update the declarations of those variables once, and baam! The changes will be all around your stylesheets.
I coded this example in Sassmeister, a Sass playground. So go ahead and try changing those variables to something else.
The usefulness of variables are not just limited to colors, but font declarations, sizes, media queries, and more. This is a really basic example to give you an idea, but believe me, the possibilities with Sass are endless.
The possibilities with Sass are endless

Cleaner Source Code: Nesting

Nesting could be possibly the second most mentioned feature of Sass. When I went back to vanilla CSS after using Sass, the CSS file I was looking at seemed so cluttered that I wasn’t sure if it was minified. Without nesting, vanilla CSS doesn’t look any better than pretty printed .min.css files:
.header {
  margin: 0;
  padding: 1em;
  border-bottom: 1px solid #CCC;
}

.header.is-fixed {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
}

.header .nav {
  list-style: none;
}

.header .nav li {
  display: inline-block;
}

.header .nav li a {
  display: block;
  padding: 0.5em;
  color: #AA8439;
}
With Nesting, you can add classes between the braces of a declaration. Sass will compile and handle the selectors quite intuitively. You can even use the “&” character to get a reference of the parent selector. Going back to our example CSS, we can transform it to:
.header {
  margin: 0;
  padding: 1em;
  border-bottom: 1px solid #CCC;

  &.is-fixed {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
  }

  .nav {
    list-style: none;

    li {
      display: inline-block;

      a {
        display: block;
        padding: 0.5em;
        color: #AA8439;
      }
      
    }

  }

}
It looks beautiful and is easier to read. Feel free to play with this example.
Again! Don’t Repeat Yourself: Mixins and Extends
Repetition in CSS is always hard to avoid. And it doesn’t hurt to stress on this a bit more, especially when Sass gives you mixins and extends. They are both powerful features and help avoid a lot of repetition. Possibilities with mixins and extends don’t seem to have an end. With mixins, you can make parameterized CSS declarations and reuse them throughout your stylesheets.
Keep things DRY with SassKeep things DRY with Sass
For example, let’s say you have a box module with a button inside. You want the border of the box and the background of the button to be of the same color. With vanilla CSS, you do something like:
.box {
  border: 2px solid red;
}

.box .button {
  background: red;
}
Let’s say you now want the same box module, but with a different color. You will add something like this to your CSS:
.box-alt {
  border: 2px solid blue;
}

.box-alt .button {
  background: blue;
}
Now, let’s say you want a box module, but with thinner border. You would add:
.box-slim {
  border: 1px solid red;
}

.box-slim .button {
  background: red;
}
A lot of repetition, right? With Sass you can abstract these cases to reduce repetition. You could define a mixin like this one:
@mixin box($borderSize, $color) {

  border: $borderSize solid $color;

  .button {
    background: $color;
  }

}
And so, your source code can be reduced to:
.box { @include box(2px, red); }
.box-alt { @include box(2px, blue); }
.box-slim { @include box(1px, red); }
Looks beautiful, right? Play around with this example. You can create your own library of mixins, or even better you can use one of the community libraries out there.
Extends are similar, they let you share properties from one selector to another. However, instead of outputting multiple declarations, they output a list of classes without repeating your properties. This way you can avoid repetition of code in your output as well. Let’s forget about the buttons in our previous example and see how @extend would work with .boxes.
Let’s say you declare a first box:
.box {
  margin: 1em;
  padding: 1em;  
  border: 2px solid red;
}
Now you want two boxes similar to this one, but with different border colors. You can do something like:
.box-blue {
  @extend .box;
  border-color: blue;
}

.box-red {
  @extend .box;
  border-color: red;
}
This is how the compiled CSS would look like:
.box, .box-blue, .box-red {
  margin: 1em;
  padding: 1em;
  border: 2px solid red;
}

.box-blue {
  border-color: blue;
}

.box-red {
  border-color: red;
}
Powerful, right? You can find the example here. If you review the resulting CSS, you will realize that the class .box is being included in the output. If you don’t want this behavior, you can combine @extend with “placeholders”. A placeholder is a special selector that won’t output a class in the CSS. For example, I sometimes find myself resetting the default styles of lists a lot. I generally use @extend with a placeholder like this:
%unstyled-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
You can then reuse this pattern in all your stylesheets:
.search-results {
  @extend %unstyled-list;
}

.posts {
  @extend %unstyled-list;
}

.nav {
  @extend %unstyled-list;
}
Your compiled CSS will look like:
.search-results, .posts, .nav {
  list-style: none;
  margin: 0;
  padding: 0;
}
Check out the examples here.

Is There More?

Absolutely! I didn’t want to overcomplicate this article, but there is a Sassy world waiting to be discovered by you; and there are also a lot of features beyond those: operations, single-line comments with //, functions, if loops … if you ever thought “it would be great to do some ‘X’ thing with CSS”, I’m sure that thing ‘X’ is already done by Sass. “CSS with superpowers” is its tagline, and that can’t be any closer to the truth.

Conclusion

Go and visit the install page and start hacking! Believe me, you won’t regret it.
Yes, there are some alternatives to Sass. Other preprocessors (LESS, Stylus), postprocessors, Grunt, etc. There are even CSS Variables. I’m not saying that Sass is the only technology out there. All I’m saying is that it’s the best! At least for now. Don’t believe in what I’m saying? Go ahead and try it yourself. You won’t regret it!

Wednesday, August 10, 2016

Sass Style Guide: A Sass Tutorial on How to Write Better CSS Code

Writing consistent and readable CSS that will scale well is a challenging process. Especially when the style sheets are getting larger, more complex, and harder to maintain. One of the tools available to developers to write better CSS are preprocessors. A preprocessor is a program that takes one type of data and converts it to another type of data, and in our case CSS preprocessors are preprocessing languages which are compiled to CSS. There are many CSS preprocessors that front-end developers are recommending and using, but in this article we will focus on Sass. Let’s see what Sass has to offer, why it is a preferable choice over other CSS preprocessors, and how to start using it in the best way.

What Is Sass and Why Should You Use It?

For those of you who don’t know what is Sass, the best starting point is to visit the official Sass webpage. Sass is an acronym for Syntactically Awesome StyleSheets, and is an extension of CSS that adds power and elegance to the basic language.
With Sass (Syntactically Awesome StyleSheets) your CSS code will be also awesome.With Sass (Syntactically Awesome StyleSheets) your CSS code will be also awesome.
Sass is a CSS preprocessor with a lot of powerful features. The most notable features are variablesextends, and mixins.
Variables store information that can be reused later, like colors or other commonly used values. Extends help you create “classes” that allow inheritance for the rules. Mixins, you can think of like “function”. Sass also has some other amazing features in comparison with other preprocessors, like the use of logic statements (conditionals and loops), custom functions, integration with other libraries like Compas, and many more. These features alone can help you and your team to be more productive and to write better CSS in the end.

Why You Need a CSS Style Guide

Unfortunately, even preprocessors can’t fix everything and help you write good CSS code. The problem every developer is facing is that current web applications are becoming bigger and bigger. That’s why code needs to be scalable and readable, and needs to avoid spaghetti code and unused lines of it. To avoid mentioned problems, some sort of standard for your team in the daily work is needed. What is spaghetti code, and how does it it happen? Spaghetti code is a name for bad, slow, repetitive, and unreadable code. When a team writes big applications without defined guidelines or standards in place, each developer writes what he needs and how he wants. Also when developers are writing a lot of bug fixes, hotfixes, and patches, they tend to write code that will solve the problem but don’t have time to write the code in the best way. In these situations, it is very usual to end up with lots of lines of CSS that are not used in any sector of the application any more. Developers don’t have enough time to clean the code, and they are forced to publish the fix as quickly as possible. Another reocurring situation is that to fix broken things quickly, developers use a lot of !important, which results with very hacky code that is hard to maintain, it results with a lot unexpected behaviors, and needs to be refactored later. As mentioned already, as the code grows the situation becomes only worse.
The idea of this article is to share rules, tips, and best practices to write a better Sass. Grouping together those Sass tips and best practices can be used as a Sass style guide. This style guide should help developers to avoid situations mentioned above. Rules are grouped into logical segments for easier referencing, but in the end you should adopt and follow them all. Or at least, most of them.

Style Guide

The set of rules and best practices in this style guide are adopted based on experience working with a lot of teams. Some of them come from trial by error, and others are inspired by some popular approaches like BEM. For some rules there is no specific reason why and how they were set. Sometimes having the past experience as the only reason is enough. For example, to make sure that the code is readable it is important that all developers are writing the code in the same way, thus there is the rule to not include spaces between parentheses. We can argue if it is better to include the space between parenthesis or not. If you think that it looks better when there are spaces between parenthesis, adjust this style guide and rules by your preferences. In the end, the main goal of the style guide is to define rules, and to make the developing process more standard.
Main goal of the style guide is to define rules, and to make the developing process more standard.Main goal of the style guide is to define rules, and to make the developing process more standard.

General CSS Rules

General rules should always be followed. They are mostly focused on how Sass code should be formatted to bring consistency and readability of the code:
  • For indentation, use spaces instead of tabs. The best practice is to use 2 spaces. You can run your own sacred war with this option, and you can define your own rule and use either tabs, or spaces, or whatever suits you best. It is only important to define a rule and follow that rule while being consistent.
  • Include an empty line between each statement. This makes the code more human readable, and code is written by humans, right?
  • Use one selector per line, like this:
selector1,
selector2 {
}
  • Do not include a space between parentheses.
selector {
   @include mixin1($size: 4, $color: red);
}
  • Use single quotes to enclose strings and URLs:
selector { font-family: ‘Roboto’, serif; }
  • End all rules with a semicolon without spaces before:
selector {
  margin: 10px;
}

Rules for Selectors

Next we are following with a set of rules to use when dealing with selectors:
  • Avoid the use of ID selectors. IDs are too specific and used mostly for JavaScript actions.
  • Avoid !important. If you need to use this rule, it means that something is wrong with your CSS rules in general, and that your CSS is not structured well. CSS with many !important rules can be easily abused and ends up with messy and hard to maintain CSS code.
  • Do not use child selector. This rule shares the same reasoning as the ID one. Child selectors are too specific and are tightly coupled with your HTML structure.
If you are using !important a lot in your CSS, you are doing it wrong.If you are using !important a lot in your CSS, you are doing it wrong.

Keep Your Sass Rules in Order

It is important to keep consistency in the code. One of the rules is that you need to keep the order of rules. This way other developers can read the code with much more understanding, and will spend less time finding their way around. Here is the proposed order:
  1. Use @extend first. This let you know at first that this class inherits rules from elsewhere.
  2. Use @include next. Having your mixins and functions included at top is nice to have, and also allows you to know what you will be overwriting (if needed).
  3. Now you can write your regular CSS class or element rules.
  4. Place nested pseudo classes and pseudo elements before any other element.
  5. Finally, write other nested selectors like in the following example:
.homepage {
  @extend page;
  @include border-radius(5px);
  margin-left: 5px;
  &:after{
    content: ‘’;
  }
  a {
  }
  ul {
  }
}

Some naming conventions

Naming conventions part of the style book is based on the two existing BEM and SMACSS naming conventions that became popular amongst developers. BEM stands for Block, Element, Modifier. It was developed by the YANDEX team, and the idea behind BEM was to help developers understand the relationship between HTML and CSS in the project. SMACSS on the other hand stands for Scalable and Modular Architecture for CSS. It is a guide to structure CSS to allow maintainability.
Inspired by them, our naming conventions rules are as follows:
  • Use prefix for each type of element. Prefix your blocks, like: layouts (l-), modules (m-), and states (is-).
  • Use two underscores for child elements for every block:
.m-tab__icon {}
  • Use two dashes for modifiers for every block:
.m-tab--borderless {}

Variables

Use variables. Start with the more general and global variables like colors, and create a separate file for them _colors.scss. If you notice you are repeating some value over the style sheet multiple times, go and create a new variable for that value. Please DRY. You will be grateful when you want to change that value, and when you will need to change it in only one place.
Also, use a hyphen to name your variables:
$red : #f44336;
$secondary-red :#ebccd1;

Media Queries

With Sass you can write your media queries as element queries. Most of the developers write media queries in a separate file or at the bottom of our rules, but that is not recommended. With Sass you can write things like the following example by nesting media queries:
// ScSS
.m-block {
  &:after {
    @include breakpoint(tablet){
      content: '';
      width: 100%;
    }
  }
}
This generates a CSS like this:
// Generated CSS
@media screen and (min-width: 767px) {
  .m-block:after {
    content: '';
    width: 100%;
  }
}
This nested media queries rules allow you to know very clearly what rules are you overwriting, as you can see in the Sass snippet where named media queries are used.
To create named media queries, create your mixin like this:
@mixin breakpoint($point) {
  @if $point == tablet {
    @media (min-width: 768px) and (max-width: 1024px) {
      @content;
    }
  } @else if $point == phone {
    @media (max-width: 767px) {
      @content;
    }
  } @else if $point == desktop {
    @media (min-width: 1025px) {
      @content;
    }
  }
}
You can read more about naming media queries in the following articles: Naming Media Queries and Write Better Media Queries with Sass.

Other Considerations

In the end, here are some other considerations that you should also keep in mind and follow:
  • Never write vendor prefixes. Use autoprefixer instead.
  • Use maximum three levels of deep in nested rules. With more than three nested levels, the code will be difficult to read, and maybe you are writing a crappy selector. In the end, you are writing CSS code to couple with your HTML.
.class1 {
   .class2 {
       li {
           //last rules
       }
    }
}
  • Don’t write more than 50 lines of nested code: Or better, don’t write more than X lines of nested code. Setup your own X, but 50 looks like a good limit. If you pass that limit maybe the block of code will not fit in your text editor window.
  • Write a main file where you will import all of your blocks, partials, and configs.
  • Import vendor and global dependencies first, then authored dependencies, then layouts, patterns, and finally the parts and blocks. This is important to avoid mixed imports and overwrite of rules, because the vendor and global rules can’t be managed by us.
  • Don’t be shy and break your code in as many files as possible.

Conclusion

The idea behind this style guide is to give you some advice on how to improve the way you are writing your Sass code. Please keep in mind that even if you are not using Sass, the provided tips and rules in this style guide are also applicable and recommended to follow if you use Vanilla CSS or another preprocessor. Again, if you don’t agree with any of the rules, change the rule to fit your way of thinking. In the end, it is up to you and your team to either adapt this style guide, use some other style guide, or create a completely new one. Just define the guide, and start writing an awesome code.
This article was written by Matias Hernandez, a Toptal Javascript developer.