CSS Crash Course
đź““

CSS Crash Course

What is CSS (Cascading Style Sheets)?

 
If web design is a house:
  • HTML is the structure (i.e. wood, bricks, concrete, foundation)
  • CSS is the style (i.e. paint, landscaping)
  • JavaScript is the function (i.e. electric, plumbing, heating, water)
When working with CSS, it is possible to define more than one style for a single HTML element. Because of this, the CSS needs to know which rule to actually apply to it. When we say "cascading", we are referring to this fact.

Purpose of CSS

Two purposes:
  1. Change the layout
  1. Change the style

The 3 Main CSS Selector Types

  1. By tag
/* Select by tag */ p { color: red; }
  1. By class
/* Select by class */ .main-text { color: red; }
  1. By ID
/* Select by ID */ #first-paragraph { color: red; }
 
Difference between class and id - class can be applied to multiple tags and id can be only applied to one, that’s how JS can like scroll to that particular component

CSS Combinators

 
Selecting descendants: With CSS, we can combine selectors separated by spaces to identify descendants of elements.
/* Select all li elements that exist inside the element with a class of .main-body */ .main-body li { color: green; }
Selecting children: If you only want to select the children (first descendant, no nesting) we use >
#main > p { color: blue; }
 

Selecting multiple HTML elements with CSS

 
Suppose we want to apply common properties to two elements, but style other properties separately, you do as such
.box-1, .box-2 { width: 200px; height: 200px; } .box-1 { border: 1px solid green; color: green; } .box-2 { border: 1px solid blue; color: blue; }
By separating each selector using a comma, we can select multiple HTML "groups" at the same time. In the example above, we are applying the width and height properties to both selectors and then individually applying border and color (text color) styles to each.
 
We could also achieve this by using
.box { width: 200px; height: 50px; } .box-1 { border: 1px solid green; color: green; } .box-2 { border: 1px solid blue; color: blue; }
 

Pseudo classes

These apply only when the user interacts with document in some way. For example
  1. :hover - The user moves their pointer over an element
  1. :focus - The user focuses the element by clicking
button:hover { color: red; cursor: pointer; }
 

Specificity of the CSS selector

 
The importance of the selector is indicated here in this flowchart
notion image
 
The more specific a selector is, the higher its precedence.
 
 

Inline HTML styles

<p style="color: red; padding: 1px;">Some text</p>
They takes precedence over all the other styles

The !important keyword(bad practice)

Writing !important at the end of a CSS property, means it will take precedence
p { color: red !important; font-size: 18px; } #my-text { color: blue; font-size: 16px; }

CSS Box Model

The Box Model attempts to describe how much space an element takes up on the page. Properties that influence this are :
  • Width
  • Height
  • Padding
  • Border
  • Margin
 

display CSS property

 
The display CSS property sets whether an element is treated as a block or inline box. It can also not display it or enable the Flexbox framework or Grid framework
  • display: none - Hides the element from the page
  • display: block - The default display type for most HTML elements
  • display: inline-block - A mix between block and inline
  • display: flex - Enables the Flexbox framework
  • display: grid - Enables CSS Grid framework

Block vs Inline elements

block elements:
  • Take up the full width of the parent container, pushing other elements to the next line
  • Always start on a new line
  • Can set width and height explicitly and it will follow
inline elements:
  • Take only as much width and height as the content within it
  • The element will not break on a new line
inline-block elements:
  • They do not break onto a new line
  • You can set explicit width and height
  • No elements have this property by default; you need to explicitly set it
Feature
Block
Inline
Inline-Block
Starts on a new line
Yes
No
No
Respects width & height
Yes
No
Yes
Takes full width by default
Yes
No
No
Use case examples
Layout containers
Text styling
Buttons, menus, etc.

box-type property

