What is a CSS border?
A border is the line that sits around an element’s box. It wraps the element’s padding and content, like a picture frame.
Borders are great for:
- Separating UI sections (cards, panels, buttons)
- Showing focus (input focus rings)
- Drawing attention (badges, alerts, highlights)
Borders are also part of layout: by default, they affect an element’s overall size. (We’ll leverage that
later with box-sizing.)
.demo { border: 4px solid #111; }
.demo { border: 10px solid #111; }
.demo { border: 4px dashed #111; }
*, ::before, ::after { box-sizing: border-box; } .wrap { display: grid; gap: 16px; font-family: ui-monospace, system-ui, sans-serif; } .demo { width: 320px; padding: 18px; background: #f2f2f2; } .demo strong { display: inline-block; margin-bottom: 8px; }
Border frame This box has padding and a border.
The border recipe: width + style + color
A border usually needs three ingredients: width, style, and color.
border-width: how thick the border isborder-style: what kind of line (solid, dashed, etc.)border-color: the border’s color
If you set only width and color but forget the style, the border might not show up. That’s because
border-style defaults to none.
.demo { border-width: 8px; border-color: #111; border-style: solid; }
.demo { border-width: 8px; border-color: #111; border-style: none; }
.demo { border: 8px solid #111; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 340px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; } .note { opacity: 0.8; margin-top: 10px; font-size: 14px; }
Try the snippets:One of them "disappears" because border-style is none.
CSS border width
Border width can be written in several ways:
- Shorthand:
border: 6px solid #111; - Longhand:
border-width: 6px; - Per side:
border-top-width,border-right-width, etc. - Four-value pattern:
border-width: top right bottom left;
Beginners tip: start with px while learning. It’s predictable. Later, you can use rem or
other units when it makes sense.
.demo { border: 6px solid #111; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 340px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; }
Drag the slider to change border thickness.
Border width per side and four values
You can set different widths on each side. This is useful for “tabs”, underlines, and UI emphasis.
The four-value order is: top, right, bottom, left.
.demo { border-style: solid; border-color: #111; border-width: 2px 10px 16px 4px; }
.demo { border: 0 solid #111; border-left-width: 10px; }
.demo { border: 0 solid #111; border-bottom-width: 8px; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 360px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; }
Borders can vary per-side.
CSS border styles
Border styles control the “type of line”. The most common are: solid, dashed, dotted, double, and none.
Some styles are drawn differently depending on the browser and border width. For example, a very thin
dotted border might look like tiny squares, while a thicker one looks more circular. That’s normal.
.demo { border: 10px solid #111; border-style: solid; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 360px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; }
Click different styles.
Mixing border styles per side
You can style each side differently. This is useful for decorative frames or “speech bubble” style elements.
.demo { border-width: 10px; border-style: solid dashed dotted double; border-color: #111; }
.demo { border-width: 10px; border-style: dashed; border-top-style: solid; border-color: #111; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 360px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; }
Borders can vary by side: top, right, bottom, left.
CSS border color
Border colors can be set with: named colors, hex, rgb(), hsl(),
and more. You can also use transparency for softer borders.
Two very common beginner-friendly patterns:
- High contrast: dark border on light background
- Subtle UI border: a semi-transparent border
.demo { border: 6px solid #111; }
.demo { border: 6px solid rgba(17, 17, 17, 0.25); }
.demo { border: 6px solid #3b82f6; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 360px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; }
Same border width and style, different colors.
Different colors on each side
Like width and style, color can also be set per-side. The four-value order is the same: top, right, bottom, left.
.demo { border-width: 10px; border-style: solid; border-color: #ef4444 #3b82f6 #22c55e #f59e0b; }
.demo { border: 10px solid #111; border-top-color: #ef4444; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 360px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; }
One border, multiple colors.
Border shorthand vs longhand
You’ll see these two styles all the time:
- Shorthand:
border: 2px solid #111; - Longhand:
border-width,border-style,border-color
Shorthand is quick and readable. Longhand is great when you want to change only one part without changing the others.
.demo { border: 8px solid #111; }
.demo { border-width: 8px; border-style: solid; border-color: #111; }
.demo { border: 8px solid #111; border-right-width: 18px; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 360px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; }
Longhand is handy when you only want to tweak one side.
CSS border radius (rounded corners)
border-radius rounds the corners of an element. The bigger the radius, the rounder the corners.
border-radius: 0;means sharp cornersborder-radius: 12px;means rounded cornersborder-radius: 999px;often means “pill shape”
Important: border-radius rounds both the border and the background. If you only want a “ring” around an
element without changing layout, you may want outline instead (we’ll cover that soon).
.card { border-radius: 12px; }
*, ::before, ::after { box-sizing: border-box; } .card { width: 360px; padding: 18px; background: #f2f2f2; border: 8px solid #111; font-family: ui-monospace, system-ui, sans-serif; }
Drag the slider to round the corners.
Circle and pill shapes with border radius
If you want a perfect circle, you usually combine: equal width and height plus
border-radius: 50%.
For a pill shape (common for buttons and tags), use a large radius like 999px.
.shape { border-radius: 50%; }
.shape { border-radius: 999px; }
*, ::before, ::after { box-sizing: border-box; } .wrap { display: flex; gap: 16px; align-items: center; font-family: ui-monospace, system-ui, sans-serif; } .shape { width: 140px; height: 140px; background: #f2f2f2; border: 8px solid #111; display: grid; place-items: center; } .pill { width: 260px; height: 70px; }
CirclePill
Per-corner radius control
You can round corners individually: border-top-left-radius, border-top-right-radius,
border-bottom-right-radius, border-bottom-left-radius.
This is perfect for “ticket stubs”, “speech bubble” bases, or unique card designs.
.card { border-top-left-radius: 28px; border-top-right-radius: 6px; border-bottom-right-radius: 28px; border-bottom-left-radius: 6px; }
.card { border-top-left-radius: 0; border-top-right-radius: 32px; border-bottom-right-radius: 0; border-bottom-left-radius: 32px; }
*, ::before, ::after { box-sizing: border-box; } .card { width: 360px; padding: 18px; background: #f2f2f2; border: 8px solid #111; font-family: ui-monospace, system-ui, sans-serif; }
Different corners, different vibes.
Learn much more about border-radius in the CSS Rounded Corners Interactive Tutorial.
CSS border inside
This part is a frequent source of confusion, so let’s be super clear:
- A real border takes up space and affects the element’s size (unless you change sizing rules).
- An outline does not take up space and is drawn outside the element.
- An inset box-shadow can look like an “inner border” and also does not change layout size.
Border inside with box-sizing
By default, width means “content width”. Add a border, and the element gets bigger.
If you use box-sizing: border-box;, then width includes padding and border. Many devs set
this globally because it’s easier to reason about.
.card { box-sizing: content-box; }
.card { box-sizing: border-box; }
*, ::before, ::after { box-sizing: border-box; } .card { width: 100%; padding: 18px; border: 16px solid #111; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; } .frame { width: 320px; border: 2px dashed rgba(17, 17, 17, 0.35); padding: 10px; font-family: ui-monospace, system-ui, sans-serif; font-size: 14px; opacity: 0.9; }
Dashed frame is 320px wideWatch how the solid card fits.
Click on the Default CSS tab to better understand what's going on.
Fake inner border with inset box-shadow
If you need a border-like look that stays “inside” without affecting layout size, try:
box-shadow: inset 0 0 0 6px ...;
This is one of the best tricks for buttons and cards where you want consistent sizing.
.card { box-shadow: inset 0 0 0 8px rgba(17, 17, 17, 0.85); }
*, ::before, ::after { box-sizing: border-box; } .card { width: 360px; padding: 18px; background: #f2f2f2; border-radius: 16px; font-family: ui-monospace, system-ui, sans-serif; }
This is an “inner border” made with inset box-shadow.
Try entering 18px instead of 8px in the box-shadow value above to see the effect.
Learn more about box-shadow in the CSS Box Shadow Interactive Tutorial
Outline vs border for rings
outline is often used for focus styles because it doesn’t shift layout. It sits outside the border and
does not take any flow space.
The tradeoff: outlines don’t follow the border box exactly the same way borders do, and they can look a bit different. Still, they’re a fantastic tool for accessibility.
.demo { outline: 6px solid #111; }
.demo { border: 6px solid #111; }
.demo { border: 6px solid #111; outline: 6px solid rgba(59, 130, 246, 0.6); outline-offset: 6px; }
*, ::before, ::after { box-sizing: border-box; } .demo { width: 360px; margin: 20px; padding: 18px; background: #f2f2f2; font-family: ui-monospace, system-ui, sans-serif; }
Outline is outside and does not affect layout.
CSS border animation
Borders can be animated, but not every part animates nicely. Here’s the beginner-friendly breakdown:
- Good to animate:
border-color,border-width,border-radius - Not great to animate:
border-style(it “jumps” between states)
If you want smooth motion, animate numbers and colors. If you want a snappy change, switching styles is fine.
Animate border color
This is one of the cleanest animations and a great first win.
@keyframes borderHue { 0% { border-color: #ef4444; } 50% { border-color: #3b82f6; } 100% { border-color: #22c55e; } }
.card {
animation: borderHue 2.2s linear infinite alternate;
}
*, ::before, ::after { box-sizing: border-box; } .card { width: 360px; padding: 18px; border: 10px solid #111; background: #f2f2f2; border-radius: 16px; font-family: ui-monospace, system-ui, sans-serif; }
Border color animation.
Animate border width (without layout jank)
Animating real border width can change layout size, which can look like the element is “pushing” things around. A smoother approach is using an inset shadow as an inner border, because it doesn’t affect layout.
@keyframes innerBorderPulse { 0% { box-shadow: inset 0 0 0 2px rgba(17, 17, 17, 0.85); } 50% { box-shadow: inset 0 0 0 10px rgba(17, 17, 17, 0.85); } 100% { box-shadow: inset 0 0 0 2px rgba(17, 17, 17, 0.85); } }
.card {
animation: innerBorderPulse 1.8s ease-in-out infinite;
}
*, ::before, ::after { box-sizing: border-box; } .card { width: 360px; padding: 18px; background: #f2f2f2; border-radius: 18px; font-family: ui-monospace, system-ui, sans-serif; }
Inner “border” animation using inset box-shadow.
Animated border dashes (the fun trick)
CSS can’t smoothly animate border-style, and dashed borders don’t have a built-in “dash offset”
property like SVG does.
But you can fake an animated dashed border using a repeating background and a transparent border.
This is a great trick for “marching ants” selection boxes.
@keyframes march {
to {
background-position: 0 0, 24px 0;
}
}
.box {
border: 6px solid transparent;
background:
linear-gradient(#f2f2f2, #f2f2f2) padding-box,
repeating-linear-gradient(
90deg,
#111 0 12px,
transparent 12px 24px
) border-box;
background-size: auto, 24px 100%;
background-position: 0 0, 0 0;
animation: march 0.8s linear infinite;
}
*,
::before,
::after {
box-sizing: border-box;
}
.box {
width: 360px;
padding: 18px;
border-radius: 16px;
font-family: ui-monospace, system-ui, sans-serif;
}
“Marching ants” style border using a repeating gradient.
Learn more about CSS animations in the CSS Animation Interactive Tutorial.
Common CSS border gotchas
Why is my border not showing?
- You set
border-widthandborder-color, but forgotborder-style. - The border color matches the background (it’s there, it’s just hiding).
- The border width is
0(or too small to notice).
Why did my element size change?
Borders affect layout. If you’re using a fixed width and add a thick border, the element can grow. Use
box-sizing: border-box; when you want width to include the border.
Why does my rounded border look weird?
- Very thick borders on small elements can look chunky on corners.
- Try a slightly smaller border width or a larger radius.
- For perfect circles, make sure width and height match and use
border-radius: 50%;.
Conclusion
Borders look simple, but they’re secretly a mini toolset: thickness, styles, colors, rounded corners, and even animation tricks. If you remember just one thing, make it this: a visible border usually needs width, style, and color.
From there, you can level up fast: use border-radius for friendly corners, outline for
non-layout rings, and inset box-shadow when you need an “inner
border” that doesn’t push things around.
