CSS
These are my notes from the fantastic (free!) course on CSS in the Frontend Masters' bootcamp. Definitely check it out, I wish I'd known about it when I was starting out.
Basics
All html elements are boxes. A great way to see what you are doing is to give elements borders. Then you can see exactly how large they are and where they lay on the page.
Parents and children:
The property of a parent will affect the children (for the most part, depending on the selector, e.g. most font properties), unless they are overridden:
<div><h1>Hi</h1></div>
with the style of:
div {
color: blue;
}
will make the text color of the h1
blue.
Specificity
The more specific the selector, the higher precedence it will have.
You can chain classes together without a space to increase specificity:
.main-brand.title-5 {
color: red;
}
.main-brand {
color: green;
}
In the above, the first selector (with two classes) will be applied, even though it is higher in the cascade (literally higher in the file), because it has two classes, and is therefore more specific.
The ID selector takes the highest precedence and will override any other selector.
The !important flag will override anything else, including ID's.
For these reasons, it's generally better not to use either ID or !important - use classes (by adding a second class or combine classes and tags) to get more specific so they can then be overridden later if necessary without too much effort (or using ID's or !important). It makes styling much easier if everything uses one class, and occasionally two classes (if necessary).
Descendant Selectors
Another trick that can be used if there aren't that many elements on a page, or if they are fairly deeply nested, is combining type selectors (but it's generally easier to just add a class). To do this, chain the selectors together with spaces:
div ul li { color: red; }
will only select an li
element that is inside a ul
element, that is inside a div
.
However, using descendant selectors is not very specific (another reason to use classes), but can be made more so with the >
symbol:
/* selects ANY paragraph that inside ANY div, no matter how deeply nested */
div p {
color: red;
}
div > p {
/* will only select a p tag directly inside a div (first child) */
}
The reason to avoid using these is if someone ever changes the structure of the page (or the tags), your CSS will break. A class can remain on any element, regardless of type, at any position on the page.
Specificity is calculated
Note that the specificity is based on number values, which can be researched for more granular control if necessary, but the broad strokes are that CSS specificity can be thought of in the following order (lowest to highest specificity):
- Type selctors (tags:
h1
) and Pseudo elements::before
- Classes
.main
, attributes[type="radio"]
, and Pseudo Classes:hover
- ID selectors
#hero-image
- Inline styles always override any external style sheets.
-
!important
overrides everything else.
To learn more, Emma Bostonian wrote a great article on it at https://dev.to/emmabostian/css-specificity-1kca
This includes the math for how to calculate specificity which can be helful if you're having trouble.
Another great resource is the 'specifishity' chart at http://www.standardista.com/css3/css-specificity/
Pseudo Classes
These come after the selector, with no space, and a colon at the beginning. They are most commonly used for interactivity (things like links):
a:hover {
color: red;
}
Other handy Pseudo Classes
:focus
:visited
:active
:checked
:first-child
:last-child
:nth-child(3)
put in the child number in the parentheses
...and more that can be googled.
Pseudo elements
Not as frequently used, but handy to know.
The ::before
and ::after
pseudo-elements in CSS allows you to insert content onto a page without it needing to be in the HTML. While the end result is not actually in the DOM, it appears on the page as if it is, and would essentially be like this:
div::before {
content: "before";
}
div::after {
content: "after";
}
<div>
before
<!-- Rest of stuff inside the div -->
after
</div>
Layout
CSS is used not just to style elements but to lay out the page how it should look.
Block level elements always start on a new line and automatically span the width of their containers (think: building block).
Inline elements (e.g. the a
, em
, and strong
tags) only take up the amount of space required to hold their content: the <a>hello</a>
tag will only take up exactly the amount of space to enclose the word 'hello'.
Another noteworthy feature of inline elements is that padding and margins can only be added to the sides, not the top and bottom.
This property can be manually changed by using display: block;
Using the property display: inline-block;
does not add a line-break after the element, so the element can sit next to other elements, and allows to set a width and height on the element. In practice, this method is commonly used to get items to appear in a row as opposed to a column, as in a navbar with a ul
.
To make sure the document is always correctly sized to the window with no overlap or scrollbars is:
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
Display properties
All tags have a default display property, that then can be overridden using CSS.
block
spans the entire width of the container.
inline
is only as large as its text.
inline-block
is a hybrid of the previous two. The browser will place the tag inline, but will still allow you to control the height, width, padding, and margins (whereas an inline element does not allow any modifications to the height propery).
flex
and inline-flex
are similar to block in that they affect the tags around them like block
(covered in depth later).
grid
and inline-grid
are more advanced display modes like flex
(covered later), but only supported by relatively modern browsers.
table
will make something act like a table (even if it's not a table). Generally, it's better to use <table>
in the HTML for this.
Width and Height
Width
Using percents is an easy way to divide up the width of a page or section (because the math is easy to do in your head), and the percentage will be relative to the size of the container.
Height
Elements/boxes have a height property as well, but a generally good practice is to not set the height property manually, but to set the height and use auto
for the width, which will allow it to resize and be responsive. Another reason is that setting the height manually won't allow for the container to expand if, say a bunch of content is added after originally styling it.
One exception is when a div contains only an image, since there is no other content to give the element height, it must contain a height in order for the image to appear (i.e. if you have a 300px image, set the container to 300px).
Margin and Padding
Padding is around the content, up to the border.
Margin is the spacing between the border and the next element.
By default, the width
property does not include border and padding (just the content), so it's very handy to declare at the top of every CSS file:
* {
box-sizing: border-box;
}
This will make it so that all width measurements include both the padding and the border.
To quickly center all content within the parent, use margin: 0 auto;
. The shorthand here is: margin: top/bottom, left/right;
, but it can also be set with 4 values - Top Right Bottom Left (TRBL, mnemonic 'TRouBLe'), and is the equivalent of margin: 0 auto 0 auto;
Float and Clear
Floats will move an element to the side of the page, and the next element will 'stick' to the side that has the open space.
Floats feature rows and cells. Rows clear the floats on the cells. The source order determines the display, and is fairly limited as to options. All cells are equal heights.
One thing to note is that if there other elements below the next one, they will never be higher than the height of the preceding element, no matter how large the screen size (e.g. if box 1 is floated left, and two more boxes, box 3 will never be higher on the page than box 2).
float: left;
, and float: right;
are how they are declared.
If you float, then you need to clear!
There is an 'incantation' (aka a formula) that is commonly used to make sure that the parent element that contains any floats will not have elements that end up outside the container (clearing the floats). It is:
parentSelector::after {
content: "";
display: table;
clear: both;
}
If you need to rearrange the columns for some reason, this can be accomplished with another incantation:
[class*="col-"] {
Flexbox
Flexbox only works with parents and children, known as the flex container and items respectively. It does not work with descendants or ancestors beyond parents/children. A common use case is using a ul
to make a navbar.
Most changes to flex are made on the parent container, not the items themselves.
The main axis is the direction of the flexbox: for columns, it's up to down, and for rows it's left to right. The cross axis is the dimension perpendicular to the main axis.
For some older browsers, prefixes are required, so check canIuse.com to see if it's necessary.
All properties can be found here: https://static.frontendmasters.com/resources/2017-10-03-responsive-web-design-flexbox-css-grid/Flexbox-and-CSS-Grid-Properties-Cheat-Sheet.pdf
Some useful properties are:
On the container
display: flex;
set on the container to make the items go into a row.
flex-flow: column;
to change this to a stacked list.
flex-flow: row wrap;
manually sets the items in a row, and wrap them to new lines.
flex-flow: nowrap;
will prevent the items from ever wrapping to a new line.
flex-direction: row-reverse;
will reverse the order of the elements.
justify-content
has a number of properties that can be set, and controls the way the items are laid out, some of which are:
-
justify-content: flex-start;
sets the items to hug the left side of the container. -
justify-content: flex-end;
sets the items to hug the right side of the container. -
justify-content: center;
centers the items in the container. -
justify-content: space-around;
sets evenly sized spaces on the left and right of each of the items, including the start and ending items. -
justify-content: space-between;
sets an even amount of space only between items.justify-content: space-evenly;
will evenly space everything.
align-items:
will align the items on the cross axis to the flex-direction. It has the flex-end
, flex-start
properties.
There is also flex-center
, which centers them in the parent, and stretch
which will modify the height of anything that doesn't explicitly have a height set to fit the parent. It also has a neat feature where all elements that doesn't explicitly have a height set will stretch to match the height of the tallest element that does have a height set.
Centering with flexbox
To make sure everything stays centered (text inside the items, and the items themselves), set
.centered-box {
display: flex;
align-items: center;
justify-content: center;
}
and no matter what the width or height of the parent, the items and content will stay centered.
Manipulating the items
Shorthand
The shorthand property for this is to use flex:
followed by the values for Grow Shrink Basis
, or they can be written out individually.
flex-grow: value;
where the value is how much the unit will grow relative to the other units as the screen size changes. The default is that they all resize equally.
flex-shrink: value;
, is the same as the above, but for when the items are shrinking.
flex-basis: value;
is the width of the items, where the values are some unit of measure (commonly percentages or viewport units). Never use width on flex items, use flex-basis
instead.
Order
Using order
you can individually override align-items using align-self
, definitely worth looking at more:
.box-1 {
align-self: flex-end;
order: 5; /* the higher the number the earlier direction it will appear */
}
On the items:
flex-basis: 10%;
will override the default box sizing and set it to roughly 10% of the total size of the container instead.
Patterns for writing CSS
Write all of the default styles for multiple elements first, then add the specific styles for each element in their own selectors futher down in the file. E.g. if you have a number of button types on a page/site, and you want them all to have similar properties (size, font, border, etc.), then write those general rules for all buttons, then add the specific (or override) styles later in the CSS file (ideally with comments):
.ex-btn {
background-color: #eee;
border: 2px solid #aaa;
padding: 4px 15px;
font-weight: bold;
font-size: 17px;
cursor: pointer;
}
.ex-btn-warn {
/* inherits from .ex-btn */
/* above comment shows where to look for default styles */
color: white;
background-color: crimson;
border-color: darkred;
}
.ex-btn-success {
/* inherits from .ex-btn */
color: white;
background-color: limegreen;
border-color: green;
}
Another neat trick to quickly change styles is to right click on the element and choose 'inspect element'. In the devtools, you can turn styles on or off, and in the 'This Element' box, even add styles. Once it looks the way you want, you can just copy and paste the code from the 'This Element' box into the editor, which allows for quick iteration.
In the 'Computed' tab, it will show the exact values of the content, paddding, border, and margins. The values can be clicked on and modified directly as well.
There's even a color dropper tool that can be used to find out a color on a page (in Firefox at least, in Chrome it shows up in the popup when using 'inspect element')
Interesting properties:
There is a a text-decoration: overline property (a line above like underline).
Resources
https://htmlcheatsheet.com/css/
https://frontendmasters.github.io/bootcamp/css
https://frontendmasters.com/bootcamp/introduction-css/
list of all css properties:
https://meiert.com/en/indices/css-properties/
https://css-tricks.com/nerds-guide-color-web/
Tools:
BrowserStack at https://www.browserstack.com/ can test your CSS for compatibility across browsers.
ColorZilla extension lets you pick colors you see on screen and will give you the hex, rgb, etc. color values.
Top comments (0)