CSS Course

Cascading Style Sheets

Cascading Style Sheets (CSS) are mainly used to style websites, and add some animations. I'm not an expert nor fond of CSS because CSS frameworks such as Bootstrap are providing most of the CSS that I need. We are currently using CSS3, but maybe someday we will see CSS4 introducing new selectors (a lot of them are already available).

  • How to write CSS
  • What are selectors?
  • List of CSS properties that I'm using the most
  • What's responsive design?

Note: as you are doing in HTML, the good developer that you are 😎, you should test that your code is following the W3C standard using this validator. You may also want to minimize your CSS (to make your page faster, as the size of the CSS will be reduced), you can do that with a CSS minifier (note that in PHPStorm, you can configure a watcher to auto-compile css to min.css). If you want to use a CDN, please refer to the WEB course.

You can use SASS/Less to generate CSS, which are working like TypeScript for JavaScript, or PHP to factorize HTML code.


Introduction

A CSS is a list of rules that are made of selectors+properties. For instance, you can say that every text in a paragraph (selector "p") will be red (property color=red): this is a rule. They are three ways to write CSS.

Inline CSS 🤮CSS tag 🤢External CSS 😍

Every tag in HTML got an attribute called style. Simply write the CSS inside.

<p style="color:red;background: yellow;">
  ...
</p>

You can use one (or more) tag <style>, and put the CSS inside.

<style>
p {
  color:red;
  background: yellow;
}
</style>

You can put the CSS in another file, write the CSS as we did in style, and link it to the HTML with

<link rel="stylesheet" 
      href="/path/to/style.css">

This is the best way, as developers won't have to look at every file for CSS. You will also be able to use CDN to speed up your website.

Usually, when using an external CSS, we are calling it style.css, you can make one for when we want to print the page print.css, and/or you can have one CSS file per page.
@charset "utf-8"; /* optional */

/* a comment */
p {
  color:red;
  background: yellow;
}
HELP! I wrote some CSS, but I don't see any changes!?

They may be three problems 1: you didn't use the good selector, 2: another style is overriding yours, or 3: your page is rendering using the cached CSS. The tips we are given are

  • for 1: try using background="red" or something like that, to check that the selector is good
  • for 2: try using !important or check the CSS used in the developers' tools
  • for 3: CTRL+R or CTRL+SHIFT+R or SHIFT+F5 or CTRL+F5.

Selectors

This is a list of the selectors I know of

DescriptionCSSHTML matched
Tag selector
Simply write the tag, you want to select.
p { /* ... */ }
<p>Some text</p>
ID selector
Each tag can have one ID, each ID is unique within a page.
#my-id { /* ... */ }
<p id="my-id">...</p>
Class selector
Each tag can have one or more classes, separated by a space.

You can match a selector having every specified classes too.
You can also add a tag before a class.
.name { /* ... */ }
p.one.two { /* ... */ }
<p class="name">...</p>
<p class="one two">...</p>

Joker selector 🃏
I'm the only one calling it like that 😶.
You can use * to select everything
(🤮 you should use body/html instead of *)

* { /* ... */ }
<p>...</p>
<div>...</div>
<!-- .... -->
Pseudo-classes selector

You can apply a style to something, but only the element is in a predefined state.

You got :active, :checked, :focus, :disabled, :visited and many more. You also got :first-child, last-child, or :nth-child(1) to select a child.

button:hover { /* mouse over */ }
:not(p) { /* ... */ }
*:not(p) { /* same */ }
:is(h1, h2) { /* either h1 or h2 */ }
:where(...) { /* same, but
 the specificity=0 */ }
...
Property selector (or attribute selector)
You can select something according to the values of its attributes.

You got = (equals), *= (contains) etc.

input[type="radio"] {
  /* ... */
}
<p class="name">...</p>

And these four aren't selector, but you can use to factorize rules

DescriptionCSS
Comma

You can apply the same rules to a bunch of selectors by separating them with a , (comma).