This is kinda complex but best explained with an example, there are 2 types content-box and border-box
content-box
notion image
notion image
Look here how the size of the actual div is 400 x 200 while excluding padding and border
border-box
notion image
notion image
Here the element size is the dimensions plus padding plus the actual div, this all together make the specified height and width, so this is smaller
 
Notice that we did NOT include the margin. Margin surrounds the element, but is not part of the element.
 
With box-type: border-box, the calculation is much easier. The total "space" occupied by the element is its width and height. If you add padding or a border, the size of them will reduce the content area of the element, but not the total space occupied by the element.
This basically means it does not change the space occupied but the content inside, when you add padding or border. So it is easier to handle
 
Because this border-box property is so much easier to handle, cos you usually want to change the contents of a container, many stylesheets employ the following code
html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; }
This is a portion of what we call a "CSS reset". The goal of this is to make every element on your webpage have border-box box sizing. The * selectors target all elements.
 

Box Model Review

Main takeaways:
  • The Box Model describes how much "space" an HTML element occupies on a webpage
  • This "space" is heavily influenced by the box-sizing property
  • The "space" and layout is heavily influenced by the display property
  • The most important components of the Box Model are height, width, padding, border, and margin
  • All other CSS properties are supplementary to this Box Model concept

Must-Know Properties

The top, right, bottom, and left properties control an element’s offset from its reference point, which depends on its position value. It basically tells where to put the element but keep in mind the position

position

5 possible values:
  • static - the default value, no special positioning, top, right,left, bottom will not affect
  • absolute - The element is not part of that HTML flow and is position relative to the nearest ancestor with position:relative . If no such ancestor (like div) exists, it will use the viewport, so like the entire page
  • relative - It remains in the flow but you can shift it, relative to itself, so wherever it is if you set top, right,left, bottom , it will render there. It is also used as a reference point for children with absolute set on it
  • fixed - this is commonly used for navbar and stuff. It is used to set the position in relation to the viewport and does not follow the “normal document flow” like absolute . Use top, right,left, bottom to exactly decide its position
  • sticky - It oscillates between relative and fixed based on scroll position. It behaves like relative until it crosses a defined threshold (using top, right, bottom, or left), at which point it becomes fixed. It is used for like table headers though not supported in all browsers
Position Value
In Document Flow?
Relative To
Use Case
static
Yes
Normal document flow
Default positioning for all elements.
relative
Yes
Its original position
Slight offsets or as a parent for absolute children.
absolute
No
Nearest relative ancestor or viewport
Tooltips, modals, or elements requiring precise placement.
fixed
No
Viewport
Sticky navigation bars or headers.
sticky
Partially (switches to fixed)
Scroll threshold (relative to parent)
Sticky headers or elements that "stick" while scrolling

CSS Units of measures

Pixels

Never thought about it but pixels can’t refer to screen pixels because different screen sizes 🤣
CSS pixels (px) are an abstract unit of measurement that scale to ensure consistent sizing across devices, regardless of their resolution or physical pixel density. They are mapped to physical pixels using the device’s pixel ratio, allowing designs to look similar on screens of varying sizes and pixel densities.

vw ("viewport width") and vh ("viewport height")

Relative units where 1vw equals 1% of the viewport’s width, and 1vh equals 1% of the viewport’s height. These units allow elements to size dynamically based on the browser’s visible area, making them ideal for responsive designs.

Percentages

These are also relative units but instead of the entire viewport, it is based on their parent element’s dimension
But
If the parent container does not have a width defined, then the percentage will be relative to the first ancestor that does have a dimension defined. If we remove the width property from .inner-container, then our progress bar will be equal in width to the main container.

rem and em

These are specific to font-sizes. Here are 3 ways to define font
body { font-size: 16px; /* 16px is a "standard" value for normal text on most webpages */ }
body { font-size: 1em; /* 100% of the parent element's font size */ }
body { font-size: 1rem; /* 100% of the root element's font size */ }
This is useful I think because it allows for contextual scaling of fonts, so the fonts are all in scale to each other. We can use this for margins but again it is relative to the font-size of the root or element, so it is just weird

