AD JB Toolbox 01 EN

CSS Tutorial / CSS Borders, Rounded Corners, and Shadows

CSS borders define a box's visible edge, border-radius rounds its corners, and box-shadow adds a shadow without increasing its layout size. Shadows can still be clipped by an ancestor's overflow settings, and a rounded border does not automatically crop every child.

Set border width, style, and color

.card { border: 2px solid #3d6b89; }

The border shorthand combines width, style, and color. solid draws a continuous line, dashed draws dashes, and dotted draws dots. A none style suppresses the expected border even if a width and color are present. Use border-bottom or border-block-end when only one edge needs a border. For further detail, see The CSS Box Model: Content, Padding, Border, and Margin.

Property Box size effect Main uses
border In content-box, it is added outside, and in border-box, it is included within the specified size. border of element
outline Does not increase layout space Shows outlines around focused elements
box-shadow Does not increase layout space Shadows and Visual Depth

With a fixed border-box width, increasing border thickness reduces the inner space while keeping the outer width. A decorative border or shadow has a different role from the focus outline that identifies the current keyboard target. Keep that indicator visible. See MDN: border.

Compare corner lengths and percentages

.round { border-radius: 12px; }

.circle { width: 80px; height: 80px; border-radius: 50%; }

.oval { width: 160px; height: 80px; border-radius: 50%; }

A length value such as 12px specifies the corner radius. You can give different values to the four corners, but compare them to one value first. If you apply 50% to a box with the same width and height, it will look like a circle, and if the horizontal and vertical sizes are different, it will look like an ellipse. The horizontal radius of the percentage is based on the width, and the vertical radius is based on the height.

The rounded corners of the parent do not automatically crop the child image. Choose between giving the border-radius to the image itself or cutting the overflow from the parent, depending on your purpose. If you add hidden to the parent, the child's shadow/focus display may also be cut off at the border. The following comparison distinguishes which box is being cut. You can check the radius calculation in MDN's border-radius description.

Read the shadow values

.shadow { box-shadow: 0 8px 24px 4px rgb(0 0 0 / 16%); }
value meaning Results to change
first 0 move horizontally Positive numbers move to the right, negative numbers move to the left
second 8px vertical movement Positive numbers move downward, negative numbers move upward.
third 24px blur radius Closer to 0, it becomes clearer and larger, it becomes softer.
fourth 4px spread radius Positive numbers increase the shadow size, negative numbers decrease it.
rgb(0 0 0 / 16%) Color and Opacity The degree to which it is distinguished from the background varies.

The first two lengths are required and blur and spread can be omitted. The blur radius cannot be negative. Adding inset is the inner shadow, the default is the outer shadow. There is also a way to add multiple shadows, but first check by changing the movement and size of one shadow separately.

A shadow does not reserve layout space. It will not push away a following card by the amount of its blur or spread. Large shadows can obscure nearby content, so supply actual spacing with margins or layout gaps when needed. See MDN: box shadow.

Find the ancestor that clips a shadow

.frame { padding: 12px; overflow: visible; }

.frame.clip { overflow: hidden; }

.frame .card { box-shadow: 0 18px 20px 8px rgb(0 0 0 / 25%); }

The last two cards have separate .frame parents. Their child shadows are identical, but one parent allows visible overflow and the other clips it. The shadow extends beyond the 12px parent padding, so the hidden-overflow version cuts it at the parent boundary. Inspect that ancestor when diagnosing a clipped shadow. See CSS Overflow, Long Text Wrapping, and Ellipsis.

Don't confuse giving yourself overflow: hidden with having the parent element cut off its child's shadow. This exercise is a situation where a parent cuts off the outer shadow of a child card. If the shadow is not visible on the actual page, you should check not only the value of the card itself, but also the overflow and border of the parent element.

Run the example and compare changes

Save the code below as UTF-8 in borders.html. Comparisons of borders, rounded corners, outer shadows, inner shadows, circles and ellipses, and truncation are all included.

<!doctype html>

<html lang="en">

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Comparing borders, corners, and shadows</title>

  <style>

    * { box-sizing: border-box; }

    body { margin: 24px; color: #333; font: 16px/1.6 sans-serif; background: #f6f8fa; }

    .card { width: 100%; max-width: 320px; margin-block: 24px; padding: 20px; background: white; }

    .border { border: 2px solid #3d6b89; }

    .round { border: 2px solid #3d6b89; border-radius: 12px; }

    .shadow { border-radius: 12px; box-shadow: 0 8px 24px 4px rgb(0 0 0 / 16%); }

    .inset { box-shadow: inset 0 0 12px 2px rgb(0 0 0 / 20%); }

    .shape { width: 80px; height: 80px; margin-block: 16px; border-radius: 50%; background: #6eb898; }

    .oval { width: 160px; }

    .frame { width: 100%; max-width: 320px; padding: 12px; margin-block: 24px; background: #dce8f1; overflow: visible; }

    .frame .card { margin: 0; max-width: none; height: 100px; box-shadow: 0 18px 20px 8px rgb(0 0 0 / 25%); }

    .clip { overflow: hidden; }

  </style>

</head>

<body>

  <h1>Card boundaries and shadows</h1>

  <div class="card border">Card with a border only</div>

  <div class="card round">Border and rounded corners</div>

  <div class="card shadow">Outer shadow</div>

  <div class="card inset">Inset shadow</div>

  <h2>50% Edges: Circles and Ovals</h2><div class="shape" role="img" aria-label="80×80 won"></div><div class="shape oval" role="img" aria-label="160×80 ellipse"></div>

  <h2>Parent: overflow: visible</h2><div class="frame"><div class="card">Child shadow visible outside the parent</div></div>

  <h2>Parent: overflow: hidden</h2><div class="frame clip"><div class="card">Child shadow clipped at the parent boundary</div></div>

</body>

</html>
  1. Change the thickness of the .border from 2px to 8px. In wide windows, make sure the outer width is maintained and the inner space is reduced, then return it to 2px.
  2. Change the width of the .shape from 80px to 160px. Make sure the circle becomes an ellipse if you keep the height at 80px. Restore to original width.
  3. Change the horizontal shift of the .shadow to 20px and the vertical shift to -8px. Keep the blur 24px and compare only the direction of movement. Next, change the blur to 0, compare it to the sharp edge, and then return it to its original value.
  4. Change spread 4px to -4px. Notice if the shadow size decreases. When I change the hidden to visible in the second .frame, I check if the shadow outside the parent is visible again and restore it to hidden.

If the shadow is blurry, check the color opacity and background contrast, and if only one side is cut off, check the parent's border and overflow. If the child content inside the corner protrudes, we also compare the method of giving rounded corners to the child itself. Rather than increasing effectiveness, base your judgment on keeping content clear and easy to manipulate.

More in This Category
CSS Tutorial / CSS Form States: Focus, Validation, disabled, and readonly

CSS Tutorial / CSS Form States: Focus, Validation, disabled, and readonly

Compare form states, create accessible labels and error messages, and inspect which enabled, disabled, and read-only fields enter submitted form data.

CSS Tutorial / Basic CSS Selectors: Type, Class, ID, and Attributes

CSS Tutorial / Basic CSS Selectors: Type, Class, ID, and Attributes

Choose basic selectors for a small page, combine conditions correctly, and inspect whether each rule matches the intended elements.

CSS Tutorial / CSS Borders, Rounded Corners, and Shadows

CSS Tutorial / CSS Borders, Rounded Corners, and Shadows

Build cards with borders and shadows, compare circles and ellipses, and inspect how ancestor overflow changes visible shadows.

CSS Tutorial / Apply CSS with Inline, Internal, and External Styles

CSS Tutorial / Apply CSS with Inline, Internal, and External Styles

Compare three ways to apply CSS, create a working external stylesheet, and diagnose common file-path and loading problems.

CSS Tutorial / Inspect CSS with DevTools: Styles and Computed

CSS Tutorial / Inspect CSS with DevTools: Styles and Computed

Use Styles, Computed, and the box model display to diagnose CSS, compare temporary edits, and transfer a confirmed change to the correct source file.

CSS Tutorial / Organize CSS with Shared Styles, Nesting, and Layers

CSS Tutorial / Organize CSS with Shared Styles, Nesting, and Layers

Refactor a small stylesheet without changing its layout, compare nesting and cascade layers, and check relative file paths and selector specificity.

CSS Tutorial / CSS Grid Basics: Tracks, Lines, and Item Placement

CSS Tutorial / CSS Grid Basics: Tracks, Lines, and Item Placement

Create a two-dimensional grid, distinguish lines, tracks, cells, and areas, and use fr, minmax(), and spans to place items.

CSS Tutorial / Flexbox Alignment, Wrapping, gap, grow, and shrink

CSS Tutorial / Flexbox Alignment, Wrapping, gap, grow, and shrink

Compare Flexbox alignment and wrapping, distribute space with flex values, and prevent long content from blocking item shrinkage.

CSS Tutorial / CSS Overflow, Long Text Wrapping, and Ellipsis

CSS Tutorial / CSS Overflow, Long Text Wrapping, and Ellipsis

Compare scrolling, clipping, long-word wrapping, and single-line ellipsis, including keyboard access and minimum-size issues in layout containers.

CSS Tutorial / CSS Fonts, Font Sizes, and Line Height

CSS Tutorial / CSS Fonts, Font Sizes, and Line Height

Build a readable font stack, compare line-height inheritance, and use browser tools to identify the fonts actually rendering your text.