p, a { /* ... */ }
Path

You can make a path by separating selectors with > (greater than).
Note that a > b means that b is a direct child of a.

p > a { /* ... */ }
Space

You can apply a selector to elements filtered by another.
This is the same as path without the constraint of being a direct child.

p a { /* ... */ }
Plus

The style is applied on the first child of the selector (ex: first link inside a paragraph).

p + a { /* ... */ }

Of course, you got more of them, as you can read here (W3Schools).


Values

Before digging into the properties, you must learn more about the values you can give them.

Size
  • a value (0 is the only one that should not have a unit)
  • a value with a unit (1px, ...). The most used unit is px (default, pixels), but you may check rem, pc, or vh.
  • a percent such as 100%
  • an expression resulting in a value calc(100% - 15px)

A lot of properties will usually take 4 values t r b l (respectively top-right-bottom-left). You can either use property-top: value (to only set the top) or a shortcut

  • padding: ALL; (t=r=b=l=ALL)
  • padding: Y X; (t=b=Y, r=l=X)
  • padding: U V W; (t=l=U, r=V, b=W)
Color

You can use

  • a name (red, yellow, etc.)
  • the RGB function (ex: rgb(r, g, b) such as rgb(255, 0, 0) for red)
  • the RGBA function (ex: rgba(r, g, b, a), with alpha the transparency)
  • the HEX code (ex: #dd4411 or #d41)
Variables

You may create variables (to store a color, a value, etc.).

/* declare */
:root { 
  --name: value;
}
/* use */
p { 
  color: var(--name);
}

CSS properties

The format is

selectors {
    property_name: property_value;
}

Notes

  • write one per line 👍
  • the ; (semicolon) is optional, but add it 👍
  • you may add !important to force a style 🤔
  • the last style is applied ("cascade" 👈), or the last with important
    • to be accurate, each selector have a specificity, which is used to determine what property is the most relevant (source)
  • you may use the value inherit to inherit the value of the parent

Usually, when you are learning CSS, you will go to other websites that you like, and learn by reading how they do something. You can also ask something on Stack Overflow, or you check websites such as W3Schools/YouTube (don't copy-paste code, usually websites are under copyright). I think that the best way to learn CSS, is to learn the syntax, then look on the WEB each time you need something new, and learn bit by bit, as there are too many properties.


My List of properties

Background
div {
    background: yellow; /** change background **/
    background: rgb(255,0,0); /** change background **/
    background: rgba(255,0,0, 0.8); /** change background with alpha=transparency **/
    background: #dd4441; /** use a hexadecimal code **/
    background: url("..."); /** url is a path or a real url **/
    /* if it's an image, you can play with it */
    background-size: 100% 100%;
    background-size: auto;
    background-size: cover;
    background-repeat: repeat;
}
Text
div {
    color: red; /* working like background */
    font-size: 15px; /* font size */
    font-family: "Open Sans", sans-serif; /* change font-family, try using
     "Open Sans" then ... until the last one. In case of something no-specific
     link "sans-serif" than any font passing the requirement is used. */
    font-weight: 400; /* font weight, you could also write bold, ligh,
     lighter, ... */
    line-height: 50px;

    text-align: justify; /* center, left, right, ... */
    text-decoration: underline #dd4441; /* add underline */
    text-decoration: none; /* remove underline */
}
Size and position
div {
    width: 5px; /* width */
    height: 5px; /* height */

    display: block; /* display value. You can use none to hide something */

    position: absolute; /* relative, fixed */
    top: 0; /* try to set a position */ 
    left: 0;
    right: 0;
    border: 0;
    z-index: 1; /* if two div at the same pos,
    who is on top ? the one with the highest z index */

    margin: auto;
    padding: 15px; /* all */
    padding: 15px 5px; /* top=bottom=15, left=right=5 */
    padding: 15px 5px 15px 5px; /* top, right, bottom, left */
    padding-bottom: 15px; /* manually */

    /* so convenient to center a div */
    justify-content: center;
    align-self: center;
    align-items: center;
    /* or you may have to look around flex box*/
    display: flex;
    /* or maybe you would like */
    float: left;
    float: right;
}
Others
div {
    border: 1px solid #202735; /* add border, size=1px, type=solid and black */
    border-radius: 4px; /* border radius, round some button for instance */
    
    cursor: pointer; /* change cursor to "click"=pointer cursor */
    outline: none; /* for button, outline shown on focus */

    /** content is too big and the size is not enough,
    how should we handle the overflow?
     */
    overflow:hidden; /* hide */
    overflow:auto; /* show a scroll bar */

    list-style-type: none; /* change list style 😅 */
}

This is almost everything I used, and I'm considering myself to be a beginner. You should at least know these ones

Property Effect
background set the background (image/color/...)
color set the color of the text
text-decoration: none; remove the underline under a link
display: none; same as the attribute hidden in HTML
display: flex; Read about flex, it's wonderful 😍
border: size solid color; add a border
padding gap between a component, and it's border
margin gap between a component, and the "outside"

Responsive design

This is most likely what will take most of your time, and why I switched to Bootstrap. Your user will use different resolutions when visiting your website, different browsers, and different platforms (mobile, tablet, computer, etc.). This is your job, that the website is properly rendered on each platform, and that's a practice called responsive design.

The first thing to do is to add this line in your HTML, so that the website will try to adapt itself according to the size of the screen

<meta name="viewport" content="width=device-width, initial-scale=1">

Then, we will write media queries. These are blocks in which you will declare the rules that should be used if the screen is lesser than "Xpx" or greater than "Ypx" or within "Xpx" and "Ypx".

@media screen and (max-width: 950px) {
    /* the style declared here will only
     be used is the width is lesser than
     950px. */
}

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

You can use that to hide/show some buttons, change some component's positions, ...

edit 02/09/2021: media queries are more complex than what I learned, you can read more here, as I saw a lot of times @media (min-width: 950px) {} instead of the code above with screen and.


Animations

I never used CSS animations (hence you may complete this part), but here are some links. It looks fun, and I hope someone will scout this for us


External resources

Guidelines

CheatSheets


SCSS, SASS, and Less

You can use Less, SASS, or SCSS to write a sort of enhanced CSS. Both are similar, but the syntax is a bit different. You may read JetBrains tutorial to configure watchers too (in PHPStorm) (you can enable/disable watchers).

npm install sass -g 
# watcher
sass --watch input.scss output.css
# or compile when you want
sass input.scss output.css

As always, W3Schools got a tutorial about SASS. SASS official documentation is quite good too.

My notes about the syntax
Variables
$name: #d41;
p { color: $name; }
Inheritance
p { }
p.red { @extend p; }
Nested tags
p { 
  color: #d41;
  span { color: #fc3; }
  &:hover { color: #0a53be; }
  :hover { color: #0a53be; }
}
Mixin (functions)
@mixin some-mixin {}
.button { @include some-mixin; }

@mixin padding-x ($value) { padding-left: $value; padding-right: $value; }
.button { @include padding-x(1rem); }

// you can also declare rules inside a mixing
// or variables, or give default value to arguments
@mixin some-mixin2 ($val: 0px) {}

// you can call it anywhere
@include theme("dark", ...);
Statements
@if $value == something {} @else if /* ... */ {} @else {}
//ternary: if($value == something, 'if_true', 'if_false')
@each $i in value1, value1  { .#{i} {} }
// 12 included (=>through)
@for $i from 0 through 12 {}
@while $i <= 12 { $i: $i + 1; }
Functions
// mix 50% of color 1 and 100-50% of color2
mix(color1, color2, 50%)
lighten(color, 50%)
darken(color, 50%)
opacity(color, 0.5)
Breaking into files You can split a SCSS into files=modules, the modules are starting with a _module.scss. Then, in the main file, use
@import 'module'
(or @use)

Sources