Setting up our project
You're probably eager to start writing some Sass, so let's jump right in. I'm going to create my project in my root (C:/
) directory, but you can place your project wherever is easiest for you. I'll call it mastering-sass and inside I'll create the following files and folders in that folder: sass and index.html and within the sass folder create a file: style.scss.
Open your index.html file in your editor of choice and add the following markup:
<!-- mastering-sass/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Mastering Sass: Chapter 2</title> <link href="css/style.css" rel="stylesheet"> </head> <body> <div> <h1>Heading 1</h1> <h2>Heading 2</h2> <h3>Heading 3</h3> <h4>Heading 4</h4> <h5>Heading 5</h5> <h6>Heading 6</h6> <p>This is a normal paragraph of text with <em>emphasised</em>, <strong>strong</strong> text and, of course, a <a href="#">link.</a></p> <p> <img src="http://placehold.it/300x200" alt="Image from Placehold.it" style="float:left;"> !!!ENTER SOME LOREM IPSUM OR SOMETHING HERE!!!</p> <p><img src="http://placehold.it/800x600" alt="Image from Placehold.it" style="float:right;"> !!!ENTER SOME LOREM IPSUM OR SOMETHING HERE!!!</p> <ul> <li>List Item 1</li> <li>List Item 2</li> <li>List Item 3</li> <li>List Item 4</li> </ul> </div> </body> </html>
Believe it or not, this simple page has pretty much all the elements you need to make a fully functional HTML website (as it was originally intended). Not counting the stuff in the <head>
or the <body>
tag, there's roughly 15 elements present in almost every webpage since the dawn of web time (circa.1991)
, and you're looking at them.
From these elements you can make navigation, break things into sections (with more divs of course) and get pretty much any message across to a reader that text and images will allow.
Sass
You noticed the link to the stylesheet located at css/style.css. You also surely noticed we never created that. Let's open up our command line and change directory to our mastering-sass folder.
Now in your command line simply run the following command:
sass --watch sass:css
This command will tell sass
to compile all sass
files in the sass
directory into css
files in the css
directory. If the folder or the files don't exist sass
creates them. Once it's finished it will watch the sass
directory for any changes and automatically compile them to the css
directory. The command line should look something like the following screenshot:
Note
If you're wondering what the style.css.map
file is all about, don't worry, we'll cover that in Chapter 7, Sourcemaps – Editing and Saving in the Browser.
So now open style.scss and we'll begin writing some Sass to style our typography. In style.scss let's set our box model and remove the padding and margins first:
// mastering-sass/ch02/scss/style.css *, *::before, *::after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing:border-box; } html { font-family: serif; font-size: 100%; -webkit-font-smoothing: antialiased; } html, body { padding:0; margin:0; }
Next, we'll use our div
to center everything and give it a reasonable width for reading text. It's said that between 55 to 75 characters per line is optimal for reading so let's set our divs max-width
, because we still want it to be able shrink down for smaller screens (right now we're not worrying about mobile-first or anything like that):
// path: mastering-sass/scss/style.scss body > div { // We only want to get the "wrapper" div max-width: 38rem; // approx 600px margin: 0 auto; }
There's method to my madness. In fact, that first line actually has 65 characters exactly, and the image is 600px
wide. Between the end of that sentence and the images is optimal line length, depending on the font. For me, serif looks too small at 1rem (or em). Sans-serif works much better at the default size of 1rem (16px). So let's set the font family on our paragraphs to sans-serif and set up our line heights and margins:
// mastering-sass/ch02/scss/style.scss p { font-family: sans-serif; font-size: 1rem; line-height: 1.5rem; margin-bottom: 1.5rem; }
C'mon, where's the Sass already?!
Ok! Ok! We're finally ready to writing some Sass. We actually have two perfect reasons to start using Sass here.
We have some repeated values: both line height and margin bottom are 1.5rem.
Couldn't we write a mixin to deal with the issues of serif being too small at 1rem while sans-serif is just about right?
So let's create our variables at the top of our style.scss which we'll use to correct these common issues:
// mastering-sass/ch02/scss/style.scss $base-font-family-sans: sans-serif; // 1. $base-font-family-serif: serif; // 2. $base-font-family-code: monospace; // 2. $base-font-size: 1rem; $base-line-height: 1.5; $base-font-family: $base-font-family-code;
Then let's replace the values in our paragraph rule:
// mastering-sass/ch02/scss/style.scss p { font-family: $base-font-family-sans; font-size: $base-font-size; line-height: $base-line-height; margin-bottom: $base-line-height + rem; }
Now we can actually write a mixin that will check our current font-family and adjust all of our values accordingly, so we always have the best line length and spacing for our current font.
Let's create a separate folder inside our sass folder, called helpers
, and inside that we'll create a file called _mixins.scss.
Inside that file create the following mixin
:
// mastering-sass/ch02/scss/helpers/_mixins.scss @mixin base-font-family-sizing() { // 1. // Check what $base-font-family we are using... // If $base-font-family-serif we need to multiply // our $base-font-size by 1.25 and increase // our $base-line-height accordingly // 2. // Otherwise, a font-family we haven't set // specific values for has been set so we // should leave the browser defaults in place. }
Don't forget to include it at the beginning of our style.scss file following our variables also:
// mastering-sass/ch02/scss/style.scss $base-font-family-sans: sans-serif; // 1. $base-font-family-serif: serif; // 2. $base-font-family-code: monospace; // 2. $base-font-size: 1rem; $base-line-height: 1.5; $base-font-family: $base-font-family-code; @import "helpers/mixins";
So I've explained the steps on how we need to tackle this problem in the comments. So let's write a quick if
/elseif
/else
and output some content to see if our logic is correct before adding anything more complex:
// mastering-sass/ch02/scss/helpers/_mixins.scss @mixin base-font-family-sizing($current-font-family: $base-font-family) { @if $current-font-family == $base-font-family-serif { // 1 content: 'Serif'; } @else { // 2. If $base-font-family-code you should see... content: 'Not serif'; } }
Now, place our mixin inside our paragraph rule, like so:
// mastering-sass/ch02/scss/style.scss
p {
font-family: sans-serif;
font-size: $base-font-size;
line-height: $base-line-height;
margin-bottom: $base-line-height + rem; // Add our rem unit to make it 1.5rem
@include base-font-family-sizing();
}
Seeing as $base-font-family
is actually set to $base-font-family-code
, you should see the following in your style.css:
// mastering-sass/ch02/scss/style.scss p { font-family: sans-serif; font-size: 1rem; line-height: 1.5; margin-bottom: 1.5rem; content: 'Not serif'; }
Now, replace
$base-font-family: $base-font-family-code
with
$base-font-family: $base-font-family-serif
and you should see the following:
// mastering-sass/ch02/scss/style.scss p { font-family: sans-serif; font-size: 1rem; line-height: 1.5; margin-bottom: 1.5rem; content: 'Serif'; }
For good measure, also check $base-font-family-sans
. Do you get content:'Not Serif'
?
Great! It works! Now we can start adding the stuff we actually want into the @if
/@elseif
/@else
blocks.
So, modify the font-family-sizing mixin as follows:
// mastering-sass/ch02/scss/helpers/_mixins.scss @mixin base-font-family-sizing($current-font-family: $base-font-family) { font-family: $current-font-family; line-height: $base-line-height; margin-bottom: $base-font-size * $base-line-height; @if $current-font-family == $base-font-family-serif { font-size: $base-font-size * 1.15; } @else { font-size: $base-font-size; } }
Multiplying or adding a value with units such as 1rem * 1.5 will result in 1.5rem...the units are kept.
So that's a mixin that uses just a few of the basic features of Sass. Variables and mixins are pretty much what everyone utilizes in the beginning, not to mention nesting. Getting predictable results from your if statements can be tricky if you don't write them in a way that you can be sure they're working at every step of the process. It's easy to accidentally check for a false value when you meant true and throw an entire system into mayhem.
The key to coding anything, no matter how simple the problem seems, is to get feedback straight away from your code so you know the minute anything is wrong. Check the values you're getting back as early as possible. Otherwise, if you go too far without checking your results to see something isn't right, it can be near impossible to figure out what actually went wrong, and when it went wrong.
Using the CSS content
property is a handy way of checking values so Sass won't through compilation errors due to incorrect types and values. There are other ways to debug your Sass, and we'll look at that method soon. However, output values to the content property can be useful while figuring mixins or functions out.
So now you have a simple mixin that will keep your line lengths in check between the main two font families, sans and serif. You only need to change the $base-font-family
variable and everywhere this mixin is used it will update correctly. No more small text in a box scenarios.