CSS - robbiehume/CS-Notes GitHub Wiki
- Hubspot CSS tutorial
- Learn CSS (web.dev)
- Advanced HTML / CSS
- How CSS is structured
- CSS Zen Garden
- CSS Tricks
- CSS Tips & Tricks #3 : CSS-only Tooltip
- CSS Tricks Almanac
- Inline vs Inline-Block Display in CSS (with visuals)
- Box model
- CSS complete guide to centering things (vertical & horizontal)
- Cursor options (has good visual demo)
- Sticky Headers And Full-Height Elements
- Say you have some HTML that you write some css for, but the content ends up wider than the 100px you specified and the content breaks out of your element. Why is that?
- The box model is a core foundation of CSS. Understanding how the box model works, how it's affected by other aspects of CSS, and importantly, how you can control it, can help you write more predictable CSS
- It's important to remember that everything displayed by CSS is a box, even if it's just some text, or has a
border-radius
that makes it look like a circle
- Good examples here
- Boxes have different behavior based on their
display
value, their display dimensions, and the content they contain - You can control this using extrinsic sizing, or you can use intrinsic sizing to let the browser make decisions for you based on the content size
-
Overflow: happens when content is too big for the box it's in. You can manage how an element handles overflow content using the
overflow
property - Switching to intrinsic sizing lets the browser make decisions for you based on the box's content size. This makes overflow much less likely because the box resizes with its content
- Good analogy: link Content Box: the area that the content lives in
- The content can control the size of its parent, so this is usually the most variably sized area
Padding Box: surrounds the content box and is the space created by the padding
property
- Because padding is inside the box, the box's background is visible in the space it creates
- If the box has overflow rules set, such as
overflow: auto
oroverflow: scroll
, the scrollbars also occupy this space
Border Box: surrounds the padding box
- Its space is defined by the
border
value, which creates a visual frame for the element - The element's border edge is the limit of what you can see
Margin Box: the space around your box, defined by the box's margin
rule
- Properties such as
outline
andbox-shadow
occupy this space too because they're painted on top of the element and don't affect the size of the box - Changing your box's outline-width of 200px on a box doesn't change anything inside the border edge
- It's better to use a stylesheet than to do in-line styles (which should be avoided when possible)
Overview: (Mozilla getting started tutorial)
- Can use a star (
*
) as a wildcard - Can set based on role:
div[role=main]
- You need to add a dot (
.
) before class names, but not for HTML elements:.green { color: green; } p { color: green; }
- Can use an element and class combo (
.
) and assign multiple to the style (,
):-
li.special, span.special.special2 { color: orange; font-weight: bold; }
- This means "target any
li
element that has a class of special"
-
-
Descendant combinator (space): style based on location/hierarchy
-
li em { color: purple; }
- This selector will select any
<em>
element that is inside (a descendant of) an<li>
-
-
Next-sibling combinator (
+
): style based on the element that came before it at same hierarchy level-
h1 + p { font-size: 200%; }
- This will style a paragraph when it comes directly after a heading at the same hierarchy level in the HTML
-
-
Styling based on id:
-
#my-id { color: red; }
-
-
Styling based on state:
- Ex: change tag for a link based on the status(unvisitied, visited, hover)
a:link { color: pink; } a:visited { color: green; } a:hover { text-decoration: none; }
- Ex: change tag for a link based on the status(unvisitied, visited, hover)
-
Combining selectors and combinators:
- It is worth noting that you can combine multiple selectors and combinators together. For example:
/* selects any <span> that is inside a <p>, which is inside an <article> */ article p span { ... } /* selects any <p> inside an <h1> that has a class of "header" */ h1.header p { ... } /* selects any <p> that comes directly after a sibling <ul>, which comes directly after a sibling <h1> */ h1 + ul + p { ... }
- It is worth noting that you can combine multiple selectors and combinators together. For example:
-
Combining multiple types together:
-
body h1 + p .special { color: yellow; background-color: black; padding: 5px; }
- This will style any element with a class of special, which is inside a
<p>
, which comes just after an<h1>
, which is inside a<body>
-
-
Regex: link
-
[id^='td-']
: selects anything that has an id that starts with td- -
[id*='-input']
: selects anything with -input- within it's id -
[id$='0']
: selects anything that has an id that ends in 0 - Can combine them:
div [id^='x'][id$='0']
selects any div that starts with x and ends with 0
-
Cascade, specifity, and inheritance:
- You may encounter scenarios where two selectors select the same HTML element
- CSS has two rules to control which selector is stronger in the event of a conflict: cascade and specificity
-
Cascade: if two or more selectors are the same, then it will take the one that appears latest in the stylesheet
- For example, with this stylesheet, the paragraph would be colored blue
p { color: red; } p { color: blue; }
- For example, with this stylesheet, the paragraph would be colored blue
-
Specificity: if there's a conflict between two selectors, then the higher specificity one is used
- Specificity overview
- For example, a class selector is rated as being more specific than an element selector, so a paragraph with class of "special" will be red, not blue
.special { color: red; } p { color: blue; }
-
Attribute selectors (
[]
): link - Pseudo-classes: link
Functions: link
- While most values are relatively simple keywords or numeric values, there are some values that take the form of a function
calc()
function: do simple math within CSS -
.box { width: calc(90% - 30px); background-color: green; }
Transform functions:
- Some functions are
rotate()
,scale()
,translate()
- Pronounced "at-rules", they provide instruction for what CSS should perform or how it should behave
- A couple common ones are
@import
and@media
- The
@media
rule is used to apply styles conditionally based on the characteristics of the device or viewport displaying the content - This rule allows you to create responsive designs that adjust to different screen sizes, orientations, and other media features
- Basic syntax:
@media media-type and (media-feature) { ...
- Example:
-
/* Styles for screens wider than 768px */ @media screen and (min-width: 768px) { ... /* Styles for screens narrower than 600px */ @media screen and (max-width: 600px) { ...
-
- Can combine multiple criteria:
@media screen and (max-width: 600px) and (orientation: portrait)
// only if screen is narrower than 768 pixels and device is in portrait mode - Can also use a comma (
,
) as anor
:@media screen and (max-width: 600px), screen and (orientation: landscape)
- As well as
not
:@media not screen and (max-width: 600px)
- Complex example:
-
/* Styles for screens between 600 and 900 pixels, or the device is in portrait orientation */ @media (min-width: 600px) and (max-width: 900px), (orientation: portrait) { .sidebar { display: none; } }
-
- Some properties like
font
,background
,padding
,border
, andmargin
are called shorthand properties - Example:
padding: 10px 15px 15px 5px; --- is equal to --- padding-top: 10px; padding-right: 15px; padding-bottom: 15px; padding-left: 5px;
- Floating elements in CSS are elements that are removed from the normal document flow and positioned to the left or right within their containing element
- This allows text and other inline elements to wrap around the floated element, creating a flexible and often visually appealing layout
- It's done with the
float
property, though the use of floating has been somewhat diminished with the advent of more modern layout techniques like Flex and Grid
-
Pseudo-Elements: used to style specific parts of an element's content or to insert new content (e.g.,
::before
,::after
,::first-letter
)- They typically use double colons (
::
), but are backwards compatible with single colons (:
) as well
- They typically use double colons (
-
Pseudo-Classes: used to style elements based on their state or position (e.g.,
:hover
,:focus
,:nth-child
). They use single colons (:
)
Key differences:
- Targeting: pseudo-elements target specific parts of an element's content (or create new content), while pseudo-classes target entire elements based on their state or position
-
Syntax: Pseudo-elements use double colons (
::
) in modern CSS, while pseudo-classes use single colons (:
) - Functionality: Pseudo-elements are used to style or insert content that doesn’t exist in the HTML, while pseudo-classes apply styles based on conditions like user interactions or structural relationships
- Pseudo-elements are used to style specific parts of an element's content. They don't actually exist in the HTML; they are created purely through CSS
::before
and::after
overview (CSS-Tricks)- 7 practical uses for
::before
and::after
- The
::before
and::after
pseudo-elements in CSS are used to insert content before or after the content of an element - These pseudo-elements are powerful tools for adding stylistic elements to your web pages without needing additional HTML markup, keeping your HTML cleaner and more semantic
-
Content property:
- To use
::before
and::after
, you must define thecontent
property. This property specifies what should be inserted before or after the content of the selected element- The content can be text, an empty string (for styling purposes), or even an image (using
url()
)
- The content can be text, an empty string (for styling purposes), or even an image (using
- Example:
.example::before { content: 'Prefix '; color: red; }
- To use
- Positioning:
- The pseudo-elements are treated as inline elements by default, meaning they flow with the surrounding text. However, you can style them just like any other element, including setting their
display
property toblock
,inline-block
, or other display types - You can also apply
position
properties (likeabsolute
,relative
, etc.) to control their placement relative to the parent element.
Pseudo classes (link)
- Pseudo-classes are used to define a special state of an element. They target elements based on their state, position, or user interaction, rather than targeting a specific part of the element’s content
- Examples:
-
:hover
: Styles an element when the user hovers over it with a pointer -
:focus
: Styles an element when it has focus (e.g., a focused input field) -
:nth-child(n)
: Selects elements based on their position in a parent’s list of children
-
- Note: Flexbox layout is most appropriate to the components of an application, and small-scale layouts, while the Grid layout is intended for larger scale layouts
- Simple summary: flexbox is for alignment; grid is for layout
- flexbox vs grid: summary; in-depth article
display:inline
vsdisplay:inline-block
vsdisplay:block
in CSS (with visuals)- You can think of flex box as "one dimensional" and grid as "two dimensional"
- While flexbox can make rows and columns in the sense that it allows elements to wrap, there’s no way to declaratively control where elements end up since the elements merely push along a single axis and then wrap or not wrap accordingly
- You can (if you want to) declare the sizing of rows and columns and then explicitly place things into both rows and columns as we choose
- Grid is mostly defined on the parent element. In flexbox, most of the layout (beyond the very basics) happen on the children
- Grid is better at overlapping
Overview
- Complete guide to flexbox: this is a great resource with visuals. Most of the notes in this wiki section are copied straight here
- Flexbox aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word “flex”)
- The main idea behind the flex layout is to give the container the ability to alter its items’ width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes)
- A flex container expands items to fill available free space or shrinks them to prevent overflow
- Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts: block which is vertically-based and inline which is horizontally-based
Basics and terminology
- Since flexbox is a whole module and not a single property, it involves a lot of things including its whole set of properties
- Some of them are meant to be set on the container (parent element, known as “flex container”) whereas the others are meant to be set on the children (said “flex items”)
Properties: Flex container
-
align-content
: aligns a flex container's lines within when there is extra space in the cross-axis- This only takes effect on multi-line flexible containers, where
flex-wrap
is set towrap
orwrap-reverse
Flex items
- This only takes effect on multi-line flexible containers, where
-
order
: sets the order of the flex items. It doesn't affect the source order of the elements in the DOM, only the visual order on the screen -
flex-basis
: defines initial size of a flex item before any available space is distributed according togrow
andshrink
- Overrides the
width
orheight
properties (depending onflex-direction
, unlessflex-basis
is set toauto
(or not set)
- Overrides the
Overview
- Complete guide to grid: this is a great resource with visuals. Most of the notes in this wiki are copied straight here
- CSS Grid Layout (aka “Grid” or “CSS Grid”), is a two-dimensional grid-based layout system
Basics
- To get started you have to define a container element as a grid with display: grid, set the column and row sizes with grid-template-columns and grid-template-rows, and then place its child elements into the grid with grid-column and grid-row
- Similarly to flexbox, the source order of the grid items doesn’t matter. Your CSS can place them in any order, which makes it super easy to rearrange your grid with media queries
- Imagine defining the layout of your entire page, and then completely rearranging it to accommodate a different screen width all with only a couple lines of CSS. Grid is one of the most powerful CSS modules ever introduced
Relative Unit | Relative To | Common Use |
---|---|---|
% |
Parent element | Widths, heights, margins, padding |
rem |
Root element font size | Typography, global scaling |
em |
Parent element font size | Nested elements, local scaling |
vh |
Viewport height | Full-height sections |
vw |
Viewport width | Responsive layouts |
vmin |
Smaller of vw or vh
|
Scaling across devices |
vmax |
Larger of vw or vh
|
Flexible UI for orientation changes |
ch |
Width of "0" character | Inputs, text elements |
ex |
x-height of font | Font alignment tweaks |
cap |
Capital letter height | Font-based spacing |
lh |
Line height | Spacing in typography-heavy layouts |
When to Use These Units:
- Use
rem
andem
for font sizes and padding to maintain consistent scaling - Use
vw
andvh
for full-screen sections or hero banners - Use
vmin
orvmax
for layouts that need to adapt to both portrait and landscape modes - Use
ch
for inputs or containers where character width matters
-
Key Difference:
-
rem
is consistent because it refers to the root element -
em
can vary since it depends on the parent’s font size, which can lead to cascading size changes if not managed carefully
-
-
When to Use:
- Use
rem
for global, predictable sizing (e.g., typography, padding) - Use
em
when scaling based on a specific parent’s size makes sense (e.g., buttons inside a larger container)
- Use
-
Relative to: the root element (
<html>
)'s font size -
Consistent scaling: all
rem
units are based on the same root size, ensuring uniform scaling across the page - Use case: when you want consistent sizes across the entire site
-
Example:
-
html { font-size: 16px; } p { font-size: 2rem; } /* 2 * 16px = 32px */
-
- Relative to: the parent element's font size
- Contextual scaling: the size changes based on the parent’s size, which can lead to unintended compounding effects
- Use case: when you want elements to scale relative to their parent (e.g., nested components or elements)
-
Example:
-
.parent { font-size: 20px; } .child { font-size: 1.5em; } /* 1.5 * 20px = 30px */
-
- Relative to: the size of the parent element
- Use case: often used for widths, heights, and positioning elements relative to their parent container
-
Example:
-
div { width: 50%; } /* Takes 50% of the parent's width */
-
-
Relative to: The size of the viewport (browser window)
-
1vh
/1vw
= 1% of the viewport height / width
-
- Use case: useful for responsive designs that need to adapt to screen size, like full-screen sections or hero banners
-
Example:
-
section { height: 100vh; } /* Takes full height of the viewport */
-
-
Relative to: the smaller or larger of
vw
andvh
(viewport width and height)-
10vmin
= 10% of the smaller dimension (width or height) -
10vmax
= 10% of the larger dimension
-
- Use case: helpful for scaling elements proportionally regardless of screen orientation (portrait and landscape)
-
Example:
-
div { font-size: 5vmin; } /* Scales with the smaller of vw or vh */
-
-
Relative to: the width of the
0
(zero) character in the element's font -
Use case: used to size text areas or elements with content length in mind
- Also useful for inputs or containers where character width matters
-
Example:
-
input { width: 20ch; } /* Enough space for approximately 20 characters */
-
- Replacing an image with the Kellum Method (may be outdated): link
.hide-text { text-indent: 100%; white-space: nowrap; overflow: hidden; }
-
Have container element fill text content: (example
- Set
width
andheight
to different combinations ofmin-content
/max-content
- To not have it go over a certain width/height, can also set a
max-width
and/ormax-height
- Set
- Vertically align text inside a flexbox
- Horizontally align text in element: `text-align:' right, left, center, etc.
- Center a div or text in a div: link
- Extend clickable area of element: see example.css in repo
-
Render
\n
as newline: link -
Bring element to front: set
z-index: 2
; or set it to higher than the other element that's on top of it