Introduction
This is a quick and dirty introduction to Sass and responsive design. You should be able to work through it in 20 minutes, one lunch hour.
As is the usual convention, any line starting with $ can be typed at a (Bash) shell command line. Monospace font is used for listings, or anything that appears on the screen.
I'm assuming you have sass and bower already installed on your system, if not, consult the internets.
Let's Get Started
If you aren't using a framework like Rails, AngularJS etc. (more about this in another post) you will start off by creating your project directory from the Bash prompt:
$ mkdir sass
$ cd sass
Next use a text editor like gedit to create an empty HTML5 template looking like this:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Blank HTML5 template</title>
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
Hello, World!
</body>
</html>
Check this displays as expected in a browser (blank page except for the words 'Hello, World!').
Before going any further, I want to associate bootstrap with the project:
$ bower install bootstrap
Food for thought. Look at the other related packages you might be able to use in the future:
$ bower search bootstrap
I'm not going to create a bower.json file or do any fancy git grunt stuff right now. If I was going to I would have used 'bower init'.
The first thing I wanted to do was create a Sass stylesheet. ALL my styling will be done in one file called ms.scss, which starts off looking like this:
/* Original file: ms.scss */
$primary-color: #333;
body {
color: $primary-color;
}
h1 {
font-size: 250%;
}
h2 {
font-size: 200%;
font-style: italic;
text-align: right;
}
p {
font-size: 100%;
}
There really isn't much to it at the moment. This file will be compiled into ms.css by entering the following command at the shell prompt:
$ sass --watch ms.scss:ms.css
This tells the compiler to compile it, but also keep watching the file for changes. Whenever a change is detected, it triggers a recompile. If you inspect the generated .css, you should see it looks pretty much the same as the .scss file, except for the body color.
Finally I can add a reference to my new stylesheet into the web page in the header section AFTER the reference to bootstrap. Why after? So this .css file overrides the bootstrap .css file if there are any conflicts (try it the other way around):
<link rel="stylesheet" href="./ms.css" />
Hopefully this displays a simple web page.
...cup of tea...
The other thing I wanted to do was use Bootstrap to make a responsive layout.
We are NOT doing table-based layout here, but in HTML tables are written out by rows and the concept of a column doesn't really exist. He (TBL) could have defined tables as a group of columns he couldn't do both at the same time so he made a decision: rows. Hold that thought for a paragraph.
The key thing about Bootstrap CSS (possibly the only thing) is there are nested divs: a container-fluid contains a row, and each row contains some divs (which appear as columns) with widths adding up to 12. The accumulated width of the columns in a row must always add up to 12 or it won't work.
See these pages for a description of the Bootstrap layout:
http://getbootstrap.com/css/#grid-example-basic
https://scotch.io/tutorials/understanding-the-bootstrap-3-grid-system
As the screen width shrinks (or if the page is viewed on a device with a different screen size) instead of displaying a scroll bar, the screen will re-organise itself and the content will re-flow so that 'column 2' appears underneath 'column 1'. If you are clever, you can organise the columns so that the content reflows in different ways for different devices.
1. in the head region, next to the other meta tag:
<meta name="viewport" content="width=device-width, initial-scale=1">
2. after the title:
<link rel="stylesheet" href="./bower_components/bootstrap/dist/css/bootstrap.css"/>
3. here's the new body, replacing the 'Hello, World!' message:
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
...
</div>
<div class="col-sm-6">
...
</div>
</div>
</div>
I'm keeping it very simple here.
Now we have the STRUCTURE, we can add the actual CONTENT:
Super important: the structure part MUST NOT CHANGE, but you can muck around with the content 'till the cows come home. This is where all beginners stuff up. There is no indication of which bit is structure and which bit is content if you don't know what you're looking at. The reason I call the bit above this paragraph 'STRUCTURE' is because it controls the Bootstrap 3 responsive layout, but doesn't actually display anything on the screen; the reason I call the bit immediately below this paragraph 'CONTENT' is because it is all plain, old HTML5, semantically structured, and visible in the browser.
The first ellipsis can be replaced with this:
<h1>Never give in</h1>
<p>“Never give in. Never give in. <br>
Never, never, never, never — in nothing, great or small, large or petty — never give in, <br>
except to convictions of honour and good sense. <br>
Never yield to force. <br>
Never yield to the apparently overwhelming might of the enemy.” </p>
<h2>― Winston S. Churchill</h2>
The second ellipsis can be replaced with this:
<h1>We shall fight them on the beaches</h1>
<p>“We shall go on to the end. <br>
We shall fight in France, we shall fight on the seas and oceans, <br>
we shall fight with growing confidence and growing strength in the air, <br>
we shall defend our island, whatever the cost may be. <br>
We shall fight on the beaches, we shall fight on the landing grounds, <br>
we shall fight in the fields and in the streets, we shall fight in the hills; <br>
we shall never surrender.</p>
<h2>― Winston S. Churchill</h2>
If the screen is wide enough to display it, you should see both quotes side-by-side.
Finally, I wanted to make the initial quote symbol much bigger. This is where your basic HTML and CSS capability becomes a bit intermediate IMHO.
First, the styling is only to be applied to the quote mark, so it has to be wrapped in a span tag so it has its own HTML element. Naturally the tag is going to have a class so we can refer to it directly instead of something perverted like p + span and so it is reusable (we don't really reuse it). Change both quotes like this:
<p><span class="qbox">“</span>We shall go on to the end. <br>
Then you can muck around with the styling by right-clicking on the quote and selecting inspect element, then applying element.styles directly until it looks like you want it to. Finally copy your style from the browser to the Sass style sheet. I settled for this:
.qbox {
font-size: 360%;
}
Add this to the .scss file and re-display the page. Notice how the qbox span mucks up the line height.
To get the "hanging left indent" you need to know what it's called so you can Google it. I first came across the term in 2004 when I read a book called
Designing With Web Standards By Jeffery Zeldman. This page contains what I'm looking for: http://www.thesitewizard.com/css/hanging-indents.shtml
So after a bit more mucking around I've got this HTML:
<p class="hangingindent"><span class="qbox">“</span>We shall go on to the end. <br>
and this SCSS:
.hangingindent {
padding-left: 26px;
text-indent: -22px;
line-height: 25px;
}
Finally (advanced CSS?) we do not use pixels to define the size, because it will look alright on one device and the layout will be a bit stuffed up on other devices, so you fix the layout on the second device only to find you have stuffed it up on the first etc. etc. In 2015 we use REMS to talk about size, and this is a multiple of the base font size. Note that it is normally 16px, but Bootstrap sets it to 10px - I don't know why. Perhaps to make it easier to convert px to rems?
Which has the Sass function called "calculateRem". Drop that function into ms.scss and change 20px values to calculateRem(20px).
THAT'S IT!
My final Sass is:
/* Original file: ms.scss */
$primary-color: #333;
@function calculateRem($size) {
$remSize: $size / 10px; /* changed from 16px */
@return #{$remSize}rem;
}
body {
font-family: 'EB Garamond';
color: $primary-color;
}
h1 {
font-family: 'Tangerine', serif;
font-size: 250%;
}
h2 {
font-size: 200%;
font-style: italic;
text-align: right;
}
p {
font-size: 100%;
}
.qbox {
font-size: 360%;
}
.hangingindent {
padding-left: calculateRem(26px);
text-indent: calculateRem(-22px);
line-height: calculateRem(25px);
}
body > div > div > div:nth-child(1) { /* column 1 */
background-color: aliceblue;
}
body > div > div > div:nth-child(2) { /* column 2 */
background-color: beige;
}
which compiles to:
/* Original file: ms.scss */
body {
font-family: 'EB Garamond';
color: #333; }
h1 {
font-family: 'Tangerine', serif;
font-size: 250%; }
h2 {
font-size: 200%;
font-style: italic;
text-align: right; }
p {
font-size: 100%; }
.qbox {
font-size: 360%; }
.hangingindent {
padding-left: 2.6rem;
text-indent: -2.2rem;
line-height: 2.5rem; }
body > div > div > div:nth-child(1) { /* column 1 */
background-color: aliceblue; }
body > div > div > div:nth-child(2) { /* column 2 */
background-color: beige; }
/*# sourceMappingURL=ms.css.map */
And my responsive HTML is now:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>How to create a responsive web page using Bootstrap 3 and Sass</title>
<link rel="stylesheet" href="./bower_components/bootstrap/dist/css/bootstrap.css"/>
<link rel="stylesheet" href="./ms.css" />
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine">
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=EB+Garamond" /> <!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<h1>Never give in</h1>
<p class="hangingindent"><span class="qbox">“</span>Never give in. Never give in. <br>
Never, never, never, never — in nothing, great or small, large or petty — never give in, <br>
except to convictions of honour and good sense. <br>
Never yield to force. <br>
Never yield to the apparently overwhelming might of the enemy.” </p>
<h2>― Winston S. Churchill</h2>
</div>
<div class="col-sm-6">
<h1>We shall fight them on the beaches</h1>
<p class="hangingindent"><span class="qbox">“</span>We shall go on to the end. <br>
We shall fight in France, we shall fight on the seas and oceans, <br>
we shall fight with growing confidence and growing strength in the air, <br>
we shall defend our island, whatever the cost may be. <br>
We shall fight on the beaches, we shall fight on the landing grounds, <br>
we shall fight in the fields and in the streets, we shall fight in the hills; <br>
we shall never surrender.</p>
<h2>― Winston S. Churchill</h2>
</div>
</div>
</div>
</body>
</html>
Try re-sizing the browser window when the page is displayed and confirm that the divs are displayed side-by-side when the display width is greater than sm-6 pixels and, when the width drops below sm-6 px, the screen re-arranges to display one quote above the other.
Inspect an element and notice how the link to the style points to the file ms.scss. Note that, if you click on that link, the browser displays the source file scss, not the compiled css file. This is because of the ms.css.map file created by the Sass compiler. You really need this if, when maintaining the web page, you want to change anything affected by ms.css, for example the body font color.
Hope this gives you a quick and dirty introduction. Thanks for reading.