The CSS border is the visible ring between padding and margin. Beyond a simple line, modern CSS borders support rounded corners, individual side control, gradient tricks, and image fills. In this lesson you will master the full border shorthand, border-radius for rounded shapes, the difference between border and outline, and how to create decorative effects using borders alone.
Border Properties
| Property | Values | Example |
|---|---|---|
border |
width style color (all required) | border: 2px solid #4f46e5 |
border-width |
px, rem, thin/medium/thick | border-width: 1px 3px |
border-style |
solid, dashed, dotted, double, none | border-style: dashed |
border-color |
Any color value | border-color: transparent |
border-radius |
px, % or per-corner values | border-radius: 8px / 50% |
Border vs Outline
| Feature | border | outline |
|---|---|---|
| Affects layout | Yes โ takes up space inside box model | No โ drawn outside; no layout shift |
| Per-side control | Yes โ border-top, border-left etc. | No โ all four sides only |
| Follows border-radius | Yes | Yes in modern browsers |
| Primary use | Decorative framing and component styling | Accessibility focus indicator |
border-radius Values
| Value | Result | Use Case |
|---|---|---|
border-radius: 8px |
Slightly rounded corners | Cards, buttons, inputs |
border-radius: 50% |
Circle (on square elements only) | Avatars, icon badges |
border-radius: 9999px |
Pill/capsule โ always rounded ends | Tags, badges, toggle switches |
border-radius: 16px 4px |
Top-left+Bottom-right / Top-right+Bottom-left | Asymmetric decorative shapes |
border-style makes the border invisible โ the initial value for style is none, not solid. A common mistake is writing border: 2px #4f46e5 and seeing nothing.border: 2px solid transparent on interactive elements and switch to a visible color on hover or focus. This preserves layout space (no shift) while showing a border only on interaction โ a smooth, jank-free effect.outline: none or outline: 0 on focusable elements without providing a custom focus style. Removing focus outlines makes keyboard navigation invisible โ a critical WCAG accessibility failure that affects millions of users.Basic Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS Borders</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body {
font-family: system-ui, sans-serif;
padding: 40px;
background: #f8fafc;
display: flex;
flex-wrap: wrap;
gap: 16px;
align-items: flex-start;
}
.demo { padding: 16px 20px; font-size: 0.875rem; font-weight: 600; }
/* Solid border */
.b-solid { border: 3px solid #4f46e5; border-radius: 8px; }
/* Dashed border */
.b-dashed { border: 2px dashed #f59e0b; border-radius: 8px; }
/* Single side โ accent left border */
.b-left {
border: none;
border-left: 5px solid #10b981;
background: #d1fae5;
border-radius: 0 8px 8px 0;
}
/* Circle โ only works on a square element */
.b-circle {
width: 80px;
height: 80px;
border: 4px solid #6366f1;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
padding: 0;
}
/* Pill โ radius larger than height */
.b-pill { border: 2px solid #ec4899; border-radius: 9999px; }
/* Transparent border โ space preserved, shown on hover */
.b-hover {
border: 2px solid transparent;
border-radius: 8px;
transition: border-color 0.2s;
}
.b-hover:hover { border-color: #4f46e5; }
/* Accessible focus outline */
button:focus-visible {
outline: 3px solid #4f46e5;
outline-offset: 3px;
}
.focus-btn {
padding: 10px 20px;
border: 2px solid #4f46e5;
border-radius: 6px;
background: white;
cursor: pointer;
font-size: 0.875rem;
}
</style>
</head>
<body>
<div class="demo b-solid">Solid border</div>
<div class="demo b-dashed">Dashed border</div>
<div class="demo b-left">Left accent border</div>
<div class="b-circle">★</div>
<div class="demo b-pill">Pill shape</div>
<div class="demo b-hover">Hover to reveal border</div>
<button class="focus-btn">Tab to focus (see outline)</button>
</body>
</html>
How It Works
Step 1 โ Border Shorthand Requires All Three Parts
border: 3px solid #4f46e5 sets width (3px), style (solid), and color together. Any of the three can be set independently with border-width, border-style, and border-color for fine control.
Step 2 โ Per-Side Border Overrides the Shorthand
border: none resets all sides first, then border-left: 5px solid #10b981 applies only to the left. The declaration order matters โ per-side properties must come after the shorthand reset in the cascade.
Step 3 โ border-radius: 50% Creates Circles
On a 80ร80 square, a radius of 50% equals 40px โ exactly half of width and height โ producing a perfect circle. On a rectangle, 50% creates an ellipse. Use 9999px for a pill that always has fully rounded ends regardless of element dimensions.
Step 4 โ Transparent Border Preserves Layout Space
border: 2px solid transparent reserves the layout space for the border without showing it. When border-color changes to a visible color on hover, no layout shift occurs because the space was already there.
Step 5 โ focus-visible for Accessible Custom Outlines
:focus-visible applies only when the browser determines keyboard navigation is active (not on mouse click). This allows clear keyboard focus styles without adding an unwanted ring on mouse interaction โ the best balance of accessibility and aesthetics.
Real-World Example: Status Cards with Accent Borders
*, *::before, *::after { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; padding: 40px; background: #f1f5f9; }
/* Status card โ border-left signals category */
.status-card {
background: white;
border-radius: 12px;
border: 1px solid #e2e8f0;
border-left-width: 5px; /* thicker accent side */
padding: 20px 24px;
max-width: 380px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
margin-bottom: 16px;
}
.status-card.success { border-left-color: #10b981; }
.status-card.warning { border-left-color: #f59e0b; }
.status-card.danger { border-left-color: #ef4444; }
.status-card.info { border-left-color: #3b82f6; }
.status-card h3 { margin: 0 0 6px; font-size: 1rem; color: #0f172a; }
.status-card p { margin: 0; font-size: 0.875rem; color: #64748b; }
/* Badge pill */
.badge {
display: inline-flex;
align-items: center;
padding: 3px 10px;
border-radius: 9999px;
border: 1.5px solid;
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.badge-success { border-color: #10b981; color: #10b981; background: #d1fae5; }
.badge-warning { border-color: #f59e0b; color: #92400e; background: #fef3c7; }
.badge-danger { border-color: #ef4444; color: #ef4444; background: #fee2e2; }
/* Avatar ring using outline */
.avatar-ring {
width: 64px;
height: 64px;
border-radius: 50%;
border: 3px solid white; /* inner white gap */
outline: 3px solid #6366f1; /* coloured outer ring */
display: block;
background: #c7d2fe;
}
/* Horizontal rule using border */
.divider {
border: none;
border-top: 1px solid #e2e8f0;
margin: 24px 0;
}
/* Custom focus for all interactive elements */
:focus { outline: none; }
:focus-visible {
outline: 3px solid #4f46e5;
outline-offset: 2px;
border-radius: 4px;
}
Common Mistakes
Mistake 1 โ Missing border-style makes border invisible
โ Wrong โ no style means no visible border:
.box { border: 2px #4f46e5; } /* style omitted โ border does not appear */
โ Correct โ always include width, style, and color:
.box { border: 2px solid #4f46e5; }
Mistake 2 โ Removing focus outline without replacement
โ Wrong โ keyboard users cannot see where focus is:
* { outline: none; } /* WCAG failure */
โ Correct โ remove default, add a custom focus style:
:focus { outline: none; }
:focus-visible { outline: 3px solid #4f46e5; outline-offset: 2px; }
Mistake 3 โ border-radius: 50% on non-square elements
โ Wrong โ produces an ellipse on rectangular elements, not a circle:
.tag { width: 120px; height: 40px; border-radius: 50%; }
โ Correct โ use a large fixed value for guaranteed pill shape:
.tag { width: 120px; height: 40px; border-radius: 9999px; }
Quick Reference
| Property | Common Values | Notes |
|---|---|---|
border |
2px solid #000 |
Shorthand โ width style color all required |
border-style |
solid, dashed, dotted, double | Omitting makes border invisible |
border-radius |
8px, 50%, 9999px | 50% = circle on squares; 9999px = pill |
border-top etc. |
3px solid red |
Per-side โ use after shorthand reset |
outline |
3px solid blue |
No layout impact; key for focus styles |
outline-offset |
3px |
Gap between element edge and outline ring |