Color Codes and CSS Properties

The basic overview:
Here are the most common color-related CSS properties.
  • color - defines the text color of the container or element
  • background-color - defines the background color of the element
  • border-color - defines the border color
And here are 5 valid ways to define a color.
  • green - a built in value
  • rgba(0, 255, 0, 0.8) - Same thing as RGB, but the last number represents the transparency value. In this case, we are defining 80% transparency.
  • color keyword - There is a lit of key words available here that one can use
🎨
Amazing Tip - Use Adobe Color to make website color themes if you dont have an UI designer

Font Properties

Basic properties you will use:
  • font-family - defines the font that your webpage will use
  • font-size - defines the size of the font
  • font-weight - defines the thickness of the font (i.e. regular, bold, etc.)
  • line-height - defines the spacing between lines of text
While using font-family, you can provide 2, the second being the fallback in case the bowser is unable to load it correctly
html { font-family: "Georgia", serif; font-size: 16px; }
If you ever want more than the built-in browser fonts, Use Google Fonts and you can use it like this
<link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap" rel="stylesheet" />

Background properties

Each of these properties will affect the content area of the Box Model (including padding, but excluding border and margin).
  • background-color - changes the color of an HTML element
  • background-image - uses an image as a background
  • background-position - if using a background image, positions the image
  • background-repeat - determines whether a background image is repeated
  • background-size - changes the size of the background imag
 

Writing Shorthand CSS

Some properties can be written with Shorthand. For example, setting a border can be done like this
.some-element { border-width: 1px; border-style: dashed; border-color: black; }
OR
.some-element { border: 1px dashed black; }
Same for margin
.some-element { margin-top: 10px; margin-right: 5px; margin-bottom: 2px; margin-left: 15px; }
OR
.some-element { margin: 10px 5px 2px 15px; }
 

A Systematic Way to Write CSS Effectively

In my experience, the real key to using CSS effectively is to ask the following four questions in order, every time you style a webpage. These will become second nature eventually.
  1. How do I want to arrange these HTML elements on the page?
  1. How does this arrangement look in the form of HTML?
  1. How can I use CSS to achieve the layout I have imagined?
  1. How should each element be styled?
 

Responsive Web Design

It is called responsive because the web app should respond to the user changing his/her screen size.
đź’­
Most people open their sites on their mobile devices before their computers, so this is something we should just do from the beginning

Start WITHOUT code

At a minimum, you should have one of the following two things:
  1. Wireframes - simple sketches of your design to illustrate the layout you want
  1. Mockups - full designs that depict layout (how the elements are arranged) and style (colors, fonts, etc.)
Example of wireframes that help us visualize the page for both Desktop and mobile
Example of wireframes that help us visualize the page for both Desktop and mobile

CSS Breakpoint

CSS breakpoints are specific points (typically defined in media queries) where a website’s layout and styles adapt to different screen sizes or resolutions. They are used to create responsive designs, ensuring content looks good and functions well across devices like phones, tablets, and desktops.
notion image
The basic breakpoint syntax
/* On screen sizes ≥756px, apply these CSS rules */ @media (min-width: 756px) { /* CSS rules go here */ }
@media can be used to apply part of a style sheet based on the result of one or more media queries.
@media all and (min-width: 756px) { } /* Target all devices */ @media print and (min-width: 756px) { } /* Target paged material (i.e. "print preview" mode) */ @media screen and (min-width: 756px) { } /* Target mobile devices, tablets, computer screens (most common) */ @media speech and (min-width: 756px) { } /* Target speech synthesizers */
Check it out we can even modify it for printing
 
