CSS Border Table

PieceWhat it doesField note
border: 1px solid #333The three-part shorthandWidth, style, color - style is REQUIRED (none erases the border)
border-radiusRound the corners50% on a square = circle; per-corner lists go clockwise from top-left
border-width per sideborder-top-width etc.The shorthand resets all four - longhands for mixed sides
border-style valuessolid/dashed/dotted/doublehidden vs none: hidden wins over collapsed-table conflicts
transparent borderborder: 1px solid transparentReserves layout space invisibly - the hover-without-jump trick
outline vs borderOutside, no layoutOutline draws over neighbors, no box growth - focus rings live here
border-imageImage as the frameslice/stretch mechanics - niche but zero-extra-element framing
logically: border-inline-startFlow-relative borderThe start side follows reading direction - pairs with logical properties
Reference: the MDN border reference. Border shorthand is three decisions (width, style, color) applied to all four sides at once - and style is the load-bearing one: a border with width and color but no style does not exist. The layout trick worth owning: a transparent border reserves the exact pixels a hover border will occupy, so buttons stop jumping. Bottom line: outline is the no-layout sibling (draws outside, never moves the box - which is why focus rings use it), border-radius composes per-corner, and border-inline-start follows the reading direction for internationalized UIs. Related tools: box-shadow table (the depth layer borders complement), backgrounds table (which box the border clips), and logical properties table (the flow-relative border names).

The border shorthand is three decisions (width, style, color) applied to all four sides at once - and style is the load-bearing one: border: 1px #333 renders NOTHING, because the default style is none. Width and color only matter once a style exists.

Bottom line: the transparent-border trick is the layout saver - border: 1px solid transparent reserves the exact pixels a hover border will occupy, so buttons and cards stop jumping when the border appears. Outline is the no-layout sibling: it draws outside the box without moving anything, which is why focus rings belong to outline, not border.

The honest part: border-radius composes - one value rounds all corners, but the per-corner syntax goes clockwise from top-left, and the elliptical slash syntax (border-radius: 50% / 20%) makes ovals. An element that is square with radius 50% is the entire circle recipe.

How to use

  1. Stop hover jumps: give interactive elements border: 1px solid transparent in the rest state, then recolor on hover - the layout box never changes size.
  2. Focus with outline: outline: 2px solid + outline-offset: 2px on :focus-visible - outside the box, no layout shift, and offset gives it air.
  3. Mix sides with longhands: border + border-bottom: none for separators-in-a-row - the shorthand first, longhand overrides second, cascade does the rest.

Frequently asked questions

Why doesn't my border show even though I set width and color?

The style is missing - it defaults to none, and none means no border regardless of width or color. border: 1px solid #333 works; border: 1px #333 paints nothing. This bites twice in practice: the shorthand written without a style keyword, and a stylesheet that sets border: none somewhere with higher specificity, silently erasing styled borders - the longhand border-style: solid is the surgical revival. The shorthand resets all three components, which is why 'border: red' also produces no border: it resets style to initial (none) too.

How is outline different from border, and when should each be used?

Border is part of the box model: it takes layout space, pushes neighbors, participates in width calculations (unless box-sizing says otherwise). Outline paints OVER the surrounding content without affecting layout at all - it can overlap neighbors freely. That difference assigns their jobs: borders are structural (separators, card edges, input frames) and participate in size; outlines are annotation (focus rings, validation highlights, debug outlines) that must never shift the page. The accessibility pairing: :focus-visible with a 2px outline and a small outline-offset is the standard keyboard focus indicator - moving focus to a border change instead would make every focus click jiggle the layout.

What is the per-corner radius syntax actually doing?

It maps clockwise from the top-left corner: border-radius: 8px 0 0 8px rounds only the left side (top-left, top-right, bottom-right, bottom-left). Two values mean corners diagonal-paired, four values walk the corners individually. The slash syntax adds elliptical control - the value before the slash is horizontal radii, after is vertical: border-radius: 50% / 20% makes an oval by curving more horizontally than vertically. And the circle recipe remains the classic: a square element with border-radius: 50% - the radius is a percentage of the box, so any square becomes a perfect circle.

When do logical border properties earn their keep?

Whenever the border marks the reading direction rather than the screen direction: border-inline-start draws on the leading side (left in English, right in Arabic), border-block-end sits under the text flow's end. Blockquotes, active nav indicators and list markers are flow-relative decorations - an RTL translation flips them for free, while border-left keeps pointing at the same physical side and breaks the design. The migration rule from the logical properties playbook applies: new components use the logical names, existing screen-locked decoration stays physical until touched.

Related tools