The basic concepts of Sass for RWD
For starters, Sass is a programming/scripting language. I bet you didn't see that one coming. Yes, it's a programming/scripting language focused on increasing the efficiency of web designers and web developers creating CSS. In this book, we're going to focus on the simple parts of Sass that can help us write CSS more efficiently, and more importantly, we'll have fun doing it.
Implementing RWD is time consuming: coding, testing, creating assets, browser troubleshooting, and then testing some more. The more we streamline our coding processes and the less repetitive work we do, the more efficient we become and the more value we add to a project, our team, the business and eventually, our users. Sass is going to do just that—help us streamline the coding of CSS.
Let's discuss the following concepts first:
- Sass or SCSS
- Variables
- Mixins
- Arguments
- Nesting
- Partial files
- @import
- Source maps
- Sass comments
There are two ways we can write Sass-style CSS: the Sass syntax and the SCSS syntax.
Tip
Make no mistake; Sass is written with capital S and the rest with lower case and SCSS is all uppercase.
The Sass syntax, also known as the indented syntax, was the initial and only way to write Sass. But it looked a bit too different than regular CSS, making the learning curve steeper than it really needed to be.
This syntax didn't use any braces or semicolons. In some cases, instead of colons it used the equals sign. Unlike SCSS, indentation was very strict and mandatory. Many developers weren't too fond of these aspects of the Sass syntax.
Here's a basic example:
This compiles to the following code:
When SCSS was introduced with the release of version 3 of Sass, things got a lot easier for those of us who are not programmers but want to harness the power of Sass.
Note
SCSS stands for Sassy CSS.
If you already write CSS, you already write SCSS. All the things we already used while writing CSS are the same things we'll use when writing Sass with the SCSS syntax. So, the learning curve is initially nonexistent.
Then, you realize that you can also use bits of Sass that enhance what you already know, making learning Sass an awesome experience because you can get good at it quite fast. It honestly feels like you're gaining superpowers. I'm not kidding.
Here's the same example we saw before with the SCSS syntax:
Wait a second! That's CSS! Yes, and it's also SCSS.
Let's see that same example in a different way using the SCSS syntax as well:
The ampersand symbol, &
, in SCSS allows us to add the name of the parent selector to the nested selectors without having to type the whole thing, keeping us on the DRY side of things.
Note
DRY means Don't Repeat Yourself.
Both SCSS examples compile to the following code:
Let's understand a few things first:
- A variable is simply a way to store a value for later use
- This value is usually associated with a simple user-friendly word
- Sass variables have to start with a dollar sign (
$)
symbol - The great benefit of variables is that if we need to change the value, we would make the change in a single place rather than finding and replacing the value across the entire document
Tip
When listing more than one variable, there should be a semicolon symbol (;
) at the end of each variable. If there's only one variable, there's no need for the semicolon. However, this is a good practice to always end variables with a semicolon even if it's just one.
Here's an example of a Sass variable:
Tip
I recommend you name variables using the camelCase style in order to differentiate them from dash-separated class names and CSS properties. This is very helpful when scanning the SCSS document, because the variables are easier to detect.
As we can see, we're storing a color value. The name we're using, brandBlue
, is certainly more user friendly than #416e8e
. Also, we're using the dollar sign symbol ($
) and ending it with a semicolon (;
) for good measure if/when we need to add more variables. Now, if we need to change the value later, all we'd need to do is change it in one location.
The variables should always be included at the top of your SCSS file so Sass knows where to go when using them. You can also include them via a partial file, but we'll talk about what partial files are later on in the chapter.
Here's an example of how to use an SCSS variable:
The preceding code compiles to the following:
Mixins are one of the most powerful features of Sass. Mixins are a group of CSS declarations (a property and value) that are stored for later use, just like a variable. So instead of typing all those CSS declarations over and over again, we just type the mixin's name.
A few things to consider about Sass mixins are as follows:
- They start with the
@mixin
directive - A mixin is called with the
@include
directive - We can store any amount of CSS/SCSS data in a mixin
- Try to use arguments when creating a mixin so it's more scalable
Tip
We haven't seen what arguments are yet, but it's important to mention the word now so you can start getting familiar with different Sass terminology. We'll cover Sass arguments in the next section.
Let see an example of a mixin:
We call a mixin in our SCSS file as follows:
When compiled, it looks like this in the CSS:
Let's recap what we did in the mixin.
We used the @mixin
directive:
We used the camelCase naming convention to differentiate the mixin's name from dash-separated class names and CSS properties:
We used Sass variables within the mixin:
We used the keyword black
in the box-shadow
color property instead of using the hex #000
or rgb (0, 0, 0)
values:
For that matter, we could've also used our variable name like this:
We also omitted the 0
in the alpha value (.3
). This is actually not a Sass feature; this is a CSS feature:
Tip
On decimal values that start with a zero, the zero can be omitted.
Again, the preceding mixin compiles to the following CSS:
In our first mixin example, we didn't have any arguments. This is really not ideal because it doesn't allow us to use different values in the same properties. In reality, not using any arguments in a mixin isn't really any different than typing the same properties and values every time we need them. We are not really doing any DRY.
Arguments are the part(s) of a mixin in which you can put your own values depending on your needs. Arguments make a mixin worth creating.
In the mixin example mentioned earlier, let's add an argument:
The argument for padding
allows us to set any value we want. We are not forced to have the padding as 10px
every time.
This is how we set the value of the argument:
This compiles to the following:
However, there's a potential problem with the argument; if we don't set a value for the padding
, we're going to get an error when compiling.
So the solution here is to set a default value; if we don't define a value for padding
for some reason, Sass is going to take that default value and use it when compiling without throwing an error.
Here's how we set a default value of an argument:
This is how we call the mixin, without declaring any padding
value:
The compiled CSS is as follows:
How to use several arguments in the same mixin
Building on the preceding mixin, let's add a few more arguments to make it more robust and scalable:
This is how we declare the arguments when including our mixin:
We can use the same mixin and obtain different styles without having to type all the properties repeatedly.
The preceding mixin and its arguments compile to the following code:
Setting default values in multiple arguments
Sometimes, we need to define some default values in case we only need to declare one or a few arguments. In other words, by declaring default values in our arguments, we'll always be sure that a value is created and we don't get any errors when compiling our SCSS file.
Here's how we set default values in our arguments:
If we need to declare only the first property, padding
, we can do this:
This compiles to the following:
Tip
Some Sass compilers will turn a shorthand color hex value, #333
, to a longhand value, #333333
.
As we can see, only the first argument, padding
, was declared. Other arguments used their default values and compiled successfully.
But let's say we still want to declare only one argument but not the padding
, which is the first in the list of arguments. Let's say we want to declare the background color!
In this case, we need to declare the value by typing the name of the variable:
Tip
If we want to declare only a single argument that is different from the first one, we need to declare the whole argument name.
There are more advanced ways to declare arguments, but this is sufficient for the scope of this book.
Nesting in Sass is a perfect way to make our SCSS more readable. Just like in HTML where tags get nested based on their parent elements, Sass uses exactly the same structure.
Here's an example of two-level selector nesting for a navigation bar:
Tip
Beware of deep nesting! Best practices recommend nesting a maximum of three levels. Otherwise, we will run into selector specificity and maintainability issues down the road.
Did you notice that I used the $brandBlue
color variable again? The preceding SCSS for the navigation bar compiles to the following CSS:
Partial files (partials) in Sass
Partial files are SCSS files we create to house SCSS snippets. Partials allow us to modularize our files, for example, _variables.scss
. Partials start with the underscore symbol (_
) and end with the extension .scss
. The underscore symbol tells the compiler that this file and its contents do not need to be compiled into a separate CSS file.
Partials are called using the @import
directive, just like it is done in CSS. The main differences are that there's no need to specify the underscore symbol and the file extension.
Let's create a partial file and put these color variables in it. We're going to call this partial file, _variables.scss
. The variables (snippets) in the _variables.scss
partial are as follows:
Let's then say that our main SCSS file is named styles.scss
. We now have two files: styles.scss
and _variables.scss
.
Tip
The main SCSS file of a project does not start with an underscore symbol.
We call _variables.scss
into styles.scss
using the @import
directive:
Notice that the underscore symbol and file extension are not needed when referencing a partial; they can be omitted. However, if you want to add them, that's fine too. Omitting them keeps the code cleaner.
The Sass extend/inherit feature
Many professionals say extend or inherit is one of the most useful features of Sass. Others actually recommend staying away from it. This book's recommendation is: just use Sass as much as possible and experiment with different features so you can create your own opinions. When you have enough experience, you can decide which side you want to join.
Extending in Sass means that we can use a selector's properties in another selector without having to type all those properties again. This is called inheriting. We use the @extend
directive for this.
For example, consider the following selector:
Suppose we want to inherit all the properties of this selector on a different selector. We're also going to modify one property, since they are almost identical, using the @extend
directive to reuse the styles of the first selector in the second one:
This compiles to the following:
Notice that .generic-container
and .box-customer-service
are in the same rule; this means that .box-customer-service
is inheriting all the properties and values of .generic-container
. Then, there's a separate rule for .box-customer-service
, where only the padding
property is declared since it's the only difference between the two containers.
Since we know that a CSS document is a valid SCSS document, using the CSS comment syntax is also valid:
In Sass, there's another way. We can comment using double slashes (//
) at the beginning:
The difference between the two styles is that the traditional CSS comment using /**/
syntax gets added to the compiled file, whereas the comments with Sass using //
does not get added.
The comments with the Sass syntax are very helpful to document our SCSS files without having to worry about all those comments getting compiled and bloating our final CSS file. The Sass comment in the following example doesn't get compiled:
However, the traditional CSS comment does get compiled:
Tip
Now, depending on the options set on the compiler, the final CSS can be minimized. Thus, the traditional CSS comments will get stripped out in order to optimize file size.
Vendor prefixing is basically adding a specific tag to a CSS3 property or value that hasn't been widely used by the web development industry and communities or finalized and included in the CSS3 specification.
The vendor part refers to the abbreviation tags that represent the names of the companies that create the browsers: Mozilla, Opera, and Microsoft.
There's one exception though, Apple. Although Apple created Safari, the vendor prefix is based on the layout engine of the browser rather than the company name.
- Mozilla:
-moz-
- Opera:
-o-
- Microsoft:
-ms-
- Webkit (Apple):
-webkit-
The prefix part refers to the description of adding the vendor tags before the CSS property or CSS value. Each vendor prefix only works in its own browser, so for the preceding list, here are the browsers they belong to:
- Mozilla: This prefix
-moz-
works in Firefox - Opera: This prefix
-o-
works in Opera - Microsoft: This prefix
-ms-
works in Internet Explorer - Webkit (Apple): This prefix
-webkit-
works in Safari
If you're wondering where Google Chrome is in all this, there's a simple explanation.
Although Google created Chrome, there is no specific prefix for Chrome. In the beginning, Chrome was using the same layout engine as Safari: Webkit. Thus, the Webkit-based prefixes not only affected Safari, but also affected Chrome and other Chromium-based products.
However, Google Chrome no longer uses Webkit; it now uses its own layout engine called Blink. However, in order to maintain compatibility and avoid fragmenting the Web even more, Chrome still supports the -webkit-
prefix.
Opera had a similar story where they had their own layout engine, Presto, and then switched to Webkit. It now uses Blink. There are other browser vendors in addition to the ones mentioned before and they use their own prefixes as well, such as the Konqueror browser with its prefix, -k-
.
Here's an example of a vendor-prefixed CSS property:
And, here's an example of a prefixed CSS value:
The order of vendor prefixing
The reality is that the order in which we can list the vendor prefixes doesn't matter; what matters is that we always place the nonvendor prefixed version at the end.
Staying with the example of the linear-gradient property, we should do it like this:
Tip
You can also use background: linear-gradient(red, blue);
if you like.
The reason the nonvendor-prefixed declaration should always be last is, if the browser vendor modifies its prefix or drops the support for it, the last line will always override anything above it because of the cascade. This makes the whole CSS rule more future-proof. Plus, we won't have to rewrite our style sheets every time a vendor changes something.
Now, many CSS3 properties and values do not need all vendor prefixes. Most of the time, they only need a couple of vendor prefixes, and other times the nonvendor-prefixed - properties or values is enough.
But how do we know which CSS3 properties and values can be prefixed or not so that we can create styles that are supported by certain legacy browsers without having to memorize so much information?
The answer is automating the vendor prefixing process.
Automating vendor prefixing
There are several problems that come with vendor prefixing, and we can't get away from these if we want some of our CSS3 properties to work in current browsers and/or certain legacy ones. Vendor prefixing is dirty work and we don't have to do it.
So how do we automate the process of vendor prefixing while keeping our work as DRY as possible? There are several ways.
Compass is a framework for Sass that helps us write CSS more efficiently. Compass has a massive library of mixins that we can use to leverage dealing with vendor prefixes.
The installation of Compass is outside the scope of this book, so we're going to focus on the basic usage to deal with vendor prefixes and will assume that it is already installed on your machines. Refer to the Compass site for detailed instructions on how to install it (http://compass-style.org/).
Once we have Compass installed, we need to import the specific module that contains the mixins we need.
Staying with the linear gradient example we used before, let's import Compass' images
module into our SCSS file. Place this at the top of your main SCSS file:
Then, we can use the corresponding mixin:
This will compile to the following:
There are a few new things here.
The first declaration uses a base64 embedded SVG file. This is because legacy IEs and old versions of Opera have issues rendering gradients so an SVG is their fallback. Dealing with these types of issues is completely unnecessary by today's standards:
The background-size: 100%;
parameter is used so that the embedded SVG covers the whole container. Again, dealing with something like this is just a waste of time. Moreover, our code keeps getting bloated trying to support old technology. Consider the next block of code:
The third declaration is the old CSS linear gradient syntax that was supported only by Webkit browsers; more unnecessary code bloating in our file:
The fourth and fifth declarations are basically for old Firefox, Chrome, and Safari versions:
The last declaration is the proposed syntax without any vendor prefixes:
As we can see, Compass is a very handy tool and it allows us to customize the output. However, this may end up being more work than necessary.
A few things to consider before concluding whether Compass is the best solution for us:
- Compass needs to be installed. This is usually done via the command line.
- Once Compass is installed, we don't have to use the command line anymore to use its mixins.
- Compass has a massive library of mixins that can help deal with vendor prefixing and many other things.
- Each time we need to work with a specific CSS3 property or value, we have to import the corresponding module in our main SCSS file with the
@import
directive. This means that we have to spend a lot of time finding the modules we need and learn to use them. - The learning curve of using Compass is medium, we need to be a bit knowledgeable in other technical aspects to get to use Compass even at its most basic.
- Compass has great documentation and is a project in constant development.
- There's a similar, well-known mixin library called Bourbon: http://bourbon.io/.
-prefix-free
is a JavaScript file created by Lea Verou. When the script is called by the browser, it detects it and then adds that browser's specific prefixes to the CSS. The -prefix-free
file is intelligent enough to determine which prefixes are needed and only inject those.
Using -prefix-free
is simple. Just add a call the JavaScript file. As per Lea Verou's recommendation, it's best to include this script after the style sheets in order to reduce the Flash of Unstyled Content (FOUC).
You can visit the -prefix-free
project at http://leaverou.github.io/prefixfree/.
Since our HTML is so short, we can follow the tip mentioned before:
It's certainly tempting to use this method since calling a mere JavaScript file to deal with automating vendor prefixes sounds like the best idea ever.
Let's see a short list of things to consider before deciding to use -prefix-free
:
- It's incredibly easy to use.
- It's an additional HTTP request. The fewer requests our site/page(s) have the faster they are, hence the better UX we provide our users. It's also beneficial for SEO.
- It's an extra file to manage. Yes, once we upload the JavaScript file we may not need to go back to it—unless we're updating it, which means we need to run extensive tests locally so that we don't break anything in production.
- It puts a bit more strain on the user's browsers to do the heavy lifting since everything happens in the browser.
- It doesn't work in files being called using the
@import
directive. This could also be seen as a good thing because if we're using @import
to import files, we have a different and even bigger problem in our hands. - If we're serving style sheets from a different domain than our main site,
-prefix-free
won't work on those external CSS files. - Chrome and Opera have issues with allowing
-prefix-free
to work locally. Although this is easy to fix, it just adds another layer of complexity to our workflow. - If there are inline styles, some unprefixed CSS values and properties won't work in IE.
With this list, we are now in a better position to make a more informed decision that will benefit the project, ourselves and our users.
Autoprefixer is a CSS postprocessor that uses the CanIUse.com database to append vendor prefixes to an already compiled CSS file.
The term postprocessor means that it processes the CSS after (post) it has been created. In other words, if we have an SCSS file called styles.scss
, this file gets compiled into styles.css
after we save it. At that moment, Autoprefixer takes that generated styles.css
file, opens it, adds all the necessary vendor prefixes to each property and value, saves the file, and closes it. In addition, you can configure it to create a new separate file as well. Once this is done, we can use this file in our website/app.
The major advantage that this method has over any other automated vendor prefixing method is that it uses the CanIUse.com database; this means that as soon as a browser vendor no longer requires its prefix for a CSS property or value, all we need to do is run our CSS files through Autoprefixer and it will be up to date in seconds.
The major disadvantage of Autoprefixer is that it has so many ways to use it that it could be a bit overwhelming for some. To name a few, we can use it via the command line but we'd need to have Node.js
installed first:
We can also use Autoprefixer with Compass, but we need to have Ruby installed first:
We can use it with CodeKit on Mac and with Prepros or Koala App on Windows/Mac/Linux. We can also install plugins for Sublime Text, Brackets, or Atom Editor. There are Grunt and Gulp plugins as well.
Let's see a short list of things to consider before deciding to use Autoprefixer:
- The fact that it uses the CanIUse.com database is by far the best feature and advantage over any other automated vendor prefixing application, because we can always be sure that our CSS files have the latest prefixes, or none if the browser vendor has dropped any of them.
- It can be integrated into many applications.
- It can be a bit daunting to install for new web designers or developers.
- Autoprefixer comes preinstalled in other applications, so all we need to do is run those applications and we're automatically using Autoprefixer without having to set anything up.
Autoprefixer can be downloaded from https://github.com/postcss/autoprefixer.
Yes, it's Pleeease with three e. Pleeease is also a CSS postprocessor like Autoprefixer and it also depends on having Node.js
installed. It only runs via the command line, but it's actually quite simple. Pleeease uses Autoprefixer, which means that it uses the CanIUse.com database as well to define which CSS properties and/or values need prefixing.
Once Pleeease is installed, we need to create a configuration file (a JSON file) in which the most important thing we need to define is the source CSS file and the destination CSS file:
Once we have that configuration file set, we run this in the command line:
Pleeease takes the style.css
file, adds all necessary vendor prefixes, and creates styles.fixed.css
, which is the file we use in production.
There are other important things that Pleeease does at this point:
- Compiles the same media queries into one
@media
block - Inlines
@import
style sheets (this is great because we end up with one single CSS file for production) - Minifies/compresses the final file
If you're comfortable using the command line and JSON files, Pleeease can be a very useful part of your arsenal. If you prefer to stay away from the command line, that's fine too; there are other friendlier ways to automate vendor prefixing.
Here are a few things to consider before deciding if Pleeease is the way to go to automate vendor prefixing:
- It requires the use of the command line to install and use, but the commands are quite simple.
- It uses a JSON file to configure its settings.
- It uses Autoprefixer, which means it uses the CanIUse.com database as well. This makes it incredibly powerful when it comes to knowing which properties and/or values need or don't need to be prefixed.
- It makes several other improvements to the final CSS file, such as packing the same media queries in a single
@media
rule, minifying the result, and so on. - It can be integrated with the Grunt, Gulp, Brunch, and Node.js workflows.
You can download Pleeease from http://pleeease.io/.
Emmet allows us to write CSS and HTML faster. It's a plugin for text editors such as Sublime Text, Coda, TextMate, and even Dreamweaver.
Emmet also helps us with vendor prefixing our CSS3 properties and values, which is what we're going to focus on in the following examples.
Tip
Emmet used to be called Zen Coding.
Once the Emmet plugin is installed in our favorite text editor, we type this in our SCSS file:
Tip
-trf
is the abbreviation of the CSS3 property transform.
Then we press Tab on our keyboard and the code automatically gets changed to this:
All we need to do to add vendor prefixes is start our abbreviation with a dash (-
). This tells Emmet that it needs to add the necessary vendor prefixes when hitting the key Tab.
Tip
The transform values were not defined in the previous example because we want to show the result from using Emmet. Obviously, we'd have to add those values in the end.
Here are a few things to consider before deciding to use Emmet to automate vendor prefixing:
- It's up to us to define what gets prefixed and what doesn't, so we may end up prefixing properties and values that no longer need to be prefixed. Thus, we end up bloating our CSS files.
- If we forget to add a dash at the beginning of a property/value, it won't be prefixed and maybe that property/value does need prefixed. Thus, we'll spend more time troubleshooting.
- Emmet works with the most popular text editors out there, so chances are we'll be able to use it.
- The learning curve to use Emmet is incredibly low.
- Emmet does not depend on the use of the command line.
- Emmet has great documentation and it's in constant development.
You can download Emmet from http://emmet.io/.
Using a third-party application
As we have seen, the previous methods for automating vendor prefixing are all over the place, from methods that are used via the command line and methods that make you find a specific module to import before being able to use to JavaScript solutions.
The most important of all the features mentioned is that Autoprefixer uses the CanIUse.com database. This is pretty much what we want to use, since all we need to do is write the CSS3 properties and values and forget about vendor prefixing altogether, leaving it to Autoprefixer and CanIUse.com to add them for us.
Fortunately, there are third-party applications out there that already come with Autoprefixer installed. This means we don't have to set anything via the command line, or install a plugin, or anything like that. Just install the app, activate the Autoprefixer checkbox, and off we go!
We mentioned several applications before: CodeKit, Prepros, and the Koala app. They all do basically the same things, but they excel in two things:
- They can watch our SCSS files and compile them for us.
- They can automatically add vendor prefixes via Autoprefixer.
These two features have a huge impact on our workflow, allowing us to focus our energies on the important stuff, such as RWD and a better user experience.
However, there are a few things to consider before deciding if a third-party application is the best solution for vendor prefixing:
- Prepros and CodeKit are paid apps. Koala is free but supporting the author with a small donation shows appreciation for his work. However, they are not expensive by any means; the benefits are worth tens of times over when we compile a file for the first time.
- They are extremely easy to set up.
- They have great documentation, communities and are in constant development by the authors.
- For many non-frontend developers who work with CSS and HTML, these applications allow them to focus on other important things such as user experience, design, usability, and SEO—without worrying about JSON files, command line, plugins, and so on.
The recommended vendor prefixing method
This book recommends that you use CodeKit, Prepros, or Koala apps to deal with vendor prefixes. These applications not only compile the SCSS files, but also automatically run them through Autoprefixer when saving those SCSS files.
So let's take a look at Prepros, which can run on the most popular operating systems such as Windows, Linux, and Mac.
Using a third-party program to compile
Using the command line to compile our SCSS files is really not that difficult:
That's all we need to do in the command line to have Sass watch over the SCSS files in the /scss
folder and compile them into the /css
folder. It really is that simple.
The problem with the previous situation is that we need to run this command every single time we have to work on a different project. Although we can automate this in many different ways, some find the use of the command line either daunting or just unnecessary.
Prepros is a tool for web designers and developers that deals with many parts of a regular workflow: compiling, CSS prefixing, live refresh, JavaScript concatenation, file minification, optimizing images, browser testing synchronization, source maps creation for compiled files, built-in server, FTP, and so on.
For the scope of this book, we're going to focus on how it can help us compile our SCSS files while adding vendor prefixes automatically.
You can download it from https://prepros.io/. Prepros is a paid application. However, spending $29 is not going to break the bank. I assure you that right after the first compilation, this app will have paid itself.
There is also a way to use Prepros for free and enjoy all the features of the app. However, this comes at the expense of having to keep closing the buy the app pop-up window about every 5 minutes.
This is the current welcome screen of Prepros (it may have changed by now):
Remember the steps in the installation of Sass where we created a /Demo
folder and created two subfolders, /scss
and /css
, within it? We are going to drag and drop the /Demo
folder onto the Prepros interface:
A sad face appears, letting us know that the project is empty. This is true since we haven't added any files to the /scss
folder:
So, let's create a .scss
file in the /scss
folder:
Prepros will automatically detect the new styles.scss
file and compile it to create the styles.css
file, which is saved in the /css
folder.
Clicking on the styles.scss
file will bring out the file's default settings:
Let's modify some of these settings so Prepros can automatically perform the following operations:
- Add vendor prefixes.
- Create source maps.
- Not compress our compiled CSS (at least yet).
Tip
The source map
is a file with the .map
extension that gets generated together with our CSS file. This map file contains the necessary information that links each line of our CSS file to their corresponding line in our SCSS files and partials. This is crucial when we need to inspect the styles of an element via the DevTools of any modern web browser.
In the OUTPUT STYLE section, we're going to leave the setting as Expanded.
The differences between the four styles of output are simple:
This is the traditional CSS styling where each selector, property, and value is in a separate line:
You can see that the second rule is indented, which means it belongs to the header
selector:
All rules reside in a single line, as shown here:
This is the minified version, which is the version we should use in production:
That's it. We now leave Prepros running. It will add all vendor prefixes and compile the SCSS files every time we save it. Let's see this in action.
Add some CSS and let the Prepros app do the rest!
Every time we hit Save, Prepros will show either one of the following dialog boxes at the bottom-right corner of our screen.
Success will give us the following output:
Error will give us the following output:
Let's take our styles.scss
file and let's add a simple CSS rule that requires some vendor prefixing.
When we save the styles.scss
file, Prepros shows the green/success dialog box and compiles our SCSS file to styles.css
.
This is what the compiled file looks like with all the prefixes added automatically:
Defining how many legacy browser versions to support for prefixing
As browsers evolve, CSS3 properties and values are standardized and less of them require vendor prefixing. Our CSS files should reflect that so we don't fill our style sheets with unnecessary prefixes.
Prepros allows us to define how many legacy browser versions we want to support when applying prefixes. The steps are as follows:
- Click on the MORE OPTIONS menu at the top:
- Click on Project Options from the drop-down menu:
- Click on the CSS menu option:
- Scroll all the way to the bottom and type the number
2
in the AutoPrefixer field: - Once this is done, save the
styles.scss
file. We'll see that the CSS3 linear gradient property doesn't really need to be prefixed after Prepros compiles the CSS file:
Tip
If you are not able to see the linear gradient property prefixed in the beginning, try changing the value to something very high, such as 40
so that it reads last 40 versions. Save your SCSS document and check your CSS file again.
That's all there is to it.
One very important note before we continue. So far, we've talked about using the command line via the --watch
flag and using Prepros to compile our SCSS files. Note that only one compiler needs to run at any given time. Having both the CMD and Prepros compiling the same SCSS file is not necessary.
Sass mixins to house our media queries
There are many ways to create a Sass mixin to house media queries: mixins with variables only, mixins with the No Queries fallback for older browsers that don't support media queries, and plugins (for Compass) such as Breakpoint. There are other techniques too, such as Named Media Queries. Another technique is a simple three-line mixin that will work for anything we want.
They're all fine and very powerful. However, for the scope of this book, we're going to focus on two simple methods that will allow us to be efficient, keep things simple, and harness the power of mixins.
All that you have learned about Sass so far, especially the part about mixins, culminates in the creation of a partial file that will house our media queries for RWD.
Remember that partial files are SCSS files we create to house SCSS snippets. Their file name starts with an underscore symbol and ends with the .scss
extension.
Media queries mixin methods
There are as many methods to name media queries and breakpoints as there are web designers and frontend developers. Everyone has their own way and style.
Regardless of the method you use, the important thing is to start using a Sass mixin to automate this process. As we build sites or apps and become better web designers / frontend developers, we'll find that other solutions may work better.
There are several ways to name your media queries mixins:
- Let the content define the breakpoints. In other words, when you resize your browser window during testing and you see that the content breaks or doesn't display in an ideal, legible way—bam! create a breakpoint (this is the recommended method).
- Name media queries using abstract names such as
small
, medium
, and large
, or s
, m
, and l
. - Use device-specific names (I do not recommend this method).
In this book we're going to focus only on the first and second methods mentioned in preceding list.
Let the content define the breakpoints
Since we don't know where our content is going to break and we need an initial mixin that we can add values to as we build our responsive site/app, we're going to start with a few known, width-specific values. Understand that these values may very well change and many other values will be added to this mixin.
We're going to name this file _mediaqueries.scss
. The media queries mixin looks like this:
This is how we use the mixin in our main SCSS file:
This is what the mixin compiles to:
In the media queries examples of this book, we're going to declare the width values in em
units rather than pixels. This is because using em
helps scale all values better, independent of the screen densities. Let's see what's happening here.
First, we see the Sass-style comment describing that this mixin is for a mobile-first approach:
Then, we have the opening @mixin
directive. This directive contains the name of the mixin, minw
, which is the abbreviation of minimum-width. We're going to keep this name simple because we're going to type it a lot, so it's faster to type minw
than minimum-width while still maintaining a meaningful term.
In parenthesis, we have the ($point)
argument that will store the value we specify when defining which breakpoint we're going to be using:
Then, we have an opening @if
statement. Remember we said that Sass was a programming/scripting language? What best represents a programming language than if-else
statements?
The @if
statement is followed by the $point
variable that equals (==
) 320 pixels width. The two equals signs (==
) mean that it is absolutely equal to the value, that is, 320
:
After that, we have the CSS @media
directive that we've seen many times before. Within this directive, we specify the width in em
, in this first case, 20em
.
Then, we have the @content
directive that allows us to put any content in between the brackets:
This is followed by the @else
statement with the $point
variable, the two equals (==
) signs, and the value of 640
. If the defined value is 640
instead of 320
, then the mixin can go ahead and use this specific media query for 640 pixels width.
This means that 640 pixels is 40em
:
Finally, we have the same media query structure for 768 pixels width. 768 pixels is the same as 47.5em
.
Consider the following points before choosing the method of letting content define the breakpoints:
- The great thing about using specific width values (remember, these values are content-based) as media queries names (320, 640, or 768) is that when we use the mixin, we truly know what specific width we're targeting.
- This means that no matter how many breakpoints we have, we will always know which width we're targeting.
- We can have as many breakpoints as we need, and we'll never have to go back to the mixin to remind us which name belongs to which width.
This is the favorite of many frontend developers. This mixin is almost the same as the one we just saw; the difference is that instead of using specific widths and knowing that those widths will change and others will be added, this mixin uses abstract names for device-specific widths and usually there's an already defined list of breakpoints.
Here's what this mixin looks like:
This is how we use it:
And this is how it looks compiled:
Consider the following points before choosing the Named Media Queries method:
- The use of abstract names can be confusing if you have many breakpoints.
- At some point, you're either going to run out of abstract names, or have so many of them that you can't really remember which name belongs to which width.
This is the recommended mixin to use when working with media queries, and it has the following advantages:
- It allows us to keep thinking in pixels when defining our widths, but the output is in relative units (
em
). - It's quite simple to understand and to scale.
- If we're using the desktop-first approach, all we need to do is change the mixin name from
mobileFirst
to desktopFirst
, and change the min-width
keyword to max-width
. - If we want to use pixel-based width, we just need to remove
16
from the division: /16+em
. - Since it doesn't use named variables to represent different widths, there is no need to remember which named variable corresponds to which width.
- We'll never run out of named variables since it doesn't use them.
Now, considering that our recommendation is to let the content define the breakpoints, here's the mixin:
That's it—a mere three-line mixin. This is how we use it:
This is what it compiles to:
Now, you might be asking yourselves, "where did the em
values come from?"
It's simple. We divide the desired width by 16. The reason we're dividing by 16 is because 16px
is the default font size of all browsers. By doing this, we get our values in em
units.
Consider the following examples if you want to use 16px
as your default font size:
- 320px/16px = 20em
- 640px/16px = 40em
- 768px/16px = 47.5em
If you decide that your default font size is not going to be 16px
but rather 18px
, then the same process applies. Divide the desired width by 18px
:
- 320px/18px = 17.77em
- 640px/18px = 35.55em
- 768px/18px = 42.66em
The choice is yours.
Tip
All our examples are going to be based on a 16px
default font size.