Notice there are logical operators like and , which helps us target multiple conditions. For example, we could target only "screens" that are between 400 and 600 pixels with this rule.
@media only screen and (min-width: 400px) and (max-width: 600px) { /* CSS rules here */ }
Some browser do not support all features, we can then use @supports at-rule
/* Only use these rules if the browser supports Flexbox */ @supports (display: flex) { /* CSS rules here */ }
Going back to responsive design, look at this mobile-first code
html { box-sizing: border-box; } img { width: 100%; } @media (min-width: 576px) { img { width: 49%; } } @media (min-width: 992px) { img { width: 24%; } }
It is mobile first because by default you see the image takes the full width, but as the min-width increases we change the width of the image
Turns out order of media queries is important!!! If we did this
html { box-sizing: border-box; } img { width: 100%; } @media (min-width: 992px) { img { width: 24%; } } @media (min-width: 576px) { img { width: 49%; } }
 
then the @media (min-width: 992px) rule would have not applied, because the last rule’s minimum width encompasses the previous rule’s width
So suppose I am doing a desktop (larger screen) first approach, I would need to reverse the rules
html { box-sizing: border-box; } img { width: 24%; /* Default for large screens */ } @media (max-width: 991px) { img { width: 49%; /* Medium screens */ } } @media (max-width: 575px) { img { width: 100%; /* Small screens */ } }
Things to remember:
  • Media queries always go at the bottom of your stylesheet
  • If you have multiple min-width media queries (i.e. "mobile-first"), the largest pixel values go last.
  • If you have multiple max-width media queries (you usually won't because that is considered "desktop-first"), the smallest pixel values go last

CSS Flexbox

Flexbox is a one-dimensional CSS layout system enabled by a single CSS property:
.container-element { display: flex; }
It creates responsive and efficient arangement elements, especially when their size is dynamic or unknown.
Key Concepts of Flexbox:
1. Flex Container:
• The parent element with display: flex;.
• Defines the context for arranging child elements (flex items).
2. Flex Items:
• The child elements inside a flex container. Only the direct children of “flex containers” are “flex items”
• Their size and alignment are influenced by the container’s properties.
 

Flexbox pertinent CSS properties

For the container:
  • align-items - Defines the alignment of flex items on the cross axis
  • flex-wrap - For overflowing content, defines whether it will "wrap" to the next line
  • align-content - Only applies if flex-wrap is set to wrap, and defines the alignment of all the wrapped content on the cross axis (I know, a bit confusing)
 
For the item:
Flex Item" CSS Properties
  • align-self - Similar to align-items and align-content above, but only applies to a single flex item
  • order - Change the order of flex items
  • flex-grow, flex-shrink, and flex-basis - All properties related to how large the flex item will be in the container. These are probably the trickiest of all properties, but we'll walk through them.
 

Alignment of Flex Items / Flexbox Container Properties

Flex Direction - Main Axis vs. Cross Axis

notion image
notion image
It basically tells how the elements in the containers are arranged
notion image
notion image
Note - If height and width are not set to containers, the container will occupy 100% width and adjust height according to the height of content within

justify-content - main axis alignment

notion image
notion image
notion image
notion image
notion image
notion image
Most of it is quite obvious, but space-around and space-evenly might need more clarification. With space-around, the space between flex items will be equal, but the space on the edges will not. With space-evenly, all empty space will be equal.

align-items - cross axis alignment

By default, the items occupy 100% of height as previously mentioned, so the containers stretch to fill the container, but if you want to change this action which is along in the cross-axis (main axis would be horizontal), we use align-items that has 5 values
notion image
notion image
notion image
notion image
notion image
  • stretch - Items are stretched to fit the container
  • flex-start - Items are positioned at the beginning of the container
  • flex-end - Items are positioned at the end of the container
  • baseline - Items are positioned at the baseline. No one is probably gonna use this one
    • The baseline is the line upon which most letters "sit" and below which descenders extend.
      notion image
  • center - Items are positioned at the center of the container
 

Overflowing Flex Items

When you add items to a flex box, if the total dimensions of the flex items exceed the dimensions of the flex container, they will first shrink to their smallest possible dimensions, and if they still do not fit in the container, they will overflow.
Two options then:
  1. Specify what you want to do with the overflowing flex items
    1. Using the property overflow (not restrictive to Flexbox), you can see how to handle overflowing content , Here are the important options:
      • visible: The overflow content is not clipped and will appear outside the container's boundaries.
      • hidden: The overflow content is clipped and hidden from view, without scrollbars.
      • scroll: The overflow content is clipped, but scrollbars are added to view the overflow.
      • auto: The overflow content is clipped, and scrollbars are added only if necessary.
      • clip: The overflow content is clipped, with no scrolling or visibility beyond the boundaries.
      Clip and hidden look similar but in clip the content is still in the layout and is accessible
  1. Wrap the overflowing flex items to the next line
    1. Use the property flex-wrap
      .flex-container { display: flex; flex-wrap: wrap; }
      When using flex-wrap, we can no longer use align-items , we need to use align-content .
 

Flex Item Properties

At the flex-item level, we can do two main things:
  1. Change the alignment of a flex item
  1. Change the size of a flex item

Aligning a single flex item

Suppose you want to align a single flex-item different from the others, we use align-self . This alignment only works across the cross-axis. Observe this in the example
notion image
  • Flex items 1, 5 - align-self: flex-start
  • Flex items 2, 4, 6, 8 - align-self: center
  • Flex items 3, 7 - align-self: flex-end
 

Sizing flex items

Ok this is complicated even in the docs I am ripping off but let us just get to basics, but let us get to the basics. A flex item has these properties with these default values
  • flex-grow: 0 - If you set flex-grow to 1, this item will grow to occupy the remaining empty space in the main axis, now if there are multiple items with this property set to one, they will equally share the remaining space. By default, it is an innocent container that wont grow
Containers 2 and 4 have their flex-grow set to 1
Containers 2 and 4 have their flex-grow set to 1
  • flex-shrink: 1 - Remember, how when flex containers shrink, they force the flex items to shrink as much as possible, well that is cos of this. So if we set it to 0, that item wont shrink even if you shrink the container and keep its dimensions
    • đź’­
      TLDR
      We know that if there is "empty space" in a flex container, flex-grow determines how flex items will occupy that space. We also know that if there is "overflow" in a flex container, flex-shrink will determine how the items will shrink to fit the space.
  • flex-basis: auto - this is a really weird property but basically if set to auto, the item will follow width and height property assigned to it, but it set to a value in px or % then that value will override the property in the width or height (depending on what is in the main axis)
notion image
notion image

Ordering

Usually ordering is done in HTML but sometimes you want to assign ordering differently based on screen size. This is where the order property comes in
By placing the order property on a single flex item, you can specify where it belongs on the main axis.
.flex-container { display: flex; } .flex-item-1 { flex-basis: 25%; order: 3; } .flex-item-2 { flex-basis: 25%; order: 4; } .flex-item-3 { flex-basis: 25%; order: 2; } .flex-item-4 { flex-basis: 25%; order: 1; }
notion image
 

Flexbox Cheatsheet

CSS Grid

Just basics, since MUI has it’s own implementation which abstracts away but I give a basic understanding
CSS Grid is a 2-dimensional layout system. In other words, you can control how elements sit on both the x and y axis. “We have CSS Grid for high-level, complex, 2-d layouts and Flexbox for simpler layouts. It's the best of both worlds.”
đź’­
Use Grid when:
  • You need full control of rows AND columns (examples: full page layouts, gallery items)
  • You want to explicitly define the layout regardless of content size (i.e. if you are using Flexbox and it starts to get really complicated with a bunch of heights and widths, you probably should be using Grid)
Use Flexbox when:
  • Your content is a row OR column (examples: horizontal navbar, vertical sidebar)
  • You want the size of items to determine layout
 

Interactive Tutorial

 

Grid Cheatsheet

Â