What is CSS styling?

CSS stands for Cascading Style Sheets. HTML is the “structure” of a web page (headings, paragraphs, buttons, tables), and CSS is the “style” (colors, spacing, fonts, borders, layout).

Think of it like this: HTML is the LEGO bricks, CSS is how you paint them, arrange them, and make the build look good.

h2 {
  color: #0a58ff;
}

p {
color: #222;
} 
h2 {
  color: #e11d48;
}

p {
  color: #111;
  font-size: 1.7rem;
  line-height: 1.6;
}
  
h2 {
  color: #111;
  border-left: 6px solid #111;
  padding-left: 12px;
}

p {
  color: #222;
  background: #f2f2f2;
  padding: 12px;
  border-radius: 10px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

h2 {
  margin: 0 0 10px;
  font-size: 1.6rem;
}

p {
  margin: 0;
}
  

Hello CSS

Same HTML, different CSS. That’s the whole magic trick.

CSS styling in HTML

There are three common ways to add CSS to a page:

  • Inline CSS: styles on a single element (fast to test, messy for real projects)
  • Internal CSS: a <style> block inside the HTML file
  • External CSS: a separate .css file linked with <link> (most common)

1) Inline CSS

Inline CSS uses the style attribute directly on an element. Switch to the HTML view to see the inline styles.

/* There is no CSS in 
this snippet on purpose.
   Inline CSS is written 
   directly in the HTML. */
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.note {
  padding: 12px;
  border-radius: 12px;
  background: #f2f2f2;
}
  

Inline CSS example

This border is inline CSS. It works, but it’s not great for maintainability.

Inline CSS is okay for quick experiments, but it’s usually better to use classes and a stylesheet.

2) Internal CSS with a style tag

Internal CSS lives inside the HTML file, usually in the <head> section.

  • Good for small demos or single-page experiments
  • Not ideal for large sites (harder to reuse styles across multiple pages)
/* Switch to the HTML view to see the CSS */
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}
  
      

Internal CSS example

The CSS is “in the HTML file”, but not on each element.

External CSS is the most common approach. You put your CSS in a file like styles.css and link it:

  • <link rel="stylesheet" href="styles.css">

This keeps your styling reusable and clean. One stylesheet can style many pages.

/* Imagine this is inside styles.css */
.card {
  border: 2px solid #111;
  border-radius: 14px;
  padding: 14px;
}

.card h3 {
margin: 0 0 8px;
}

.card p {
margin: 0;
color: #333;
} 
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.card {
  background: #f2f2f2;
}
  

External CSS example

In real life, this CSS would come from a separate .css file.

CSS syntax basics

CSS is made of rules. Each rule has:

  • Selector: what you’re targeting (like p or .card)
  • Declarations: property and value pairs (like color: red;)
/* selector */
p {
  /* property: value; */
  color: #0a58ff;
  font-size: 1.7rem;
}
  
p {
  color: #e11d48;
  font-weight: 700;
}
  
