Master CSS
Master CSS
Ryan Boddy
COPYRIGHT PAGE
Although the author and publisher have made every effort to ensure that the
information in this book was correct at press time, the author and publisher
do not assume and hereby disclaim any liability to any party for any loss,
damage, or disruption caused by errors or omissions, whether such errors or
omissions result from negligence, accident, or any other cause.
Neither the author nor the publisher assumes any responsibility or liability
whatsoever on behalf of the consumer or reader of this material. Any
perceived slight of any individual or organization is purely unintentional.
The resources in this book are provided for informational purposes only and
should not be used to replace the specialized training and professional
judgment of a health care or mental health care professional.
Neither the author nor the publisher can be held responsible for the use of
the information provided within this book. Please always consult a trained
professional before making any decision regarding treatment of yourself or
others.
This template is free to you and does not require attribution! You can
use it as many times as you’d like, in perpetuity. You can use it for
marketing material, or you can simply examine the files to see how concepts
from this book are applied in a practical way.
I stand by the idea that the web should be a beautiful place, which is
why I wrote this book! I hope this template helps you in pursuit of that
same goal!
To Download visit:
https://conquercss.com/free
z
DEDICATION
This book is dedicated to my wonderful wife, Baylee. I could not have
achieved my dream of completing my first book without her belief in me.
Time after time, I’ve presented her with idea after idea that would become
my next big project and she has dived in with me each time. This book was
different for me but no different for her. She was by my side out of the gate,
just like with every other crazy idea I’ve come up with. I knew that I was
going to finish what I started with this book, but she kept me going when I
felt like giving up.
Chapter 1
A Brief History of CSS ............................................................................................. 2
Chapter 2
CSS Syntax .................................................................................................................. 4
Selectors ........................................................................................................................................ 7
Properties .................................................................................................................................. 14
Specificity ................................................................................................................................... 15
Chapter 3
CSS Organizational Methods .............................................................................. 22
Stylesheets ................................................................................................................................. 22
Comments .................................................................................................................................. 26
Organizational Patterns ..................................................................................................... 28
There Is No Right Answer ................................................................................................... 36
Chapter 4
The Box Model ........................................................................................................ 37
Margin ......................................................................................................................................... 38
Padding ....................................................................................................................................... 41
Border.......................................................................................................................................... 43
Content........................................................................................................................................ 46
The Secret Fifth Category? ................................................................................................. 46
Chapter 5
Responsive CSS ....................................................................................................... 51
Responsive Units ..................................................................................................................... 51
Media Queries .......................................................................................................................... 60
Mobile Considerations.......................................................................................................... 62
Responsive Design Can Be Even Simpler ..................................................................... 65
Chapter 6
Flexbox and Grid ................................................................................................... 66
Flexbox ........................................................................................................................................ 66
Grid ............................................................................................................................................... 74
Chapter 7
CSS Frameworks.................................................................................................... 82
Advantages ............................................................................................................................... 82
Disadvantages ......................................................................................................................... 83
Bootstrap ................................................................................................................................... 84
Material Design ...................................................................................................................... 85
Foundation................................................................................................................................ 86
Tailwind CSS............................................................................................................................. 87
Wrapping Up ............................................................................................................................ 88
CHAPTER 8
Preprocessors and Postprocessors ................................................................. 89
SASS/SCSS ................................................................................................................................. 89
LESS.............................................................................................................................................. 92
Postprocessors ......................................................................................................................... 93
Pleeease ...................................................................................................................................... 93
PostCSS ....................................................................................................................................... 94
CHAPTER 9
This Is Only the Beginning ................................................................................. 96
If the web is our canvas, then the code we write is the paint. The
problem is that not all “paint” is created equal—and some is downright
wacky. Cascading Style Sheets (CSS) is some of the wackiest there is, and this
is not lost on most web developers. I often scroll through Twitter and find
sentiments from other web developers about their love-hate relationship with
the language. When it works, it’s a delight to see your design come to life.
When you are a beginner and you have to center a div, it becomes a seemingly
impossible task.
These feelings of disdain toward CSS are what drove me to start writing
this book. I have been writing CSS for over 10 years now, and I have always
enjoyed growing this skill. I want to share this knowledge with other web
developers. I want to show them that CSS doesn’t have to be scary. Even the
most technical backend developers can pick up CSS and create beautiful,
responsive web pages and apps. This is not a magic skill that people are born
with, despite the CSS wizards we all look up to.
—Ryan Boddy
1
CHAPTER 1
I
n the beginning, there was nothing. Then, in 1993, Tim Berners-Lee gifted
the world with HyperText Markup Language (HTML). This birthed the
modern web as we know it. While HTML allowed developers to structure
web pages, styling options were incredibly limited. As the artists of the web,
developers were painting in black and white, which couldn’t be blended to
create gray. Information could be displayed on a web page, but the
information wasn’t any fun to look at.
Even scientists and researchers want a little bit of flair when they’re
getting their information. Shortly after the release of HTML, several
proposals were floated to create “stylesheets” that would define how HTML
would look. One such proposal was for a stylesheet language called Cascading
Style Sheets by Håkon Wium Lie. The World Wide Web Consortium (W3C)
combined this proposal with others to create the first public release of their
CSS recommendation, or endorsement and set of instructions for CSS, in
1996. HTML has been in its fifth major version since 2014. As HTML grew,
CSS grew alongside it. The latest and greatest CSS version is CSS 3, which
was introduced in 2011. Here is a graphic showing the timeline of CSS over
the years:
2
Conquer CSS
3
CHAPTER 2
CSS Syntax
C
SS is unique among web languages. It’s not a full-fledged programming
language because it doesn’t have many logic features. It’s not a markup
language like HTML or XML because it doesn’t (for the most part)
determine what content is displayed. CSS is a stylesheet language. It is used
for styling. There are options for it to perform some logic, and there are
options to use it to set content, but these are not the primary purposes of
CSS.
We can’t start writing CSS without having a little bit of content to style.
Let’s start with some basic HTML that will allow us to see our changes. Here
we have some simple HTML for a Header 1.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<title>Conquering CSS</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
4
Conquer CSS
Alright. This is absurdly boring to look at. We have a heading with a very
plain font, black lettering, and no text decoration. Let’s throw some CSS on
it and see what we can do. The following CSS will transform our heading to
make it look less bland. Add a <style> tag to your header in your HTML,
along with the CSS inside like so:
<style>
h1 {
color: #002699;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
</style>
Maybe not the best design in the world, but it is much more appealing
to look at. Now, let’s break down exactly what our CSS is doing.
5
Ryan Boddy
Let’s start with the <style> tag. The style tag is an HTML tag that allows
us to write CSS directly in our HTML document. I am using it here to show
the example CSS, but it won’t always be our method of injecting CSS into our
HTML (more on this later). For now, if you want to experiment with CSS as
a total beginner with minimal HTML knowledge, you can use the style tag
to write your code.
You might be wondering, “What about the rest of the code?” We won’t
get into what each property is doing here, but let’s get familiar with the syntax.
Here is a diagram that shows the biology of a CSS rule, which is a grouping
of CSS properties for the purpose of being applied to certain HTML
elements:
6
Conquer CSS
Selectors
Let’s take another look at the code:
h1 {
color: #002699;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
But what happens if I put another <h1> tag on the page? Let’s find out:
Adding another h1 gives us a header with the exact same styling since
we’re targeting all h1s. This is a handy way of styling all the elements on a
page that have the same tag.
7
Ryan Boddy
But what if we only want to style the first h1? Well, we have a few options
when it comes to selectors that we can use to do that. Let’s change our code
a little bit and introduce the first way:
<h1>Another H1</h1>
<style>
.header {
color: #002699;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
</style>
So, what’s happening here that allows us to only style the first header
tag? We have just created a class. In CSS, classes are custom selectors that
8
Conquer CSS
allow developers to choose styling for whichever elements get assigned that
class. You can see here that we have assigned the class to our first <h1> tag
by giving it an HTML attribute of class followed by the same name we put in
our CSS. To create a class, simply put a dot (.) in front of the class name in
your CSS selector, and then use class=“className” with className being the
class name you chose without the dot. You can include multiple classes if
you’d like the element to get styling from multiple CSS rules. Just ensure that
your classes are separated by a space in your class attribute.
There is another method of selecting only one element per page, and
that’s by setting an ID. Let’s look at the following code:
<h1>Another H1</h1>
<style>
#header {
color: #002699;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
</style>
The code above will have the exact same output as the class, but instead
of using a class, we use the id HTML attribute to assign our style. IDs are
delineated in CSS by putting a # (pound, hashtag, number) symbol in front
of our ID name. IDs should be unique for each element on the page and
shouldn’t be repeated. This means that it’s okay to use IDs to style one
element on the page but no more than one. In the instance where you need
to style a set of elements, you should create a class. Furthermore, classes also
9
Ryan Boddy
work for single elements, so it’s common practice not to use IDs at all in your
CSS and stick to classes.
You can also chain selectors together to get more and more specific with
your selections. Let’s say that you have a paragraph with a class, and within
that paragraph, there is an anchor tag—the text designating the start and end
of a hypertext link—and you want to target that particular anchor tag. Here’s
an example of how we can do that. Consider the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<title>Conquering CSS</title>
</head>
<body>
<p class="red-paragraph">
This is a red paragraph. But I want my
anchor tags to be green. Like <a href="/">this
one!</a>
</p>
<style>
.red-paragraph {
color: red;
}
.red-paragraph > a {
color: green;
}
</style>
</body>
</html>
10
Conquer CSS
Here you can see that by using the greater-than sign, or right carrot sign,
you can chain together selectors to target elements that are subelements of
other elements. This symbol is called the child combinator. It only works if
you have chained together selectors that have a parent-child relationship. So,
if I were to change the code to look like this:
<div>
<p class="red-paragraph">
This is a red paragraph. But I want
my anchor tags to be green. Like <a href="/">this
one!</a>
</p>
</div>
<style>
div {
color: red;
}
div > a {
color: green;
}
</style>
11
Ryan Boddy
What if you want to apply the same CSS styling to multiple selectors?
That’s pretty simple in CSS. All you need to do is comma separate your
selectors before your CSS rule. For example, if you want to apply the color
red to all your paragraphs and anchor tags, you can do the following:
p, a {
color: red;
}
12
Conquer CSS
<div>
<p class="red-paragraph">
This is a red paragraph. But I want
my anchor tags to be green. Like <a href="/">this
one!</a>
</p>
</div>
<style>
div {
color: red;
}
div a {
color: green;
}
a:hover {
color: purple;
}
</style>
Now you can see that when you hover over the link, the color changes
to purple. This is just one of many pseudo-selectors.
13
Ryan Boddy
be handy when prototyping a quick change, it can quickly make your HTML
code very verbose and sloppy. For the purposes of this book, we won’t be
using inline styles, but I want to bring it up before we get into the topic of
specificity at the end of the chapter.
Properties
This is where the magic happens. We know how to target our elements using
element, class, and ID selectors. But how do we make them look the way we
want them to? This is where properties come into play. In CSS, a property
is exactly what it sounds like. It is a property of the HTML element that
determines the style of what gets put on the page. Let’s take a look at the CSS
from the code example we’ve been using:
.header {
color: #002699;
font-family: Arial, Helvetica, sans-serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
In this example, we have five CSS properties. Can you guess what they
are?
● Color
● Font-family
● Text-decoration
● Text-transform
● Font-style
When pairing these properties with their values, you can easily see what
they do. We’re setting the color to a hex value for a navy blue color. We will
14
Conquer CSS
then set the font family to Arial, underline the text, transform all the letters
to uppercase, and finally make the header italic.
At the time of this writing, there are 520 official CSS properties, and
each of them have different acceptable values. While that may seem
overwhelming, modern tooling makes it so that we don’t have to remember
all of the properties. With modern code editors, we have tools like
autocomplete and IntelliSense that suggest properties as we start typing or
give us a list of common properties to choose from. We can then use the
same tools to list out acceptable values. We will cover plenty of important
properties as we move through this book, but not all 520.
Specificity
So, now you know about selectors and properties, but we need to talk about
specificity. In CSS, specificity refers to the order in which conflicting styles
are applied. We’ve looked at element selectors, class selectors, and ID
selectors. Now, what if I have properties designated for all three? Which one
is chosen to be the style that gets applied? Let’s look at the following code:
<h1>Another H1</h1>
<style>
#headerId {
color: blue;
15
Ryan Boddy
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
.headerClass {
color: red;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
h1 {
color: yellow;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
</style>
I’ll give you a second to think. I encourage you to try it out on your own.
Let’s break down what is happening here to our headers. Maybe you
took a guess or you tried it out. If you try it, you’ll see our first header—the
one that says, “Hello World!”—is blue. The second header—the one that says
“Another H1”—is yellow. This all has to do with specificity. In CSS, IDs are
16
Conquer CSS
more specific than classes. This is due to the fact that they are only supposed
to be used to style one element, and classes can be used to style multiple
elements. The next highest specificity when it comes to selectors are classes.
If I removed the ID attribute from the first header, it would become red
instead of yellow. That is because our lowest specificity selector is the element
selector. In this example, the second header doesn’t have an ID or class,
which means it falls back to the styling from the h1 element selector. That
leaves us with headers that look like this:
Not the prettiest headers to look at, but this example drives home the
idea of specificity.
Let’s take a look at the previous example but with one slight
modification:
17
Ryan Boddy
<h1 id="headerId" class="headerClass">Hello
World!</h1>
<h1>Another H1</h1>
<style>
#headerId {
color: blue;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
.headerClass {
color: red;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
h1 {
color: yellow !important;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
</style>
18
Conquer CSS
You can see here that I have put the !important keyword in the element
selector for h1. This means that despite our first headings, which have an ID
and class set that define different colors, both headers are now yellow as you
can see here:
There are a few more rules about specificity that we will cover when they
become relevant in future chapters, but we’ll end this chapter with one more.
Remember those inline styles from the selector section? They have the
highest priority overall (as long as !important isn’t in the mix somewhere). If
you use an inline style on an element that has an ID or class, the inline style
will take precedence. Let’s look at an example of this:
19
Ryan Boddy
<h1 id="headerId" class="headerClass">Hello
World!</h1>
<style>
#headerId {
color: blue;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
.headerClass {
color: red;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
h1 {
color: yellow;
font-family: Arial, Helvetica, sans-
serif;
text-decoration: underline;
text-transform: uppercase;
font-style: italic;
}
</style>
20
Conquer CSS
Here you can see that I’ve put the style attribute on the second header
and used it to set the color to purple. When we refresh the page, we see the
following:
Now we have a purple header despite the element selector that is being
used to set the color to yellow. Pretty handy if you need to override some
styling and you don’t want to use the !important keyword.
21
CHAPTER 3
I
n the last chapter, we covered the CSS syntax rules that are the foundation
of writing CSS. In this chapter, we will be covering methods of organizing
your CSS code. This will give you the lumber to build on those syntax
foundations. That being said, there are quite a few ways to build a house. We
will cover some popular methods of organizing CSS and some things to
consider when arranging your code, but it is ultimately up to you to determine
the best way that works for you. The information provided here is meant to
be a starting point to help you make those decisions.
Stylesheets
CSS is called Cascading Style Sheets, but so far, we haven’t really made a
stylesheet. We’ve put some CSS in a <style> tag, but that wasn’t a stylesheet.
Allow me to explain. Let’s start with a simple directory:
In this directory, we have an index HTML file with some markup, and
an app.css file with some CSS in it. The app.css file is a stylesheet and by
referencing it in our HTML file, we can organize our CSS in a different
document. Let’s look at what these documents look like:
22
Conquer CSS
app.css
p {
color: red;
}
h1 {
color: blue;
}
li {
color: green;
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<link rel="stylesheet" href="./app.css" />
<title>Conquering CSS</title>
</head>
<body>
<h1>Hello Readers!</h1>
<ul>
<li>This is a list!</li>
23
Ryan Boddy
<li>It can also be styled with CSS!</li>
</ul>
<div>
<p>And this is another paragraph, but it
is contained within a div tag! It too, can be styled
with CSS</p>
</div>
</body>
</html>
We have some color properties in the app.css file for some elements on
the page in our HTML file. The way we link the two together is shown in the
<head> tag. To reference a stylesheet in HTML, create a <link> tag in the
head with the attributes of rel and href. The rel attribute tells the browser what
kind of link the tag is referring to. In this case, it’s a stylesheet. The href
attribute gives the location of the CSS file. In this case, it’s in the same
directory, so we can simply use “./app.css”. Now, if we refresh our page, it
looks like this:
You can see that our styles are included and that everything is working!
Awesome. This means that we now have a separate place to organize our CSS
and we don’t have to clutter up our HTML files with it. This is the most
24
Conquer CSS
common means of infusing CSS into your HTML documents and is generally
preferred over style tags.
Separating your CSS into stylesheets ensures that you have a dedicated
space to write your CSS, and it doesn’t mix with any other code, making it
easy to keep track of. Before the proliferation of component-based web
design, there was a popular concept called separation of concerns, a best
practice which called for all code to be self-contained in its own document.
For example, all the HTML goes into an HTML document, all the CSS goes
into a CSS document, and all the JavaScript goes into a JavaScript document.
As I noted, this paradigm is no longer enforced in modern web development,
but it’s good to know about it.
The next level of specificity above inline styles is the <style> tag within
the HTML document. Code in the stylesheet itself is the lowest level of
specificity there is. Let’s take a look at an example of this.
We’re going to change our code a bit in this example. Make the following
changes to your index.html from the previous example and then try and guess
which color the header will be:
<ul>
<li>This is a list!</li>
<li>It can also be styled with CSS!</li>
25
Ryan Boddy
</ul>
<div>
<p>And this is another paragraph, but it
is contained within a div tag! It, too, can be styled
with CSS</p>
</div>
<style>
h1 {
color: yellow;
}
</style>
As you know, the inline style is going to take precedence here, so the
heading will be black.
Well, the heading would be yellow as per the style tag at the bottom of
the page. If the style tag is removed altogether, the heading will be blue
because that’s what’s in our app.css file. These specificity rules give you the
option of overriding the CSS in your stylesheet with a style tag. This allows
for quick testing of a change without going through your stylesheet. Style tags
also load faster than external stylesheets do, so if there is styling you need to
prioritize for users with slow connections, you can include the most
important code in a style tag while you wait for your stylesheet to load. This
still isn’t the final note we will have on specificity, so be ready to revisit the
topic again.
Comments
There are many different ways to organize your stylesheets to produce clean
CSS code. We will take a look at some of these patterns so that you can judge
26
Conquer CSS
which one may be best for you. Before we get started, though, I want to bring
up an organizational tool that is ubiquitous across programming languages,
and that’s comments.
Comments are lines of code that are not evaluated by the browser that
allow developers to leave notes to others who may be reading their code.
Comments are best practice in any code and should be used to explain code
to others who are going to read it. It’s also helpful to leave yourself notes
about work left to do, how something works, or areas of confusion.
So, how do we leave comments in CSS? Let’s take a look at the code
below:
Here, you can see multiple comments in the code. The first two
comments are single lines and show the syntax for comments. You start a
comment with a /* and close it with a */. The good thing about CSS is there
is no difference between single and multi line comments. Unlike many other
languages, everything between your open comment symbol (/*) and your
closing comment symbol (*/) will be considered a comment. You can put a
27
Ryan Boddy
Organizational Patterns
There are methodologies for writing your CSS that offer guidelines on
organizing and naming your selectors. When you are working on a large app
or website, you may have hundreds or even thousands of class names and
selectors in your CSS file. How do you organize them all so that they are easily
maintained? Let’s take a look at some of the organizational patterns that are
popular in the frontend development industry today.
The BEM organizational pattern has grown in popularity since its beginnings
in 2005. Since then, more web developers have adopted it as their standard
for writing CSS over most other CSS architecture patterns. Designed with
organization and modularity in mind, this approach to organizing your
stylesheets focuses on three descriptors when naming CSS classes. These
three are block, element, and modifier.
An element is exactly what it sounds like. If the header is the block, the
element may be a header image. Elements should be semantically related to
their blocks.
The modifier portion of the name refers to a flag that changes behavior
or appearance.
28
Conquer CSS
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<link rel="stylesheet" href="./app.css" />
<title>Conquering CSS</title>
</head>
<body>
<nav class="navbar">
<ul class="navbar--list">
<li class="navbar--listItem navbar--
listItem-active">
<a class="navbar--link"
href="/home">Home</a>
</li>
<li class="navbar--listItem">
<a class="navbar--link"
href="/about">About</a>
</li>
<li class="navbar--listItem">
<a class="navbar--link"
href="/contact">Contact</a>
</li>
</ul>
</nav>
</body>
</html>
29
Ryan Boddy
app.css
body {
margin: 0;
}
.navbar {
background-color: #2e2e2e;
height: 50px;
width: 100%;
}
.navbar--list {
list-style: none;
margin: 0;
}
.navbar--listItem {
display: inline-block;
margin: 15px 15px 0px 0px;
}
.navbar--listItem-active {
text-decoration: underline;
}
.navbar--link {
color: white;
font-size: 18px;
font-family: Arial, Helvetica, sans-serif;
text-decoration: none;
}
30
Conquer CSS
You can see that we are creating a navbar with some links to Home,
About, and Contact. Furthermore, we’ve given the navbar some styling and
given the current active page an underline in the menu. This is the first
example of CSS code that you may see in the real world, so be sure to become
comfortable with what each of the selectors and their properties are doing
before moving on.
If you feel comfortable with the code here, let’s discuss where BEM
comes into play. Here, you can see that we have one block, which is a navbar.
There are some elements within that block, such as a list, list items, and links.
There is a modifier on our list items that underlines the active page. As you
can see, the BEM syntax is BLOCK–ELEMENT-MODIFIER. That’s the
block, followed by two dashes, then the element, followed by one more dash,
and finally the modifier.
31
Ryan Boddy
I definitely could have written less code for this example, and that’s not out
of the norm for BEM. It is very detailed but not always succinct.
Furthermore, blocks, elements, and modifiers may not always communicate
everything you were thinking when styling that element. This is the perfect
time to add some comments to add context so that other developers may
better understand what they’re looking at.
That’s BEM in a nutshell. Try and style some other elements with this
organizational method and see if you can really get a feel for how it’s all laid
out. Once you’re comfortable, we can move on to our next organizational
pattern.
SMACSS
● Base
● Layout
● Module
● State
● Theme
Base styles are the default styles for elements on the page. For example,
it’s very common to remove the default margin on the body element with body
{ margin: 0 }. This is a perfect example of what it means to create a base style.
Base styles will almost always apply to single element selectors, and it’s
common to see the same rule applied to multiple selectors.
Layout styles are responsible for laying out your content on the page.
For example, you may have a page with three columns or a grid system. These
styles would be in the layout section of your CSS file. Layout is an important
32
Conquer CSS
Next up, we have the module category. Modules are akin to blocks in
BEM in that you can consider them to be the components that make up your
page. Common examples are navbars, headers, footers, or sidebars. This
category is pretty self-explanatory. It’s where most of the CSS classes will live
since it has the largest effect on the content of our web app or page.
The state category refers to the look and behavior of our modules when
their state changes. For example, we may have a button that is being used to
cancel a subscription. The state of this button may be “danger” because it is
a permanent action that cannot be undone. We may make the button red or
the text in the button red to communicate this to the user. The class .button-
danger would be used to apply these styles, and it would be in our state
category.
And lastly, there is the theme category. This is where you may set
common theme colors for your application or your custom fonts. Any aspect
of how your modules look in relation to the theme of your website or web
application would be stored in this category.
At first glance, it may seem like it would be difficult to keep track of all
of these categories. However, once you get better at sorting your CSS rules
into these categories, it helps keep things organized in places where they
would be easy to find and modify. This methodology also allows you to keep
short class names at all times, making it easier to find exactly what you’re
looking for and keep your HTML more succinct. If this sounds like it would
match your organizational style, give SMACSS a try. If neither BEM nor
SMACSS appeal to you, I’ll cover one more organizational method that is
growing in popularity in today's web architecture.
Component-Scoped CSS
33
Ryan Boddy
For many developers, the answer to this question came in the form of
scoped CSS. Scoped CSS refers to the concept that only the CSS that belongs
to a specific component is included in that component's base code. This
means that you are only changing the CSS related to that one particular
component and you can reuse it as many times as you need. Libraries for
“CSS-in-JS” and stylized components have been rising in popularity as
component-based frameworks have become more prevalent. Let’s take a look
at an example of component-scoped CSS in a framework that supports it out
of the box—Svelte:
header.svelte
<script>
export let text;
</script>
<div class="header">
<h1>{text}</h1>
</div>
<style>
.header {
height: 150px;
width: 100%;
display: flex;
align-items: center;
background-image: linear-gradient(
34
Conquer CSS
45deg,
hsl(188deg 85% 35%) 0%,
hsl(194deg 100% 36%) 11%,
hsl(199deg 100% 40%) 22%,
hsl(209deg 70% 52%) 33%,
hsl(232deg 63% 64%) 44%,
hsl(269deg 56% 62%) 56%,
hsl(305deg 52% 55%) 67%,
hsl(324deg 80% 55%) 78%,
hsl(332deg 100% 49%) 89%,
hsl(344deg 100% 50%) 100%
);
}
.header > h1 {
text-align: center;
width: 100%;
font-family: "Bebas Neue", cursive;
font-size: 50px;
}
</style>
In this .svelte file, you can see that we have a component with features
like any other component-based framework, such as properties. These are not
to be confused with CSS properties. (Don’t worry if you don’t know what
these are—they’re not in the scope of this book.)
You can also see that through the use of a style tag, all the relevant styling
for this component is included in the component file. This means that
everywhere I use this component, styling will be applied.
The advantages of this approach are numerous. First off, I can change
the styling of this component and change it everywhere it’s being used
throughout the application. This is not an advantage that’s inherent to this
approach, but it’s worth mentioning. It’s also easier to organize CSS because
you know that the CSS is only affecting this one component and nothing else
35
Ryan Boddy
on the page. It also cuts down on the amount of CSS you have to look
through when making changes. With all that being said, it’s not without its
disadvantages. This method does away with separation of concerns in the
traditional sense. If that’s important to you, this may not be the approach for
you.
To get started with scoped CSS, either use a framework with support for
it like Svelte or Next.js, or install a CSS-in-JS library for popular frameworks
like React or Vue.
Up to this point, we’ve talked a lot about CSS, but haven’t written much
of it. Let’s dive in and see how we can start rethinking the way we use CSS to
make beautiful websites and applications.
36
CHAPTER 4
A
t its core, CSS is all about boxes. Of course, that is a vast
oversimplification, but a lot of people forget this simple fact when
writing their CSS. Remember reading about layout styling in the
SMACSS section of the last chapter? Well, we’re going to go over a principle
that will make layout creation much simpler for you as a developer. We’re
going to cover the box model.
The box model consists of four parts: margin, padding, borders, and
content. These four properties can be applied to any element that you style
with CSS. When considered altogether, you can see why they are collectively
called the box model. Let’s look at the image below:
This is the box model illustrated. Notice how the header here is in a box.
That’s because it has the four elements of the box model. Let’s break them
down:
Margin
If everything in CSS is a box, margin is the space around that box. Margin
allows us to move elements on the page in relation to other elements.
Let’s say you had two cardboard boxes that contained items you cared
about. If you moved those boxes one foot apart from one another, the margin
in between would be one foot.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<title>Conquering CSS</title>
</head>
38
Conquer CSS
<body>
<div class="box-1">
<p>This is box 1!</p>
</div>
<div class="box-2">
<p>This is box 2!</p>
</div>
<style>
div {
width: 100px;
height: 100px;
background-color: lightblue;
}
.box-1 {
margin-left: 30px;
}
.box-2 {
margin-top: 50px;
}
</style>
</body>
</html>
39
Ryan Boddy
As you can see, we set some base styles for our divs with the div selector
(for visibility’s sake). We set a left margin of 30 pixels on the first box, which
pushes it away from the left edge of the document by 30 pixels. We set a top
margin of 50 pixels on the second box, which pushes it under the first box
by 50 pixels.
You may have noticed that the boxes were already spaced away from the
edge of the document ever so slightly. This is because the body element has
a default margin of eight pixels on all sides when you first start. For this
reason, you’ll often see the following as the first line of any CSS document:
body {
margin: 0;
}
This will remove the default margin from the body and allow you to
make your element’s edges touch the sides of the document.
40
Conquer CSS
Let’s say I wanted to give the first box from our previous example a top
margin of 50 pixels, a right margin of 10 pixels, a bottom margin of 15 pixels,
and a left margin of 30 pixels. I could write it like this:
.box-1 {
margin: 50px 10px 15px 30px;
}
Furthermore, I can compress this down. Maybe I want to set the margin
to be equal on all sides. Instead of writing values for margin-top, margin-right,
margin-bottom, and margin-left, I can simply write the following:
.box-1 {
margin: 50px;
}
Padding
Padding is like margin in that it is a measurement of space. Padding, however,
is a measurement of space inside an element. Let’s take a look at our example
with the two boxes. If we remove all the margin rules, our output will look
like this:
41
Ryan Boddy
You may notice that the content—the words in the boxes—is essentially
touching the edge of the boxes. This makes it harder to read as it looks
disorganized. Let’s change our CSS to match the following:
div {
width: 100px;
height: 100px;
background-color: lightblue;
}
p {
padding: 10px;
}
As you can see, the text within our paragraph tags now has some padding
and it seems much more readable. Let’s take a look:
42
Conquer CSS
What we’ve done is add space between the content in the paragraph tag
and the inner edges of the paragraph tag. This allows it to become more
readable for our website visitors or application users. You see padding almost
everywhere in modern web design because without it, content would be hard
to look at.
There are a couple of things about padding that you need to keep in
mind.
The first thing is that TRBL comes back into play. You can use the same
shorthand for padding if you want different padding values on any given side.
Border
Border is the fun one in the box model bunch. You can do a lot with it, and
it’s a great way to make elements stand out on a page. That being said, it’s
also very easy to go overboard with border properties and make your page
look busy. But this isn’t a book on design, so let’s take a look at what you can
do with borders. Let’s change our CSS code from the previous example:
43
Ryan Boddy
div {
width: 150px;
height: 150px;
background-color: lightblue;
border: 1px solid black;
margin-top: 10px;
box-sizing: border-box;
}
p {
padding: 10px;
}
Let’s take a look at the output and see how our boxes are looking:
As you can see, we now have borders around our boxes that are solid
black lines. Let’s break down the code here to get an idea of how we set
borders.
1. A size: This sets the width of the border. If we set the border to 2px
solid black we’d get the same border, but twice as thick.
44
Conquer CSS
You can also use borders to change the corners of your elements. Let’s
change our CSS in our example a little more:
div {
width: 150px;
height: 150px;
background-color: lightblue;
border: 1px solid black;
border-radius: 15px;
margin-top: 10px;
box-sizing: border-box;
}
p {
padding: 10px;
}
45
Ryan Boddy
Content
This characteristic is anything you put inside the box, including headers,
paragraphs, lists, forms, and inputs. This category is easy to understand on
the surface, but it’s also where we have the most options when it comes to
properties. Here are just some of the most common properties that modify
content:
● Font-family
● Font-size
● Font-weight
● Color
● Background-color
● Text-decoration
● Text-transform
div {
width: 150px;
height: 150px;
background-color: lightblue;
border: 1px solid black;
46
Conquer CSS
border-radius: 90px;
margin-top: 10px;
box-sizing: border-box;
display: none;
}
p {
padding: 10px;
}
Well, this is sort of a trick question. Our boxes aren’t even there.
If you refresh the browser page, you’ll see that they are gone. They aren’t
just invisible either (which could be achieved by setting the visibility property
to hidden). Our boxes are gone altogether. This is because we have removed
their display property by using none. This comes in handy when you need to
hide something by default and then potentially show it again later with
JavaScript.
So, what else can we do with display? Well, we can use it to change how
the rest of the box model behaves. Remove the display: none property from
our two boxes example. It should now look something like this:
These boxes stack on top of each other because by default, they have
the display value of block.
47
Ryan Boddy
If we want them side by side, we can set our display property to inline-
block and watch the magic happen. Change your code so that the div selector
has a property of “display: inline-block;”. The result will now look like this:
Pretty cool, right? You can probably see how being able to move blocks
around like this can come in handy when creating layouts.
With newer properties such as Flexbox or Grid, we can gain full control
over the positioning of our elements on the page. Let’s check this out in
action by using Grid to align some divs in a neat pattern. Go ahead and
change your code to match the following:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<title>Conquering CSS</title>
</head>
<body>
<div class="grid">
<div>I'm a div</div>
<div>I'm a div</div>
<div>I'm a div</div>
48
Conquer CSS
<div>I'm a div</div>
</div>
<style>
.grid {
display: grid;
grid-template-columns: 2fr 2fr;
justify-items: center;
gap: 10px;
width: 50%;
margin: 0 auto;
}
.grid div {
width: 150px;
height: 150px;
padding: 10px;
box-sizing: border-box;
background-color: lightblue;
border: 1px solid black;
}
</style>
</body>
</html>
As you can see, to use Grid, we must set a parent container element like
a div that has a display value of grid. We use grid-template-columns to delineate
how much space we want our columns to take up. In this case, we use 2fr
twice. This means that the four child divs will be split into two fractional
columns that will automatically be pushed into a second row since there are
more divs than fractional units.
49
Ryan Boddy
Let’s look at the output we would get if set a grid gap using gap to
separate our boxes:
This is very well organized and structured. Grid and Flexbox are both
dynamic tools that allow developers to have more granular control over
where the elements on their page are layed out. We will discuss them in more
detail in Chapter 6.
Keeping the box model in mind while writing your CSS will help you
style elements concisely and efficiently. It may take some time to shift your
mindset to think of everything as a box, but once you do, layouts become
much simpler to create. In the next chapter, we will be discussing responsive
web design and how we can use CSS to make our web pages work on all
devices. Having the box model at the forefront of your mind will be
instrumental in this effort.
50
CHAPTER 5
Responsive CSS
C
SS was initially intended to be a stylesheet language that would
aestheically enhance the look of the internet on a computer screen, but
over the next 25 years, the web would completely transform. Over 50%
of all web browsing is now done on a mobile device, whether that be a phone
or a tablet.
Responsive Units
In CSS, pixels have been traditionally used to delineate sizes, but as CSS
evolved, more units of measurement were added that could be better
interpreted by responsive interfaces. We have some options when it comes
to responsive units of measurement. To explore these options, let’s change
our code to match the following:
51
Ryan Boddy
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<title>Conquering CSS</title>
</head>
<body>
<div>
<p>I'm a box!</p>
</div>
<style>
div {
width: 1000px;
background-color: orange;
margin: 0 auto;
height: 200px;
padding: 20px;
box-sizing: border-box;
font-size: 20px;
}
</style>
</body>
</html>
As you can see, we have a box that has been set up with static
measurements. The box may look okay on our desktop, but how can we know
what happens when we switch to mobile?
52
Conquer CSS
Most modern web browsers have the ability to check mobile views by
using the developer tools feature. If you’re using Google Chrome, open the
Developer Tools tab. To do so, click F12 on your device, or right-click and select
“Inspect”. Now click the Device Type button in the top left as shown here:
After swapping to mobile view, you can see that our box is far too large
for phone screens and would stretch off the screen. So, what can we do to
ensure that the box looks good on both screens? Instead of static pixels, we’re
going to measure our boxes using percentages. Change the code to match the
following:
div {
width: 50%;
background-color: orange;
margin: 0 auto;
height: 200px;
padding: 20px;
box-sizing: border-box;
font-size: 20px;
}
53
Ryan Boddy
Desktop
Mobile
As you can see, the boxes now fit regardless of the device we’re viewing.
Percentages are an easy way to make our elements responsive. Nevertheless,
there are always things to consider when using any particular method of
measuring. With percentages, the sizes of your elements are determined by
54
Conquer CSS
the containing element. It’s important to learn where this could cause
problems in order to avoid them. Let’s use percentages on a header:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<title>Conquering CSS</title>
</head>
<body>
<style>
h1 {
text-align: center;
width: 50%;
margin: 0 auto;
}
</style>
</body>
</html>
On the desktop, the header looks good. It takes up 50% of the space,
just like we intended. However, desktop browsers are in landscape
orientation, while mobile browsers are in portrait. So, when we set the header
to 50% of the portrait view, it looks way too small as you can see here:
55
Ryan Boddy
With em and rem units, you gain more control over your sizing. Typically
used for, but not limited to, font sizing, em and rem can be very powerful.
h1 {
text-align: center;
font-size: 2.5em;
margin: 0 auto;
}
Here, we are setting the font-size of our header to two and a half times
that of the parent element’s font-size. In this case, the parent element is the
<body> element, which has a default font size of 16 pixels. Since the font size
here sets both width and height, we will run into fewer issues than we did
56
Conquer CSS
This is all well and good, but what if we don’t want to set the font size
of every containing element on our page? This is where rems come into play.
“Rem” is short for “root element” and references the font size of your root
element. Let’s slightly modify our previous example:
<body>
<div>
<h2>This is a subtitle</h2>
</div>
<style>
h1, h2 {
text-align: center;
font-size: 2.5rem;
margin: 0 auto;
}
div {
font-size: 20px;
}
</style>
</body>
Here, you can see that despite our second header having a containing
element with a font size of 20 pixels, it gets the same size as our first header.
This is because the font size of our <body> element is 16 pixels, and rems
allow us to reference that value.
57
Ryan Boddy
There are other options for element sizing that can work quite well. The
vw and vh units are commonly used to create responsive elements as well.
“Vh” stands for “viewport height” and represents 1% of the viewport’s total
height. “Vw” stands for “viewport width” and represents 1% of the
viewport’s total width. Let’s take a look at these in action:
<body>
<div class="view-height">
<p>This one uses VH</p>
</div>
<div class="view-width">
<p>This one uses VW</p>
</div>
<style>
.view-height {
height: 10vh;
width: 100px;
background-color: orange;
}
.view-width {
height: 100px;
width: 10vw;
background-color: orange;
}
</style>
</body>
Here, you can see the different sizing produced by the viewport height
and viewport width units of measurement. Our box is 10% of the viewport’s
relative width while also being 10% of the viewport’s relative height. If you
resize the window, you will see the box grow or shrink in response.
58
Conquer CSS
While vh and vw can be very useful, they aren’t without their pitfalls.
Remember, desktop and mobile devices are generally oriented differently, the
former being landscape and the latter being portrait. If we set a measurement
using viewport width, it will look completely different on each device because
portrait width is much smaller than landscape width.
There is a way to fix this using vmin and vmax. “Vmin” stands for
“viewport minimum”—the smaller of the two dimensions of the viewport. If
we’re strictly comparing landscape desktop to portrait mobile views, 1 vmin
will equal 1 vh on desktop and 1 vw on mobile. This helps us to ensure that
these responsive units are more aligned with one another. “Vmax” means—
you guessed it—"viewport maximum”. This is simply vmin inverted. Vmax
takes the largest of the two viewport dimensions and uses that dimension to
determine whether to use vh or vw. Let’s take a look at the use of these units
in practice by implementing vmax:
<body>
<div>
<p>This one uses Vmin</p>
</div>
<style>
div {
width: 10vmax;
height: 100px;
background-color: orange;
}
</style>
</body>
59
Ryan Boddy
If you open up the developer tools of your browser and switch the view
to mobile, you’ll see that our box still has a reasonable width. This is because
vmin is dynamically switching between using vh and vw units based on viewport
size. This allows us to create elements on the page that look good on both
desktop and mobile devices.
These are definitely not all the units of measurement that are
implemented in CSS, but they are some of the most commonly used because
they make it much easier to create interfaces that look good on multiple
devices.
There are still instances in which we would still need to write entirely
separate code for different devices. That’s where our next topic comes into
play.
Media Queries
It’s time to open up a can of worms. Truth be told, there are developers who
don’t even believe in our next topic because it’s become bad practice. I, on
the other hand, still believe it’s valuable to learn about media queries.
Media queries are rules you can write in CSS that only apply to particular
types of media. The most common use case for them is writing CSS that only
60
Conquer CSS
applies to specific screen resolutions. That’s not all they can be used for, but
it’s what we’ll be covering.
<body>
<div>
<p>Media query magic!</p>
</div>
<style>
div {
width: 50%;
margin: 0 auto;
height: 100px;
background-color: orange;
}
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px)
and (-webkit-min-device-pixel-ratio: 2)
{
div {
background-color: lightblue;
}
}
</style>
</body>
61
Ryan Boddy
If you reload your browser, you may not notice anything different. Go
into the developer tools and switch the device type to mobile. The
background of our div will now be blue!
You can see that the styling is only being applied on mobile. This is
because our media query is targeting any device with a screen resolution lower
than the largest smartphone. Pretty neat, huh? We can combine this with
something like “display: none;” to make entire elements disappear on mobile
devices—or only appear on mobile devices.
To the uninitiated, this may seem like the ultimate answer to responsive
needs: just write a different set of CSS rules to make everything look good on
phones. There is, however, one serious drawback to using media queries: you
are now maintaining more code, leading to more margin for error. There isn’t
a “one-size-fits-all” media query, so to target the variety of modern devices
that exist, you have to write multiple media queries. This leads to messy,
inefficient code.
By the time you’ve finished writing all the media queries, you will need
to ensure that your non-responsive interface looks good on all devices—and
you will have written significantly more code than if you had just made the
interface responsive from the start. This doesn’t mean that you can’t use
media queries. It’s just important that you use them very conservatively. The
example I mentioned earlier is a good use case. If you have an element that
doesn’t make any sense on a mobile device, hide it altogether with a media
query.
Mobile Considerations
Now that you know how to use responsive units of measurement and media
queries to create responsive interfaces that look good on all devices, there are
things to consider when designing your elements. The way that you write your
CSS will vary based on these considerations.
62
Conquer CSS
Touch vs Cursor
One major factor to consider when it comes to writing CSS for mobile users
is to determine whether they will be using touch or cursor behaviors. Let’s
look at an example:
<body>
<div>
<p>Hover over me!</p>
</div>
<style>
div {
width: 50%;
margin: 0 auto;
height: 100px;
background-color: orange;
}
div:hover {
background-color: lightblue;
}
</style>
</body>
Here we have a box with a pseudo-selector for the styling of its hover
state. It may be important to the user experience to be able to hover over the
box to display or convey information, but keep in mind that touch devices
don’t have a way of determining whether or not a finger is hovering over an
element on the screen. This means that all the CSS we just wrote for that
hover state wouldn’t be relevant because this state doesn’t exist for our
mobile users.
Touch raises concerns for more than just the hover state. Let’s say we
write the following code for a form on the web:
63
Ryan Boddy
<body>
<div>
<form>
<label>Check Here</label>
<input type="checkbox" />
<br />
<label>Or Here</label>
<input type="checkbox" />
<br />
<label>Or Here</label>
<input type="checkbox" />
<br />
<label>Or Here</label>
<input type="checkbox" />
<br />
<label>Or Here</label>
<input type="checkbox" />
</form>
</div>
<style>
div {
width: 50%;
padding: 20px;
background-color: orange;
margin: 0 auto;
}
</style>
</body>
We have quite a few checkboxes that are already small on the web.
Generally, this isn’t an issue because we have the precision of a mouse pointer
64
Conquer CSS
to select these inputs. However, fingertips are not as precise as mouse clicks.
Someone with large fingers may accidentally check too many boxes or the
wrong boxes on our form. This can easily be mitigated by making forms that
would require form controls to be a little larger on mobile devices so that they
are easier to access.
Always try to keep the end user in mind when writing responsive CSS.
You don’t want to alienate a large chunk of your user base because it’s difficult
to use your website or application with touch controls.
Vestibular Disorders
As CSS has become more and more advanced, we have received language
features that have allowed us to do fancier things with our elements. Fifteen
years ago, animated websites were first created using Flash to allow graphical
elements to move on the page. Today, you can use CSS to animate things in
all kinds of interesting and eye-catching ways.
CSS animation is out of the scope of this book, but it’s worth
mentioning. Small, subtle animations can make information on a web page
more interesting to look at, but we must remember to take accessibility into
consideration when writing our CSS. There are users who have vestibular
disorders that make them susceptible to several reactions to overly animated
web elements, ranging from nausea to seizures. So, when it comes to
animations, less is more. After all, we want to make the web as accessible as
possible so that everyone can enjoy it.
65
CHAPTER 6
N
ow that we have covered the box model and responsive CSS, it’s time
to explore two of the most vital tools in CSS that marry these two
concepts. In this chapter, you’re going to learn about the Flexbox and
Grid layout systems.
Before we dive deeper into Flexbox and Grid, let’s explore what I mean
by layout system.
Before the introduction of layout systems, there were very few ways to
lay out HTML pages in a way that was efficient and responsive. The most
common solution to this problem was using HTML tables to lay out pages,
which added quite a bit of code to HTML documents and oftentimes led to
frustration while trying to place elements in the correct location. There were
also CSS properties such as float and margin that allowed developers to place
elements on a page in a static location. These were very difficult to work with
when the need for responsive interfaces arose.
The solution to these issues came in the form of layout systems. The
first layout system that was introduced was Flexbox. Flexbox came about in
2009 as a means of laying out elements in a one-dimensional flexible box.
When boxes became flexible, they worked much better on multiple devices.
This completely changed the way that layout was done with CSS and HTML.
Let’s take a look at what we can do with Flexbox.
Flexbox
The basic concept of Flexbox is to be able to work along two axes. The main
axis is set using the flex-direction property. It is either horizontal or vertical
depending on the value of the flex-direction. The cross axis is the other direction
that you don’t specify with the flex-direction. Let’s take a look at this in action:
66
Conquer CSS
Flex-Direction Column
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content="width=device-
width, initial-scale=1.0">
<title>Conquering CSS</title>
</head>
<body>
<div class="flexContainer">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
<style>
.flexContainer {
display: flex;
flex-direction: column;
}
.flexContainer > div {
background-color: orange;
margin: 10px;
height: 200px;
width: 200px;
}
67
Ryan Boddy
</style>
</body>
</html>
Output
68
Conquer CSS
Flex-Direction Row
<style>
.flexContainer {
display: flex;
flex-direction: row;
}
.flexContainer > div {
background-color: orange;
margin: 10px;
height: 200px;
width: 200px;
}
</style>
Output
You can also reverse the directions of your contents if you’re working
with an audience from a country that reads right to left. Simply add “-reverse”
to your direction and you’ll flip your axis. You can see this here:
69
Ryan Boddy
.flexContainer {
display: flex;
flex-direction: row-reverse;
}
You can also reorder the flex items within your flex container. To do
this, use the order property:
<div class="flexContainer">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
<style>
.flexContainer {
display: flex;
flex-direction: row;
}
.flexContainer > div {
background-color: orange;
margin: 10px;
height: 200px;
width: 200px;
}
.item1 {
order: 3;
70
Conquer CSS
}
.item2 {
order: 1
}
.item3 {
order: 4;
}
.item4 {
order: 2;
}
</style>
Output
<div class="flexContainer">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
71
Ryan Boddy
<style>
.flexContainer {
display: flex;
flex-direction: row;
width: 500px;
flex-wrap: wrap;
}
.flexContainer > div {
background-color: orange;
margin: 10px;
height: 200px;
width: 200px;
}
</style>
Output
You can also combine flex-direction and flex-wrap into one shorthand
property called flex-flow. Here is an example of flex-flow:
72
Conquer CSS
.flexContainer {
display: flex;
flex-flow: row wrap;
width: 500px;
}
As you can see, this cuts the number of lines of code you have to write
in half. Flexbox itself allows for much less code to be written than what would
have been previously required to create similar interfaces.
The final part of Flexbox that we’ll cover is justifying and aligning. Using
the property justify-content, we can determine how content is aligned along the
main axis. We can also use the align-items property to do the same thing along
the cross axis. This gives us the opportunity to do things like center elements
on a page. (Believe it or not, centering elements both vertically and
horizontally was very difficult to do prior to the implementation of Flexbox.)
Check out the following code to see this in action:
<div class="flexContainer">
<div>I'm centered!</div>
</div>
<style>
body, html {
height: 100%;
}
.flexContainer {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.flexContainer > div {
background-color: orange;
73
Ryan Boddy
margin: 10px;
height: 200px;
width: 200px;
}
</style>
Output
Grid
The original specification for CSS Grid was published in 2007, two years
before CSS Flexbox was introduced to the public. It then took over ten years
for the module to be formalized and introduced into CSS with support across
all major browsers—except Internet Explorer as it has its own grid
74
Conquer CSS
specification. Due to its legacy nature, we will not be discussing the way
Internet Explorer implements CSS Grid in this book.
CSS Grid is a layout system that gives full control over two dimensions
of your layout: column and row. This allows developers to create complex
grids of components that are responsive.
<div class="gridContainer">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
<style>
.gridContainer {
display: grid;
grid-template-columns: 300px 300px;
}
.gridContainer > div {
background-color: orange;
border: 1px solid black;
height: 200px;
padding: 10px;
box-sizing: border-box;
}
</style>
75
Ryan Boddy
Output
As you can see, we use display: grid; on a container element to create our
grid itself. Then we use grid-template-columns and grid-template-rows to define how
our grid will be laid out. Also notice that I only define columns here. That’s
because Grid is designed to automatically create new rows or columns for
your content if there is more content than the grid units can hold. Here, I
only define two grid columns, so it splits four divs into two rows in two
columns. The magic of Grid is the fact that we can use special values to create
responsive elements. The most basic of these values is a fractional unit.
.gridContainer {
display: grid;
width: 100%;
grid-template-columns: 1fr 1fr;
}
76
Conquer CSS
Output
The code above creates two spaces in our grid that take up all available
horizontal space. This means that the elements that take up these spaces will
now shrink and grow in response to different screen sizes without the need
for responsive units. This can also be done with grid-template-rows to ensure
that elements take up all available vertical space within their row. Go ahead
and switch grid-template-columns for grid-template-rows in the code above and see
the difference. The elements will still be responsive, but to changes in height
instead of width.
.gridContainer {
display: grid;
width: 100%;
grid-template-columns: 200px auto;
}
77
Ryan Boddy
Output
If you resize your screen, you’ll notice that the grid item with the auto
dimension grows and shrinks to fill the available space. This is helpful with
things like sidebars that may have a set width while the rest of the page shrinks
and grows.
You may have a grid with many elements in each row and want to use
fractional units for your sizing. However, writing out 1fr eight times would
not be very fun. This is where the repeat function comes into play. You can
use repeat along with the fractional unit and the number of times you want
that unit repeated to shorten the amount of code you write. Here is an
example:
<div class="gridContainer">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
<style>
.gridContainer {
display: grid;
78
Conquer CSS
width: 100%;
grid-template-columns: repeat(8,
1fr);
}
.gridContainer > div {
background-color: orange;
border: 1px solid black;
height: 200px;
padding: 10px;
box-sizing: border-box;
}
</style>
Output
Well, that’s easy. Simply add space between your rows or columns with
the column-gap and row-gap properties. This allows you to visually separate your
elements in a manner that may make them more pleasing to the eye. Below is
an example:
.gridContainer {
display: grid;
width: 100%;
grid-template-columns: repeat(4,
1fr);
column-gap: 10px;
row-gap: 10px;
}
79
Ryan Boddy
The final topic we’ll cover relating to Grid is align-items and justify-items.
These properties work similarly to justify-content and align-items in Flexbox, but
they always apply to the same dimensions in Grid. Align-items allows you to
align your grid items vertically, while justify-items allows you to align items
horizontally. You can also combine these two into the place-items shorthand
property. Let’s take a look at how this works:
<div class="gridContainer">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
<style>
body, html {
height: 100%;
}
.gridContainer {
display: grid;
width: 100%;
height: 100%;
grid-template-columns: repeat(2,
1fr);
place-items: center;
}
.gridContainer > div {
background-color: orange;
border: 1px solid black;
80
Conquer CSS
height: 200px;
width: 200px;
padding: 10px;
box-sizing: border-box;
}
</style>
Output
As you can see, we have four vertically and horizontally centered boxes.
This is very useful when you need to center multiple items in one layout.
That’s Grid and Flexbox! We didn’t cover every aspect of these potent
layout systems, but this is enough to get any developer started. Practice with
both systems to get a handle on them and keep them in mind when
considering how you want to lay out your projects in the future.
81
CHAPTER 7
CSS Frameworks
A
t the end of the day, programming languages are just like woodworking
tools. How you use them and what you do with them is totally up to
you. However, some people want the tools, the instructions, and the
nuts and bolts included for their woodworking projects. That is where
frameworks come into play. Just like any other programming language, CSS
has frameworks to choose from.
Before we dive into frameworks, I want to talk about the advantages and
disadvantages of using them. Like all things, there are trade-offs when using
a CSS framework, and I want to ensure that they are clear before I give you
some options to pick from.
Advantages
82
Conquer CSS
earlier in this book, CSS Grid was eventually introduced, but before that,
frameworks were the easiest way to introduce layout grids.
Disadvantages
Frameworks are not without their flaws. If they were, I’d be writing a whole
book on CSS frameworks and not the language itself. First of all, the major
CSS frameworks are used by thousands of developers. This means that you
will have to write some custom CSS on top of your chosen framework to
make your site look unique. A seasoned developer can easily spot a website
or application that uses an out-of-the-box framework styling. Many
frameworks come with the ability to theme their elements by including
additional stylesheets, but even these can often lead to websites and
applications that aren’t one of a kind.
83
Ryan Boddy
Bootstrap
When Twitter released that their internal style guide was Bootstrap 1 in 2011,
it took the development world by storm. Since then, Bootstrap has had over
20 releases and is in its fifth major version as of this writing. Bootstrap has
become prolific in the industry, being known for its simple yet powerful grid
system, fully extensible components, and minimalist design.
As you can see, Bootstrap uses a very minimal design that will spruce up
a web page without making it too busy or cluttered. The components are also
fully extensible, which allows the developer to overwrite or change styles to
match their needs.
84
Conquer CSS
Material Design
Google and its main properties, YouTube and Gmail, are some of the most
visited websites in the entire world. Throw in the fact that Google owns the
Android OS and it’s hard to find someone who hasn’t used something owned
by Google. With this being the case, the cohesive design of Google’s
properties has become familiar to users around the world. To spread the
Google design further, the company released Material Design in 2014.
85
Ryan Boddy
Foundation
Unlike Bootstrap and Material design, Foundation was created by a small
team with the goal of creating the easiest, most responsive framework
available. With a focus on mobile first design, this framework is perfect if
you’re working on a codebase that will be reused for a mobile application.
Foundation also has a unique feature in that it has a dedicated library called
“Foundation for Email” that makes the traditionally laborious task of styling
emails much easier.
Let’s take a look at the website for the car brand Subaru, which was built
using Foundation:
86
Conquer CSS
Tailwind CSS
Tailwind CSS is the new kid on the block when it comes to CSS frameworks.
Released in May 2019, it quickly gained popularity with developers who
wanted more flexibility from their CSS framework. Tailwind is a utility-first
framework. Unlike other frameworks, it doesn’t focus on pre-built
components for you to use to build your applications. Instead, it comes with
an extensive library of classes that allow you to modify elements without
writing any CSS rules yourself. Tailwind has introduced its own library of
components, but they aren’t the sole focus of the framework.
87
Ryan Boddy
If you are not a fan of writing CSS and don’t mind longer lists of
classnames in your markup elements, check out Tailwind CSS.
Wrapping Up
These are just a few of the CSS frameworks that are available today. There
are hundreds, if not thousands, to choose from if you’re still looking for the
perfect fit.
Remember, you can always write your own CSS. In the next chapter,
we’ll take a look at some tools that make writing CSS even easier so you can
be faster and more efficient.
88
CHAPTER 8
T
hroughout CSS’ evolution, each new specification that was released left
features to be desired by developers. One such example of this was being
able to use variables to store reusable values. This is one of the most
basic features of Turing complete programming languages, but CSS lacked
this ability until the addition of custom properties. Prior to this change, CSS
had to be supplemented with something else to gain this functionality. The
common solution was a preprocessor.
Preprocessors are languages of their own that are similar to CSS but with
the features that developers have requested from CSS throughout the years.
These preprocessor languages are used to write code that is then compiled
into traditional CSS before being shipped to the browser. Features that are
commonly present in preprocessors include reusable variables, nested rules,
and modules. Two of the most popular CSS preprocessors are SASS and
LESS.
SASS/SCSS
Syntactically Awesome Style Sheets (SASS) was first released in 2006. It was
announced as a new way to write CSS that allowed for more flexibility and
less code. This appealed to developers who were tired of writing long
stylesheets with hundreds, if not thousands, of rules that dictated their
website or application’s styling.
Shortly after SASS was set in motion, the SASS team introduced a new
syntax to use with SASS: SCSS, or “Sassy CSS.” This syntax bridged the gap
between traditional CSS and SASS, making it much easier for developers who
were comfortable with CSS to learn and use SASS. In this book, we’ll use
SCSS for examples, but feel free to consult the SASS documentation at
89
Ryan Boddy
Let’s take a look at some code to see how SCSS works. The following
shows a good example of many of the SCSS features:
$font: arial;
$primary-color: green;
$font-color: white;
div {
background-color: $primary-color;
width: 50%;
height: 300px;
border: 2px solid darken($primary-color,
20%);
p {
color: $font-color;
font-size: 30px;
padding: 20px;
font-family: $font;
}
}
There is a lot happening in this code that you wouldn’t see in traditional
CSS, so let’s break down what is happening in this SCSS code. First, we start
by declaring variables for font family, font color, and a primary color. The
ability to create variables to store reusable variables is powerful because it
allows developers to write a value one time and change it in various locations.
Next, we create a rule that seems like any CSS rule, but instead of using a
combinator or a selector to target the paragraph tag within our div, we simply
nest the paragraph styling within the div styling. This means that styling will
only apply to paragraphs within that div. Finally, we use the built-in color
module to darken our primary color to create a 20% darker border.
90
Conquer CSS
The next step is compiling our SCSS into CSS that our browser will
understand. I use a tool in my code editor called Visual Studio Code to
compile my SCSS, but there are many methods out there that allow you to do
this. After compiling our SCSS, the compiler generates a CSS file that looks
like this:
div {
background-color: green;
width: 50%;
height: 300px;
border: 2px solid #001a00;
}
div p {
color: white;
font-size: 30px;
padding: 20px;
font-family: arial;
}
/*# sourceMappingURL=sass.CSS.map */
As you can see, this is all regular CSS we can understand. It may not look
like we saved a lot of time, but in using SCSS, you can cut down on a
multitude of lines when writing more complex stylesheets. When we link this
new CSS file in the head of our HTML and refresh the page, we get the
following output:
LESS
LESS is very similar to SASS when it comes to the feature set. LESS was
launched in 2009 and shipped with variables, nesting, and mixins—just like
SASS. Where LESS stands on its own is in its ability to perform operations.
Operations add the ability to perform mathematical calculations within your
CSS. This sophisticated tool is very attractive to developers who are used to
having the ability to perform these calculations in other languages.
While LESS’s syntax is designed with the same goal as SCSS of having
more succinct stylesheets before compilation, there are some distinctions
between the two. Let’s take a look at some LESS code to see how the syntax
differs from SCSS:
@font: arial;
@primary-color: green;
@font-color: white;
div {
background-color: @primary-color;
width: 50%;
height: 300px;
border: 2px solid darken(@primary-color, 10%
+ 10%);
p {
color: @font-color;
font-size: 30px;
padding: 20px;
font-family: @font;
}
}
As you can see, the code is vastly similar. Notice how the nesting is the
same as in SCSS. The only syntactic difference is the way we create and
reference variables. The darken mixin is the same as the darken module in
92
Conquer CSS
SCSS, but in LESS, the use of operations to calculate our darken percentage
is distinct. You can see that instead of 20%, I demonstrate the addition
operation by adding 10% to 10%. This isn’t necessary, but I have included it
to demonstrate the biggest differentiator between LESS and SCSS. If you’re
looking for a preprocessor that introduces more of the traditional logic that
other programming languages have, check out LESS.
Postprocessors
We’ve seen two different preprocessors, and we know that they let us extend
the features of CSS. There is, however, another approach to maximizing our
CSS in the form of a postprocessor. Postprocessors work differently from
preprocessors in that they evaluate your CSS and make it better after it’s been
written. Postprocessors use best practices to perform mutations on your CSS
to make it suitable for the browser.
Don’t worry if you don’t know what all of this means. As you become
more experienced with CSS and use postprocessors, these terms and features
will make more sense. Let’s explore some of our options when it comes to
postprocessors.
Pleeease
No, that’s not a typo. This postprocessor is actually called “Pleeease.”
Pleeease’s official motto is “All the annoying CSS stuff we don't want to do
in one tool!”—and for good reason. Pleeease provides the ability to add
WebKit prefixes if any are missing from your code. We won’t cover WebKit
prefixes in this book, but they essentially allow you to achieve much better
cross-browser support with your CSS. They also add fallback units in pixels
93
Ryan Boddy
if you are using responsive units like rems. This feature ensures that your
measurements always appear the way they should, even if the user is on a
device or browser that doesn’t support rems. Pleeease also minifies your code,
which is the process of removing whitespace, renaming long variables, and
removing comments for final production code to make it faster to load.
These are just a few features of Pleeease. If you are interested in giving
it a try, check out the documentation at http://pleeease.iamvdo.me/docs/.
PostCSS
PostCSS is similar to Pleeease in that it offers an abundance of
transformations that can be applied to your CSS to optimize it. Where it
differs is the ecosystem that has been developed around it. PostCSS is written
in JavaScript, so it is easy to create and share bits of functionality that you can
integrate for yourself. A rich collection of plugins for features like fonts, grids,
and fallbacks is available to be taken advantage of.
If you’re looking for the same feature set as Pleeease with the added
benefit of plugin availability, give PostCSS a try. You can find their
documentation on Github here:
https://github.com/postCSS/postCSS/tree/main/docs.
Using processors can show you what CSS may look like in the future as
this language grows and evolves. Programming languages are always changing
and improving. Many of the features that developers love from processors
have already been implemented in the language.
Consider processors to be crystal balls that allow you to see the future
of CSS. Do you want more logic to be introduced into the language? LESS is
already showing what that would look like. Do you want more built-in
94
Conquer CSS
functions like darken() or lighten() for color values? SASS/SCSS shows that off
wonderfully.
CSS is always getting better, and you can grow with it too now that you
have a firmer grasp on the fundamentals.
95
CHAPTER 9
C
SS is a wonderful language that allows developers to make the beauty
of their designs a reality. Not only does it make websites and
applications look good, but it also makes them accessible to billions of
people by allowing developers to create responsive interfaces that work on
any device. None of this would be possible without CSS, which is why it’s so
important. My goal with this book was to make CSS more accessible to you—
the developer, the dreamer, the creator. The goal is to make the web a more
beautiful place. I hope you’ve learned something in this book to help further
that goal.
96
AUTHOR BIO
Ever since the day he first opened up a computer science textbook in second
grade, Ryan Boddy knew he wanted to become a “computer scientist.” He
has pursued that dream since then and learned the valuable skills that became
the basis of a career in the software development industry. After holding a
slew of interesting jobs across several niches in the industry, Ryan decided to
merge his lifelong bucket list item of writing a book with his desire to share
what he had learned over the years.
Ryan resides in North Carolina with his amazing wife, son, and daughter.
He spends his spare time creating written and video content about the
software industry and web development.
97
ONE FINAL FAVOR…
Thank you again for reading Conquering CSS! This book means a lot to me. I
hope you got some value out of it!
I want to help others like you learn the magic of CSS so we can all create
a more beautiful web together. The easiest way to get this book in front of
more people is with a review on Amazon, or wherever you purchased it.
I’m asking you to be 100% honest. Did you love the book? Let me know.
Hated it? I welcome that feedback as well.
I already can’t thank you enough for reading, but a review would make
me endlessly grateful.
98