Cascading Style Sheets say how your HTML looks like.
These are CSS rules.
p {
color: pink;
font-weight: bold;
margin-left: 2em;
}
The selector defines which element(s) the rule is
applied to.
There are 3 types:
p {}
or
p strong {}
.warning {}
or
p.warning {}
#about {}
The selector is followed by a block of
one or more declarations. The block starts and ends
with the opening and closing curly brackets
{ }
.
Inside the block each declaration consists of the name of a property, a colon, and the value for the property. And at the end there is a semi-colon.
color: red;
selector {
property_1: value_1;
property_2: value_2;
property_3: value_3;
...
}
The block { }
is called
declaration.
color
before width
font-size
, then block-styling, e.g.
height
and width
* {
color: black;
font-family: Arial, sans-serif;
font-size: 1em;
}
h1 {
color: pink;
font-family: Georgia, serif;
font-size: 3em;
}
p, strong {
color: pink;
font-weight: bold;
margin-left: 2em;
}
p strong {
color: pink;
font-weight: bold;
margin-left: 2em;
}
.parent {
display: grid;
place-items: center;
}
.parent {
display: flex;
}
.child {
flex: 0 1 150px;
}
<head>
<link rel="stylesheet" href="style.css">
</head>
<head>
<style>
p {
color: blue;
font-size: 12px;
}
</style>
</head>
<head>
element.
<style>
tag.<p style="color:red">Some text.</p>
style
attribute.
/* always declare html element first - it's the biggest */
html {
background : #ffffff;
box-sizing: border-box;
font-size : 10px;
/*font-size : 0.75vw;*/
line-height : 1;
height : 100%;
scroll-behavior: smooth;
overflow-x : hidden;
width : 100%;
}
/* This selects ALL elements. Add it AFTER the html selector */
* {
color : #333333;
font-family : Helvetica, Arial, sans-serif;
font-weight : 400;
font-size : 2rem;
font-smooth : always;
line-height : 1.47;
margin : 0;
padding : 0;
outline : 0 !important;
text-align : left;
scroll-behavior: smooth;
}
/* from big to small: body selector is next, followed by header, main... */
body {
min-height : 100%;
min-height: 100vh;
height : auto;
position : relative;
overflow : hidden;
width : 100%;
}
/* group rules together, e.g. all text rules */
h1 {}
h2 {}
p {}
strong {}
a {}
The CSS Cascade is the way our browsers resolve competing CSS declarations.
Every time we add a CSS rule, it enters the CSS cascade.
The further down the cascade a declaration falls, the less likely it will end up as the final style.
!important
: When we add !important to
the end of our declaration, it jumps
to this level of the Cascade. Ideally, you reserve this to
override styles from third-party libraries.p {
color: orchid !important;
}
... [many rules in between] ...
p {
color: sandybrown;
}
The color of the p-tags would be orchid. !important
declarations fall on
the second level, while normal declarations fall on the fourth
level.
user agent stylesheet
.style
HTML property are the most specific
#id
.class
[checked]
and
[href="https://powercoders.org"]
, and
pseudo-selectors, like :hover
and
:first-of-type
type
, e.g. p {}
::before
and ::selection
A pseudo-class is used to define a special state of an element.
A pseudo-element is something that acts like an element, but is not an element. Thus, it cannot be manipulated by JavaScript.
Reference<p style="color: sandybrown">...</p>
p {color: orchid;}
A wins! Remember that inline styles fall on the
first level, while type rules fall on the fourth
level.
.paragraph {color: sandybrown;}
#paragraph {color: orchid;}
B wins! Remember that rules with a class selector
fall on the third level, while rules with an
id selector fall on the second level.
.paragraph:first-of-type {color: sandybrown;}
p.paragraph {color: orchid;}
Rule A has two "hits" on the
third level (1 class and 1
pseudo-class), whereas Rule B has
only one "hit" on the third level - its "hit" on a
lower (fourth) level doesn’t come into play.
p#paragraph {color: sandybrown;}
#paragraph.paragraph {color: orchid;}
Rules A and B both have 1 hit on
the second level (1 id), but Rule
B additionally has 1 hit on the
third level (1 class), which beats Rule
A's hit on the fourth level (1
tag).
Rules lower in the file overwrite rules higher in the file
p {
color: sandybrown;
}
p {
color: orchid;
color: black;
}
In order to deal with different browser styles people came up with stylesheets which would reset these styles or normalize them.
Even with reset or normalizing stylesheets in place, browser testing is mandatory.
Your browser can accept colors in many different ways:
Color name: | red |
Hexadecimal value: | #FF0000 |
RGB value: | rgb(255, 0, 0) |
RGBA value: | rgba(255 0 0 / 1) |
HSL value: | hsl(0°, 100%, 100%) |
HSLA value: | hsla(0° 100% 100% / 1) |
Examples:
If your color scheme works with different variations of the same hue (=color), use hsl(a):
--clr-accent-hue: 34;
--clr-primary: hsl(var(--clr-accent-hue) 88% 54%);
--clr-primary-light: hsl(var(--clr-accent-hue) 88% 75%);
color
background-color
border-color
text-decoration-color
font-*
properties.
font-family
<!DOCTYPE html>
<html>
<head>
<style>
h1.serif { font-family: serif; }
h1.sans { font-family: sans-serif; }
h1.mono { font-family: monospace; }
</style>
</head>
<body>
<h1 class="serif">This is serif</h1>
<h1 class="sans">This is sans-serif</h1>
<h1 class="mono">This is monospace</h1>
</body>
</html>
Serif fonts are called that because they have the little sticking out bits at the ends of bits of the letters. For example, at the left and right ends of the top of the T.
Sans-serif literally means "without serifs" – as you can see in the second heading these letters have no sticking out bits.
And monospace fonts might be serif or sans-serif. Their main characteristic is that all the letters are the same width.
The browser defines the default fonts.
body {
font-family: 'DejaVu Serif', 'Times New Roman', Times, serif;
}
h1, h2, h3, h4, h5, h6 {
font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;
}
pre, code, tt {
font-family: 'DejaVu Sans Mono', monospace;
}
You can list multiple fonts for a
font-family
entry. This is called
a font stack.
When the browser sees a font stack, it checks to see if the first font in the list is installed on the user's computer. If it is, it uses it.
If it's not, it moves on to the next font in the list. So you should list the fonts in the stack from most specific to least specific.
Names / Font stack | Type |
---|---|
Helvetica, Arial
|
sans-serif |
Courier New, Courier
|
monospace |
Georgia
|
serif |
Times New Roman, Times
|
serif |
Verdana
|
sans-serif |
@font-face {
font-family: 'Open Sans';
src: local('OpenSans Regular'),
url('/fonts/OpenSans-Regular-webfont.woff2') format('woff2'),
url('/fonts/OpenSans-Regular-webfont.woff') format('woff');
}
One of several online repositories of free fonts that make it very easy to include them in web pages
Try to find the Lato font & include it in your page
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
code
Icon fonts are text files that can be modified using CSS.
Pro:
Con:
... stands for Scalable Vector Graphics.
It is both an image format and a document format. There’s so much possible with it.
Some drawbacks...
SVGs are quickly becoming the new standard of web icons and animations.
They offer
font-size
font-size
sets the height of the font.
default font-size in the browser is set to 16px
16px = 1em
pt
: Points are a fixed
unit, from the printing era. 1 pt = 1/72 of an inch. Only used for
letter-spacing or word-spacing.px
: Pixels are a fixed
unit. 1 Pixel is the smallest unit of a digital image that can be
displayed.%
: Percentage is a
scalable unit and calculates the size based on the default 16px (=
100%).em
: Scalable unit and
calculates the size based on the default 16 px (= 1em). The em
takes the width of the M as base.rem
:
Scalable unit similar to
em
. The r in rem stands for root.
The rem unit is relative to the root (html)
element.
vw / vh
: Scalable unit
based on viewport width / height. More used for
block-level elements than text.ch
em
versus
rem
strong
or em
in
each paragraph
Now change em
to rem
. What changes?
font-weight
says how bold the text should be
strong {
font-weight: bold; /* Default */
font-weight: 700; /* Default */
}
strong {
font-weight: normal; /* Disabled bold */
font-weight: 400; /* Disabled bold */
}
font-weight
says how bold the text should be
.bolder {
font-weight: bolder; /* bolder than bold */
font-weight: 800; /* bolder than bold */
}
.lighter {
font-weight: lighter; /* less bold */
font-weight: 200; /* less bold */
}
font-style
used for italic variations, rare
em {
font-style: italic; /* Default */
}
em {
font-style: normal; /* Disabled italic */
}
em {
font-style: oblique; /* simulates italic */
}
line-height
body {
font-height: 1.45;
}
font
shorthandp {
font: italic normal bold normal 3em/1.5 Helvetica, Arial, sans-serif;
}
p {
font-style: italic;
font-variant: normal;
font-weight: bold;
font-stretch: normal;
font-size: 3em;
line-height: 1.5;
font-family: Helvetica, Arial, sans-serif;
}
background-color: lightblue;
background-image: url("img_tree.gif");
background-position: 0 0;
background-size: cover;
background-repeat: no-repeat;
background-origin: content-box;
background-clip: content-box;
background-attachment: fixed;
background: lightblue url("img_tree.gif") no-repeat fixed center
/ cover;
You can add multiple backgrounds as layers on top of each other by adding them in one line, seperated by comma.
background-color: white;
background-image:
linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%),
linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%);
background-size:100px 100px;
background-position: 0 0, 50px 50px;
body {
width: 100%;
height: 100vh;
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
}
@keyframes gradientBG {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
HTML comment
<!-- This is a comment -->
CSS comment
/* This is a comment */
Comments can be used to organize your code into sections so you (or someone else) can easily understand your code. It can also be used to 'comment out' large chunks of code to hide it from the browser.
Document flow is the arrangement of page elements, as defined by CSS positioning statements, and the order of HTML elements.
Regarding the order of the HTML elements, their definition as inline or block-level element defines the space they take up in the document.
display
defines how an element is displayed. You can turn block-level elements to inline and vice verse.
a {
display: block; /* block-level element */
}
h1 {
display: inline; /* inline element, will break at end of line */
}
display
defines how an element is displayed. You can turn block-level elements to inline and vice verse.
li {
display: inline-block; /* appears inline, does not break across lines */
}
#footer {
display: none; /* hidden */
}
display: inline-block
Block-level elements are stacked underneath each other in one column.
Changing their display
-property to
inline-block
results in a row of these
elements.
Is the maximum width of the parent (wrapping) container reached, the elements will automatically wrap into a new line.
inline-block
elements need to have a
width defined.
Use vertical-align
to make sure that the elements are
aligned properly in one row.
When two elements with display: inline-block
are
sitting next to each other, whitespace between them becomes a space
character. Remove the whitespace.
The box model is used to describe an element's dimensions and structure. It is made up of four boxes:
width
is the width of the content areaheight
is the height of the content areabackground
properties apply to padding as well as
contentpadding
adds to the total size of the boxborder
adds to the total size of the
boxbox-sizing: content-box
The total height of an element is the sum of
The total width of an element is the sum of
box-sizing: border-box
Set border-box once on html selector and inherit for all other elements.
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
* {
box-sizing: border-box;
}
Some 3rd party plugins / components might require content-box model. With the best practice solution you ensure that those plugins will still be styled correctly.
margin
Four values: 10px on top, 5px on right, 3px on bottom, 5px on left
margin: 10px 5px 3px 5px; /* clockwise order: top right bottom left */
Two values: 10px top and bottom, 15px left and right
margin: 10px 15px; /* top/bottom right/left */
One value: 15px on all side
margin: 15px;
One side: 10px only on top
margin-top: 10px;
margin: auto
If a margin is set to auto on a box that has a given width, it will take up as much space as possible.
Centered
margin: auto;
width: 50%;
Flush right
margin-left: auto;
margin-right: 0.5rem;
width: 50%;
Collapsing margins happen when two
vertical margins come in contact with one another.
If one margin is greater than the other, then that
margin overrides the other, leaving
one margin.
This happens in these 3 cases:
<body>
<h1>Title</h1>
<p>Paragraph</p>
</body>
h1 {
margin-bottom: 25px;
}
p {
margin-top: 50px;
}
You would expect 75px, but instead you get
50px margin between the h1
and the
p
.
It's like the bigger margin ate the smaller one:
bigger margin = total vertical margin
h1 {
margin-bottom: -25px;
}
p {
margin-top: 50px;
}
50px + (-25px) = 25px
If one margin is negative, the negative margin is subtracted from
the positive margin, reducing the total vertical margin.
If both margins are negative, the bigger negative margin eats the
smaller one:
bigger negative margin = total negative vertical margin
padding
Four values: 10px on top, 5px on right, 3px on bottom, 5px on left
padding: 10px 5px 3px 5px; /* clockwise order: top right bottom left */
Two values: 10px top and bottom, 15px left and right
padding: 10px 15px; /* top/bottom right/left */
One value: 15px on all sides
padding: 15px;
One side: 10px only on top
padding-top: 10px;
*background
properties apply to padding as well as
content.
border
Borders are specified as "thickness, style, color."
You can
specify each property separately, or all three together.
border: 1px solid #ff0000;
border-top: 4px dotted #000000;
border-width: 10px;
border-style: dashed;
border-color: #666666;
position: static
position: relative
position: absolute
z-index
.
position: fixed
position: sticky
hidden
,
auto
,
scroll
height
set then the sticky
element won't have any area to stick to when scrolling. This
happens because the sticky element is meant to stick/scroll within
the height of a container.
float
Is used to solve the parent height problem of floated elements
.clearfix:before,
.clearfix:after {
content:"";
display:table;
}
.clearfix:after {
clear:both;
}
.clearfix {
*zoom:1;
}
Use the .clearfix
snippet to ensure the parent element
takes up enough space in the document flow.
Use clear
if you want following elements to move below
the floated element.
display: flex
display: flex;
to create a flex container.justify-content
to define the horizontal
alignment of items.align-items
to define the vertical alignment of
items.flex-direction
if you need columns instead of
rows.row-reverse
or
column-reverse
values to flip item order.
order
to customize the order of individual
elements.align-self
to vertically align individual
items.flex
to create flexible boxes that can stretch
and shrink.Flexbox is an easy way to create responsive websites as scalability is built-in.
With the property flex
on the items you have the first
step for a responive website.
Depending on the flex-direction
the properties
justify-content and
align-items switch meaning.
Interactive game to practice flex
It is the latest CSS layout technique.
All
major web browsers
support it though, so use it.
display: grid;
to create a grid container.grid-template-rows
to define the number (and
height) of rows.grid-template-columns
to define the number (and
width) of columns.grid-gap
or grid-row-gap
/
grid-column-gap
to define the gutter between grid
items.
display: grid
fr
unit to create flexible grid tracks. It
represents a fraction of the available space in the grid
container.fr
units with other units like px,
em or %.grid-row-start
and
grid-row-end
accordingly.
grid-template-areas
to define names for your
grid, e.g. header, content, sidebar and footer.grid-column-start
and
grid-column-end
.
grid-auto-rows
,
grid-auto-columns
and
grid-auto-flow
.
justify-items
and align-items
to
align the items inside your grid.It is not one or the other. Mix them, use them both.
Newspaper-style columns, often used as fallback for
flex
and grid
layouts or for masonary-like
layouts (like pinterest).
column-count
to define the number of
columns.column-width
to define the width of each
column.column-gap
to define the gutter/margin between
the columns.column-rule
to display a vertical line between
the columns.column-span
on child elements you want to span
all columns.break-inside
and similar properties on children
to control content breaks.
flex
, grid
and multicol
are
responsive by default.
Using one or more of these layout techniques will make your website reponsive already.
A media query consists of a test, followed by as many CSS rules as we want, with the rule block enclosed in a set of braces. If the test condition is false, the browser simply ignores the rule block and moves on.
A media query can be used to check for a particular condition such as the width and height (of the browser window), device width and height, orientation or resolution.
@media screen and (min-width: 50em) { … }
Media queries are used to define breakpoints for today's Reponsive design:
... are used to target specific devices, e.g. iPhone 6+,
iPhone
X or Samsung Galaxy S3.
Today there are hundreds of different phones of several generations.
With different screen sizes, resolutions and ratios.
Device-specific breakpoints are just not practical anymore.
/* Portrait */
@media screen and (orientation:portrait) { /* Portrait styles here */ }
/* Landscape */
@media screen and (orientation:landscape) { /* Landscape styles here */ }
/* Non-Retina */
@media screen and (-webkit-max-device-pixel-ratio: 1) {}
/* Retina */
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (min-device-pixel-ratio: 1.5) {}
Retina is Apple's brand name for double- and high-density screens. All manufacturers create similar displays.
Pixel-based images will look rasterized on high-density screens unless they have four times the size they are displayed at.
Don't target devices, add breakpoints when the design breaks (custom breakpoints).
Use em
unit instead of pixels to define a breakpoint.
Vertical breakpoints can come in handy, e.g. using multicol layouts or big typo.
... are quite new and most browsers have implemented at least parts of it. Check out caniuse.com to see which browsers already support which media query.
@media (pointer:coarse) {
.which-pointer::after {
content: "Are you on a touchscreen device?";
}
}
@media (pointer:fine) {
.which-pointer::after {
content: "Are you using a mouse or trackpad?";
}
}
@media (hover) {
.can-i-hover::after {
content: "You look like you can hover.";
}
}
@media (hover:none) {
.can-i-hover::after {
content: "I don't think you can hover.";
}
}
Next to media queries breakpoints are also used for responsive images.
<img srcset="elva-fairy-320w.jpg 320w,
elva-fairy-480w.jpg 480w,
elva-fairy-800w.jpg 800w"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
srcset
srcset
defines a list of possible images with its
real-size width (with the unit w).
sizes
sizes
defines a set of media conditions and which width
would be the best to use in these conditions.
Depending on the resolution different sizes of the image will be
displayed.
The browser will:
The picture
tag gives you more
control over which image will be displayed.
<picture>
<source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
<source media="(min-width: 800px)" srcset="elva-800w.jpg">
<img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
</picture>
em
, rem
and
vw
, %
clamp
clamp
clamp
takes 3 parameters:
minimum, preferred and maximum valueclamp
img {
width: clamp(400px, 60vw, 600px);
}
clamp
* {
font-size: clamp(1.1rem, 0.7153rem + 1.6368vw, 1.5rem);
}
font-size
will be set at
1.1rem
.
0.7153rem + 1.6368vw
becomes
greater.
font-size
value will be
calculated by the formula of
0.7153rem + 1.6368vw
.
1.5rem
.font-size
will be set
at 1.5rem
.:root {
--clr-primary: #e19785;
--clr-body: #1c1c1c;
--clr-bg: #ffffff;
--clr-footer: #ededed;
--clr-image: #c5c5c5;
--base-offset: clamp(3rem, -0.9364rem + 10.9344vw, 14rem);
--base-offset-h: 0 clamp(1.5rem, -0.4682rem + 5.4672vw, 7rem);
--base-offset-v: 2.5rem 0 2.5rem;
--base-width: 136.6rem;
}