p {
  color: #111;
  background: #f2f2f2;
  padding: 12px;
  border-radius: 12px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

p {
  margin: 0;
}
  

This paragraph is being styled by the active CSS snippet.

Learn more about selectors in the CSS Selectors Interactive Tutorial, and about properties in the CSS Properties Interactive Tutorial.

CSS comments

Comments look like this: /* comment */ or // comment. They are ignored by the browser, and they’re great for explaining your CSS.

Quick-start selectors

Here are the selectors you’ll use constantly:

  • Element: p, h2, button
  • Class: .card, .button (recommended for most styling)
  • ID: #header (try not to rely on it for general styling)
  • Descendant: .card p (targets p inside .card)
/* Element selector */
p {
  color: #0a58ff;
}
  
/* Class selector */
.highlight {
  background: #fff1a8;
  padding: 2px 6px;
  border-radius: 8px;
}
  
/* Descendant selector */
.card p {
  color: #111;
  font-weight: 700;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.card {
  border: 2px solid #111;
  border-radius: 14px;
  padding: 14px;
  background: #f2f2f2;
  max-width: 520px;
}

.card h3 {
  margin: 0 0 8px;
}

.card p {
  margin: 0;
  color: #333;
}

p {
  margin: 12px 0 0;
}
  

Selectors demo

This is a paragraph inside a card. This span has a class.

This is a paragraph outside the card.

The cascade (why “Cascading” matters)

If multiple CSS rules target the same element, the browser decides which one wins using:

  1. Importance (try to avoid !important)
  2. Specificity (more “specific” selectors beat less specific ones)
  3. Order (later rules can override earlier rules)

Takeaway: if your style “doesn’t work”, it often is working, but another rule is winning.

/* First rule */
.note {
  color: #0a58ff;
}
  
/* Later rule (same selector) wins */
.note {
  color: #e11d48;
}
  
/* More specific selector wins */
.card .note {
  color: #111;
  font-weight: 700;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.card {
  border: 2px solid #111;
  border-radius: 14px;
  padding: 14px;
  background: #f2f2f2;
  max-width: 520px;
}
  

I have a class .note and I’m inside .card.

Learn more about the CSS Cascade in the CSS Cascade Interactive Tutorial, and about specificity in the CSS Specificity Interactive Tutorial.

CSS styling properties (the “starter pack”)

CSS has a lot of properties, but beginners can get very far by learning a core set:

  • Text: color, font-size, font-weight, line-height, text-align
  • Spacing: margin, padding
  • Box: border, border-radius
  • Background: background, background-color
  • Size: width, max-width

Text styling basics

Let’s style text using a few high-impact properties.

.text-demo {
  font-size: 1.1rem;
  line-height: 1.6;
  letter-spacing: 0.02em;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.text-demo {
  max-width: 60ch;
  background: #f2f2f2;
  border: 2px solid #111;
  border-radius: 14px;
  padding: 14px;
  color: #111;
}
  

Change the sliders. Notice how readability improves with a comfortable line-height. Your future self (and your readers) will thank you.

Spacing: margin and padding

Padding is space inside an element (between content and its border). Margin is space outside an element (between elements).

.box {
  padding: 14px 14px 14px 14px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.stack {
  display: grid;
  gap: 12px;
  max-width: 520px;
}

.box {
  border: 2px solid #111;
  border-radius: 14px;
  background: #f2f2f2;
}

.box + .box {
  margin-top: 14px;
}

.box h4 {
  margin: 0 0 8px;
  font-size: 1.1rem;
}

.box p {
  margin: 0;
  color: #333;
}
  

Padding demo

Padding adds breathing room inside this box.

Second box

This one shows how elements can have space between them too.

Learn more about padding in the CSS Padding Interactive Tutorial, and about margin in the CSS Margin Interactive Tutorial.

Borders and border-radius

Borders outline elements. Border radius rounds corners. These two properties alone can make a design feel “finished”.

.panel {
  border: 3px solid #111;
  border-radius: 18px;
}
  
.panel {
  border: 3px dashed #111;
  border-radius: 0;
}
  
.panel {
  border: 3px solid #111;
  border-radius: 999px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.panel {
  background: #f2f2f2;
  padding: 14px;
  max-width: 520px;
}

.panel h4 {
  margin: 0 0 8px;
  font-size: 1.1rem;
}

.panel p {
  margin: 0;
  color: #333;
}
  

Border styles

Try different snippets to see how borders and rounding change the feel.

Learn more about borders in the CSS Border Interactive Tutorial.

CSS styling examples

Let’s do a few beginner-friendly “real world” mini examples. The goal here is not perfection, but confidence.

Example: a simple card

.card {
  border: 2px solid #111;
  border-radius: 16px;
  padding: 16px;
  background: #f2f2f2;
}

.card h3 {
margin: 0 0 10px;
}

.card p {
margin: 0;
color: #333;
} 
.card {
  border: 2px solid #111;
  border-radius: 16px;
  padding: 16px;
  background: #fff;
  box-shadow: 0px 12px 30px 0px rgba(0, 0, 0, 0.18);
}

.card h3 {
  margin: 0 0 10px;
}

.card p {
  margin: 0;
  color: #333;
}
  
.card {
  border: 2px solid #111;
  border-radius: 16px;
  padding: 16px;
  background: linear-gradient(135deg, #fff1a8, #f2f2f2);
}

.card h3 {
  margin: 0 0 10px;
}

.card p {
  margin: 0;
  color: #333;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.card {
  max-width: 560px;
}

.card h3 {
  font-size: 1.35rem;
}

.card p code {
  font-family: ui-monospace, SFMono-Regular, monospace;
}
  

Reusable card

This pattern shows up everywhere. Cards are basically the hoodies of UI.

This card has a small box-shadow applied to it. Learn more about it in the CSS Box Shadow Interactive Tutorial.

Links have special states. Common ones:

  • normal: a
  • hover: a:hover when the mouse is over it
  • visited: a:visited after it’s been clicked
  • focus: a:focus-visible for keyboard users

A beginner-friendly approach: make links obvious, add a hover effect, and include a focus outline for accessibility.

a {
  color: #0a58ff;
  text-decoration: underline;
}

a:hover {
text-decoration-thickness: 3px;
}

a:focus-visible {
outline: 3px solid #111;
outline-offset: 3px;
} 
a {
  color: #111;
  text-decoration: none;
  border-bottom: 2px solid #111;
}

a:hover {
  border-bottom-style: dashed;
}

a:focus-visible {
  outline: 3px solid #111;
  outline-offset: 3px;
}
  
a {
  color: #111;
  text-decoration: none;
  background: #fff1a8;
  padding: 2px 8px;
  border-radius: 999px;
}

a:hover {
  background: #f2f2f2;
}

a:focus-visible {
  outline: 3px solid #111;
  outline-offset: 3px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.wrap {
  max-width: 60ch;
  background: #f2f2f2;
  border: 2px solid #111;
  border-radius: 14px;
  padding: 14px;
}

.wrap p {
  margin: 0;
  color: #333;
  line-height: 1.7;
}
  

Here is a normal link you can hover and focus.

Learn more about link styling in the CSS Link Interactive Tutorial.

CSS styling buttons

Buttons are usually styled with:

  • padding (clickable area)
  • border and border-radius (shape)
  • background and color (contrast)
  • cursor: pointer (lets users know it’s clickable)
  • :hover and :focus-visible (interaction + accessibility)
.button {
  padding: 12px 16px;
  border: 2px solid #111;
  border-radius: 12px;
  background: #111;
  color: #fff;
  font-weight: 700;
  cursor: pointer;
}

.button:hover {
transform: translateY(-2px);
}

.button:focus-visible {
outline: 3px solid #111;
outline-offset: 4px;
} 
.button {
  padding: 12px 16px;
  border: 2px solid #111;
  border-radius: 999px;
  background: #fff1a8;
  color: #111;
  font-weight: 700;
  cursor: pointer;
}

.button:hover {
  background: #f2f2f2;
}

.button:focus-visible {
  outline: 3px solid #111;
  outline-offset: 4px;
}
  
.button {
  padding: 12px 16px;
  border: 2px solid #111;
  border-radius: 12px;
  background: transparent;
  color: #111;
  font-weight: 700;
  cursor: pointer;
}

.button:hover {
  background: #111;
  color: #fff;
}

.button:focus-visible {
  outline: 3px solid #111;
  outline-offset: 4px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
  margin: 10px;
}

.button {
  transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease;
}
  

Pro tip: if you remove the focus outline, keyboard users get lost. Keep :focus-visible styling in your button styles.

Learn more about hover styles in the CSS :hover Pseudo-Class Interactive Tutorial.

CSS styling images

Images often need a bit of CSS to behave nicely:

  • display: block removes the weird inline gap below images
  • max-width: 100% helps images shrink on small screens
  • border-radius can round corners
  • object-fit: cover is great for “cropped thumbnails”

Responsive image basics

.photo {
  width: 100%;
  max-width: 520px;
  display: block;
  border-radius: 18px;
  border: 2px solid #111;
}
  
.photo {
  width: 100%;
  max-width: 520px;
  display: block;
  border-radius: 999px;
  border: 2px solid #111;
}
  
.photo {
  width: 100%;
  max-width: 520px;
  display: block;
  border-radius: 18px;
  border: 2px solid #111;
  filter: grayscale(1);
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.caption {
  margin: 10px 0 0;
  color: #333;
  max-width: 520px;
}
  
Random demo image from Picsum

This image stays within a max width and adapts to smaller containers.

Cropped thumbnails with object-fit

Sometimes you want a fixed-size thumbnail, but you don’t want to distort the image. That’s where object-fit: cover shines.

.thumb {
  width: 360px;
  height: 220px;
  border-radius: 16px;
  overflow: hidden;
  border: 2px solid #111;
}

.thumb img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
} 
.thumb {
  width: 360px;
  height: 220px;
  border-radius: 16px;
  overflow: hidden;
  border: 2px solid #111;
}

.thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  background: #f2f2f2;
}
  
.thumb {
  width: 360px;
  height: 220px;
  border-radius: 16px;
  overflow: hidden;
  border: 2px solid #111;
}

.thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 20% 50%;
  display: block;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}
  
Random demo image from Picsum

Learn more about object-fit in the CSS Object Fit Interactive Tutorial.

CSS styling tables

Tables can look scary, but they’re just a grid of cells. Common table styling goals:

  • Readable spacing in cells
  • Clear borders (or clean border-less rows)
  • A header row that stands out
  • Zebra striping for readability
table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
border: 1px solid #111;
padding: 10px 12px;
text-align: left;
}

th {
background: #111;
color: #fff;
} 
table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  border-bottom: 1px solid #111;
  padding: 12px;
  text-align: left;
}

th {
  background: #f2f2f2;
}
  
table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  border: 1px solid #111;
  padding: 10px 12px;
  text-align: left;
}

tbody tr:nth-child(even) {
  background: #f2f2f2;
}

th {
  background: #111;
  color: #fff;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.table-wrap {
  max-width: 760px;
  border: 2px solid #111;
  border-radius: 14px;
  overflow: hidden;
}

caption {
  padding: 12px;
  text-align: left;
  font-weight: 700;
  background: #fff1a8;
  border-bottom: 2px solid #111;
}
  
Simple pricing table
Plan Price Support
Starter $9 Email
Pro $19 Priority
Team $39 Chat
Enterprise $99 Dedicated

Table tip: border-collapse

If your table borders look doubled, you probably want border-collapse: collapse; on the table.

Starter patterns you’ll reuse

Pattern: a badge

.badge {
  display: inline-block;
  padding: 6px 10px;
  border: 2px solid #111;
  border-radius: 999px;
  font-weight: 700;
  background: #fff1a8;
}
  
.badge {
  display: inline-block;
  padding: 6px 10px;
  border: 2px solid #111;
  border-radius: 10px;
  font-weight: 700;
  background: #f2f2f2;
}
  
.badge {
  display: inline-block;
  padding: 6px 10px;
  border: 2px solid #111;
  border-radius: 999px;
  font-weight: 700;
  background: #111;
  color: #fff;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}
  

Status: New

Pattern: simple two-column layout

Layout is a big topic, but here’s a very gentle intro: use CSS Grid for a basic two-column layout.

.layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
  
.layout {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 14px;
}
  
.layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.panel {
  border: 2px solid #111;
  border-radius: 14px;
  background: #f2f2f2;
  padding: 14px;
}

.panel h4 {
  margin: 0 0 8px;
  font-size: 1.1rem;
}

.panel p {
  margin: 0;
  color: #333;
}
  

Main

This is the main content area.

Sidebar

This is the sidebar content.

Why isn’t my CSS working?

If you ever feel like CSS is ignoring you, here’s the usual checklist:

  • Did you target the right element? Check spelling of class names (CSS is picky).
  • Is another rule overriding yours? The cascade might be winning with a more specific selector or a later rule.
  • Did you forget units? Some properties need units: width: 20px; not width: 20;.
  • Is your CSS file linked correctly? A missing href or wrong path means no styles load.
  • Browser cache Sometimes refreshing hard (using Command + Shift + R on Mac or Ctrl + Shift + R on Windows) or disabling cache in the devtools helps.
/* Common fix: increase clarity and avoid overrides */
.box {
  border: 2px solid #111;
  padding: 14px;
  background: #fff1a8;
}

.wrapper .box {
background: #f2f2f2;
} 
/* If you want .box to win inside .wrapper, target that case */
.wrapper .box {
  background: #fff1a8;
}
  
/* Another fix: place the rule later (order matters) */
.wrapper .box {
  background: #f2f2f2;
}

.box {
  background: #fff1a8;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

body {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
}

.wrapper {
  border: 2px dashed #111;
  border-radius: 14px;
  padding: 14px;
  max-width: 520px;
}

.box {
  border-radius: 12px;
}
  
I am .box inside .wrapper.

CSS properties cheat sheet

Here’s a quick list of CSS properties you’ll see constantly:

Text

  • color
  • font-size
  • font-weight
  • line-height
  • letter-spacing
  • text-align

Spacing

  • margin
  • padding
  • gap (for Grid/Flex layouts)

Box

  • border
  • border-radius
  • box-shadow

Background

  • background
  • background-color

Sizing

  • width, max-width
  • height (use carefully)
  • aspect-ratio

Interaction and states

  • :hover
  • :focus-visible
  • cursor
  • transition

CSS Styling Conclusion

CSS is a powerful tool for styling your web pages. By understanding the basics of selectors, properties, and the cascade, you can create visually appealing and responsive designs. Remember to check your CSS for common issues, use the cheat sheet for quick reference, and practice regularly to improve your skills.