Cascading Style Sheets (CSS)

Cascading Style Sheets (CSS) are used to style and animate

  • ๐ŸŒ Websites
  • ๐Ÿ–ฅ๏ธ Desktop applications (Electron/JavaFX/...)
  • ๐Ÿ“ฑ Mobile applications (Android XML layouts/...)
  • ...

Where to learn?

CSS versions

โš ๏ธ CSS selectors/rules are now modularized, so CSS3 is the last CSS version. You should refer to caniuse to see what properties/... are supported, and "CSS4"/CSSDB for potential new features.

Some CSS tools

๐Ÿš€ CSS frameworks ๐Ÿš€

As CSS rules can be complex (responsive design, accessibility), many CSS frameworks with predefined rules were created.

Based on Material Design (Google UX Guidelines)

๐Ÿซ About CSS ๐Ÿซ

CSS files (.css) are defining rules to apply on a target called selector. A rule is made of a property, and its value.

Example: Links should have the color blue. Every text in bold should have a yellow background.

a {
    color: yellow;

b {
    background: blue;
  • Selector: Links (a) and texts in bold (b)
  • Rule
    • Property: color, or background
    • Value: yellow, or blue


  • ๐Ÿ”Ž One rule per line is a good practice
  • ๐Ÿ”Ž The semicolon (;) is mandatory (unless there is only one rule)


Styles are applied in cascade! There could be many selectors that are defining a rule that could be applied to the same tag.

If there are conflicts (ex: two selectors defining the same property), the Specificity is used to determine which rule is applied. In a nutshell, every selector has a weight (~=how specific the selector is) which is used to determine which rule is more important.

a { color: yellow; }
a:hover { color: red; } /* will override the other */

โžก๏ธ You can use !important to manually force a style to be applied.

a { color: yellow !important; }
a:hover { color: red; } /* won't override the other */

Getting started

There are 3 ways to write CSS for a website.

Inline CSS ๐ŸคฎSTYLE tag ๐ŸคขExternal CSS file ๐Ÿ˜

You can use the attribute style to add inline CSS. It's convenient for testing.

<p style="background: darkcyan">

You can use <style> tags. They are usually added in the head, but you can add them everywhere.

    p {
        background: darkcyan;

You can link an external CSS file. This is the proper way to do it (CSP policy+caching, CDNs, SoC...).

<link rel="stylesheet"

โš ๏ธ Note: Modern browsers are usually caching CSS files. If you changed a file, and don't see any changes, reload the page while ignoring the cache: CTRL+SHIFT+R or SHIFT+F5 or CTRL+F5.


A selector is a target, or a set of targets, on which the style will be applied. โžก๏ธ To test a selector, we usually change the background. If the background changes, it means that the selector works.

    background: yellow;

Tag selector

The style will be applied to every element having this tag.

p { /* ... */ }

ID selector

The style will be applied to the tag having the matching ID.

<p id="my-id">xxx</p>
#my-id { /* ... */ }

Class selector

The style will be applied to any tag having this class.

<p class="name ...">xxx</p>
.name { /* ... */ }

Universal selector

The style will be applied to every element.

* { /* ... */ }

Property/Attribute selector

We can select something based on them having a property.

<p hidden>xxx</p>
[hidden] { /* ... */ }

We can select something based on the value of a property.

<input type="text" />
<path d="16 95 3"/>
[type="text"] { /* ... */ }
[d~="95"] { /* ... */ }


They are additional selectors based on a state/condition. These are called Pseudo-classes. See the complete list on W3Schools.

:hover { /* mouseover */ }
:not(p) { /* every tag aside from "<p>" */ }
:not(p, a) { /* [...] aside from "<p>" and "<a>" */ }
:is(h1, h2) { /* either h1 or h2 */ }
:first-child { /* [ ... ] */ }
:nth-child(0) { /* [ ... ] */ }
:last-child { /* [ ... ] */ }

โžก๏ธ There are also Pseudo-elements providing access to a fake element. They start with :: such as ::first-line.

๐Ÿ‘‰ Chain selectors

We can chain any selectors!

<p class="one two">xxx</p>
<input type="text" hidden>xxx</input> { /* ... */ }
input[type="text"][hidden] { /* */ }

โžก๏ธ Using .name is the same as *.name...

๐Ÿ›ฃ๏ธ Combinators

They can apply a selection based on the structure of the page.

div, a { /* applied on both "div" and "a" */ }
div > a { /* "links" having a "div" as parent */ }
div a { /* "links" having a "div" as ancestor */ }
p + a { /* an adjacent "link" right after a "p" */ }

โžก๏ธ Obviously, you can use any selectors instead of a, p, and div.

๐Ÿฅ‚ Properties Values ๐Ÿฅ‚

Properties (ex: background) are taking values (ex: a color).


You can use rgb, rgba (alpha=transparency), a hexadecimal code...

.x {
    background: red; /* alias to a color */
    background: rgb(255, 0, 0); /* red */
    background: rgba(255, 0, 0, 0.8); /* lighter red */
    background: #dd4441; /** hexadecimal code **/


You must provide a value, and a unit.

.x {
    width: 10px; /* px = pixels */
    margin: 0; /* no unit needed */
    height: 100%; /* a percentage */


You can only do some calculations inside calc.

.x {
    width: calc(100% - 15px);


:root {
    --primary-color: red;
    --p1: 10px;
p {
    color: var(--primary-color);
    padding: var(--p1); /* usage */

๐Ÿ”Ž Properties ๐Ÿ”Ž

๐Ÿ‘ป I'm not too familiar with CSS, these examples are properties that I used before moving to CSS frameworks. ๐Ÿ‘ป


.xxx {
    background: yellow; /* change background */
    background: url("..."); /** path/URL **/
    /* if it's an image, you may use */
    background-size: 100% 100%; /* expand */
    background-size: auto; /* auto */
    background-size: cover; /* cover */
    background-repeat: repeat;
    /* mix of rules */
    background: url("...") no-repeat fixed;


.xxx {
    color: #FFDD33; /* text color */


.xxx {
    font-size: 15px; /* font size */
    /* the second/... are fallback fonts (if not found) */
    font-family: "Open Sans", sans-serif;
    font-weight: 400; /* bold, light, lighter, ... */


.xxx {
    display: block; /* show */
    display: none; /* hide */

    overflow:hidden; /* hide */
    overflow:auto; /* show a scroll bar */

    opacity: 1;

    position: absolute; /* relative, fixed */
    /* set a specific value */
    top: 0; left: 0; right: 0; border: 0;
    z-index: 1; /* on top = the highest z index */

Text utilities

.xxx {
    line-height: 50px; /* ... */
    text-align: justify; /* center, left, right, ... */
    text-decoration: underline #dd4441; /* add underline */
    text-decoration: none; /* remove underline */
    white-space: pre-line; /* multiline */

Size, Margins, Padding

.xxx {
    width: 5px; /* width */
    height: 5px; /* height */

    padding: 15px; /* all */
    padding: 15px 5px; /* y=15, x=5 */
    /* top, right, bottom, left */
    padding: 15px 5px 15px 5px;
    padding-bottom: 15px; /* one by one */
    /* you can use the 4 above with margin */
    /* and, you have this "new" value */
    margin: auto;


.xxx {
    justify-content: center;
    align-self: center;
    align-items: center;
    float: left;
    float: right;


.xxx {
    /* add border, size=1px, type=solid and black */
    border: 1px solid #202735;
    border-radius: 4px; /* round corners */


.xxx {
    cursor: pointer; /* change cursor */
    list-style-type: circle; /* change list style */
    list-style-type: none; /* change list style */

Responsive design & Accessibility

You should adapt your website according to

  • ๐Ÿ‘‰ the browser (browser-specific CSS properties)
  • ๐Ÿ‘‰ the screen size (media queries, responsive sizes...)
  • ๐Ÿ‘‰ the mode (light/dark) (media queries)
  • ...

Adapt to the size of the screen

First, you need to add one of these lines in your head, to make the website automatically adapt itself to the size of the screen.

<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, height=device-height, viewport-fit=cover, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

Then, in your CSS, you can write CSS code that will only be executed when the condition of the media query is fulfilled.

@media screen and (max-width: 950px) {}
@media screen and (max-width: 1100px) and (min-width: 950px) {}

Light/Dark theme

In modern browsers, there is a media query to detect the theme.

<link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)">
<link rel="stylesheet" href="light.css" media="(prefers-color-scheme: light)">

โžก๏ธ The CSS files are intended to be used to define variables in :root, which will be used by another CSS file, such as main.css.

You can add a media query directly inside the CSS too.

@media screen and (prefers-color-scheme: dark) { }
@media screen and (prefers-color-scheme: light) { }

๐Ÿ‘ป To-do ๐Ÿ‘ป

Stuff that I found, but never read/used yet.