Borders, Shadows, and Shape Effects
1. Border Properties and Border Images
| Property | Values | Description | Default |
|---|---|---|---|
| border-width | thin | medium | thick | length |
Border thickness | medium (3px) |
| border-style | none | solid | dashed | dotted | double | groove | ridge | inset | outset |
Border line style | none |
| border-color | color |
Border color | currentColor |
| border | width style color |
Shorthand for all sides | - |
| border-top/right/bottom/left | width style color |
Individual side shorthand | - |
| border-block-start/end | width style color |
Logical border (writing-mode aware) | - |
| border-inline-start/end | width style color |
Logical border (writing-mode aware) | - |
| outline | width style color |
Outline (doesn't affect layout) | none |
| outline-offset | length |
Gap between outline and border | 0 |
| Border Image Property | Values | Description | Example |
|---|---|---|---|
| border-image-source | url() | gradient | none |
Image to use for border | url('/border.png') |
| border-image-slice | number | % |
How to slice image (9-slice) | 30 30 30 30 |
| border-image-width | length | % | number | auto |
Width of border image | 10px |
| border-image-outset | length | number |
Distance image extends beyond border | 0 |
| border-image-repeat | stretch | repeat | round | space |
How to fill border area | repeat |
| border-image | source slice / width / outset repeat |
Shorthand for all border-image properties | url() 30 / 10px round |
Example: Border basics and styles
/* Basic border */
.box {
border: 2px solid #333;
/* Shorthand: width style color */
}
/* Individual sides */
.custom-sides {
border-top: 3px solid red;
border-right: 2px dashed blue;
border-bottom: 1px dotted green;
border-left: 4px double purple;
}
/* Logical borders (writing-mode aware) */
.logical {
border-inline-start: 3px solid blue; /* Left in LTR, right in RTL */
border-inline-end: 3px solid blue;
border-block-start: 2px solid red; /* Top in horizontal mode */
border-block-end: 2px solid red;
}
/* Border styles */
.styles {
border: 3px solid black; /* Solid line */
border: 3px dashed black; /* Dashed line */
border: 3px dotted black; /* Dotted line */
border: 3px double black; /* Double line (requires 3px min) */
border: 3px groove black; /* 3D groove effect */
border: 3px ridge black; /* 3D ridge effect */
border: 3px inset black; /* 3D inset effect */
border: 3px outset black; /* 3D outset effect */
}
/* Outline (doesn't affect layout) */
.outlined {
outline: 2px solid blue;
outline-offset: 4px; /* Gap between element and outline */
}
Example: Border images and gradients
/* Gradient border with border-image */
.gradient-border {
border: 10px solid transparent;
border-image: linear-gradient(45deg, red, blue) 1;
/* Slice value 1 = use entire gradient */
}
/* Image-based border (9-slice scaling) */
.image-border {
border: 20px solid transparent;
border-image: url('/border-pattern.png') 30 round;
/* Slice 30px from edges, repeat to fill */
}
/* Advanced border-image */
.fancy-border {
border: 15px solid transparent;
border-image-source: url('/fancy-border.png');
border-image-slice: 30 30 30 30; /* Top, right, bottom, left slices */
border-image-width: 15px;
border-image-repeat: round; /* Scale to fit without cutting */
}
/* Conic gradient border */
.conic-border {
border: 5px solid transparent;
border-image: conic-gradient(
from 0deg,
red, yellow, green, blue, purple, red
) 1;
}
/* Animated gradient border */
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
.animated-border {
border: 3px solid transparent;
border-image: conic-gradient(
from var(--angle),
red, yellow, green, blue, purple, red
) 1;
animation: rotate 3s linear infinite;
}
@keyframes rotate {
to { --angle: 360deg; }
}
Note:
border-image replaces border-style. Use outline for focus indicators (doesn't affect layout). Gradient borders require
border: solid transparent + border-image.
2. Border-radius and Complex Shapes
| Property | Values | Description | Example |
|---|---|---|---|
| border-radius | length | % |
Rounded corners (all) | 10px |
| Two values | border-radius: 10px 20px; |
Top-left/bottom-right, top-right/bottom-left | Diagonal pairs |
| Three values | border-radius: 10px 20px 30px; |
Top-left, top-right/bottom-left, bottom-right | Asymmetric |
| Four values | border-radius: 10px 20px 30px 40px; |
Top-left, top-right, bottom-right, bottom-left | All different |
| Elliptical | border-radius: 50px / 30px; |
Horizontal / vertical radii | Ellipse corners |
| Individual corners | border-top-left-radius: 10px 20px; |
Specific corner (horizontal vertical) | Fine control |
| Logical corners | border-start-start-radius |
Writing-mode aware corners | Internationalization |
Example: Border-radius variations
/* Circle */
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
}
/* Pill shape */
.pill {
border-radius: 9999px; /* Large value creates pill */
padding: 0.5rem 1.5rem;
}
/* Ellipse */
.ellipse {
width: 200px;
height: 100px;
border-radius: 50%; /* Creates ellipse for non-square */
}
/* Different corner radii */
.fancy-corners {
border-radius: 20px 50px 20px 50px;
/* Top-left, top-right, bottom-right, bottom-left */
}
/* Organic shapes with elliptical radii */
.organic {
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
/* horizontal radii / vertical radii */
}
/* Individual corners */
.custom-corner {
border-top-left-radius: 50px 30px; /* Elliptical corner */
border-top-right-radius: 10px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 20px;
}
/* Notched corner effect */
.notched {
border-radius: 0 20px 20px 20px;
/* Top-left not rounded, creates notch effect */
}
Example: Complex organic shapes
/* Blob shapes with multiple radii */
.blob-1 {
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
}
.blob-2 {
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
}
.blob-3 {
border-radius: 73% 27% 53% 47% / 48% 66% 34% 52%;
}
/* Morphing animation between shapes */
@keyframes morph {
0% {
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
}
50% {
border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%;
}
100% {
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
}
}
.morphing-blob {
animation: morph 8s ease-in-out infinite;
}
/* Squircle (super-ellipse approximation) */
.squircle {
border-radius: 20%;
/* For more accurate squircle, use clip-path or SVG */
}
/* Teardrop shape */
.teardrop {
border-radius: 50% 50% 50% 0;
}
/* Leaf shape */
.leaf {
border-radius: 0 50%;
}
3. Box Shadows and Drop Shadows
| Property | Syntax | Description | Example |
|---|---|---|---|
| box-shadow | x y blur spread color inset |
Shadow on box edges | 2px 2px 4px rgba(0,0,0,0.2) |
| Offset X | length |
Horizontal offset (+ = right, - = left) | 4px |
| Offset Y | length |
Vertical offset (+ = down, - = up) | 4px |
| Blur radius | length |
Shadow blur (0 = sharp) | 8px |
| Spread radius | length |
Expand/contract shadow (+ = larger) | 2px |
| Color | color |
Shadow color | rgba(0,0,0,0.2) |
| inset | inset |
Inner shadow (optional keyword) | inset 0 2px 4px rgba(0,0,0,0.1) |
| Multiple shadows | Comma-separated | Layer multiple shadows | 0 2px 4px rgba(0,0,0,0.1), 0 8px 16px rgba(0,0,0,0.1) |
| text-shadow | x y blur color |
Shadow on text (no spread or inset) | 2px 2px 4px rgba(0,0,0,0.3) |
| filter: drop-shadow() | drop-shadow(x y blur color) |
Shadow following alpha channel | drop-shadow(4px 4px 8px rgba(0,0,0,0.3)) |
Example: Box shadow variations
/* Basic shadow */
.shadow-sm {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.shadow-md {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.shadow-lg {
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
}
.shadow-xl {
box-shadow: 0 20px 25px rgba(0, 0, 0, 0.15);
}
/* Layered shadows (more realistic depth) */
.shadow-layered {
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.12),
0 1px 2px rgba(0, 0, 0, 0.24);
}
.shadow-floating {
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.05),
0 8px 16px rgba(0, 0, 0, 0.1),
0 16px 32px rgba(0, 0, 0, 0.05);
}
/* Colored shadows */
.colored-shadow {
box-shadow: 0 10px 30px rgba(255, 0, 100, 0.3);
}
/* Inner shadow (inset) */
.inset-shadow {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* Combined inner and outer */
.combined-shadow {
box-shadow:
inset 0 2px 4px rgba(0, 0, 0, 0.06),
0 2px 4px rgba(0, 0, 0, 0.1);
}
Example: Advanced shadow effects
/* Neumorphism (soft UI) */
.neumorphic {
background: #e0e0e0;
box-shadow:
10px 10px 20px rgba(0, 0, 0, 0.1),
-10px -10px 20px rgba(255, 255, 255, 0.7);
}
.neumorphic-pressed {
background: #e0e0e0;
box-shadow:
inset 5px 5px 10px rgba(0, 0, 0, 0.1),
inset -5px -5px 10px rgba(255, 255, 255, 0.7);
}
/* Glow effect */
.glow {
box-shadow: 0 0 20px rgba(0, 100, 255, 0.5);
}
.glow-strong {
box-shadow:
0 0 10px rgba(0, 100, 255, 0.4),
0 0 20px rgba(0, 100, 255, 0.3),
0 0 40px rgba(0, 100, 255, 0.2);
}
/* Text shadows */
.text-shadow {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.text-outline {
/* Multiple shadows create outline effect */
text-shadow:
-1px -1px 0 white,
1px -1px 0 white,
-1px 1px 0 white,
1px 1px 0 white;
}
.text-glow {
text-shadow:
0 0 10px rgba(255, 255, 255, 0.8),
0 0 20px rgba(255, 255, 255, 0.6),
0 0 30px rgba(255, 255, 255, 0.4);
}
/* Drop shadow for transparent images */
.transparent-image {
filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.3));
/* Follows alpha channel, better than box-shadow for PNGs */
}
Note: Use
filter: drop-shadow() for transparent
images (follows alpha channel). box-shadow creates rectangular shadow. Layered shadows
create more realistic depth.
4. CSS Shapes and Clip-path
| Function | Syntax | Description | Use Case |
|---|---|---|---|
| clip-path: circle() | circle(radius at position) |
Circular clipping | Avatar, buttons |
| clip-path: ellipse() | ellipse(rx ry at position) |
Elliptical clipping | Oval shapes |
| clip-path: polygon() | polygon(x1 y1, x2 y2, ...) |
Custom polygons | Arrows, triangles, custom shapes |
| clip-path: inset() | inset(top right bottom left round radius) |
Rectangular clipping with rounded corners | Cropped rectangles |
| clip-path: path() | path('SVG path data') |
SVG path clipping | Complex custom shapes |
| clip-path: url() | url(#clipPath) |
Reference SVG clipPath element | Reusable complex shapes |
| shape-outside | circle() | ellipse() | polygon() | url() |
Text wrapping around shape | Magazine-style layouts |
| shape-margin | length |
Margin around shape for text wrap | Spacing around floated shapes |
Example: Basic clip-path shapes
/* Circle */
.circle-clip {
clip-path: circle(50%); /* Radius 50% at center */
clip-path: circle(100px at 50% 50%); /* 100px radius at center */
}
/* Ellipse */
.ellipse-clip {
clip-path: ellipse(50% 30% at center);
}
/* Triangle */
.triangle {
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
/* Arrow right */
.arrow-right {
clip-path: polygon(
0% 0%,
75% 0%,
75% 25%,
100% 50%,
75% 75%,
75% 100%,
0% 100%
);
}
/* Hexagon */
.hexagon {
clip-path: polygon(
50% 0%,
100% 25%,
100% 75%,
50% 100%,
0% 75%,
0% 25%
);
}
/* Star */
.star {
clip-path: polygon(
50% 0%,
61% 35%,
98% 35%,
68% 57%,
79% 91%,
50% 70%,
21% 91%,
32% 57%,
2% 35%,
39% 35%
);
}
/* Inset with rounded corners */
.inset-rounded {
clip-path: inset(10px 20px 30px 40px round 20px);
}
Example: Advanced clip-path and text wrapping
/* Diagonal clip */
.diagonal {
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
}
/* Notched corner */
.notched-corner {
clip-path: polygon(
0 0,
calc(100% - 20px) 0,
100% 20px,
100% 100%,
0 100%
);
}
/* Message bubble */
.bubble {
clip-path: polygon(
0% 0%,
100% 0%,
100% 75%,
75% 75%,
75% 100%,
50% 75%,
0% 75%
);
}
/* Animated clip-path */
@keyframes reveal {
from {
clip-path: circle(0% at 50% 50%);
}
to {
clip-path: circle(100% at 50% 50%);
}
}
.reveal-animation {
animation: reveal 1s ease-out;
}
/* Text wrapping with shape-outside */
.float-circle {
float: left;
width: 200px;
height: 200px;
shape-outside: circle(50%);
clip-path: circle(50%);
margin: 0 20px 20px 0;
}
/* Polygon text wrap */
.float-polygon {
float: left;
width: 200px;
height: 200px;
shape-outside: polygon(0 0, 100% 0, 100% 100%);
clip-path: polygon(0 0, 100% 0, 100% 100%);
shape-margin: 20px; /* Space between shape and text */
}
/* Image-based shape */
.float-image {
float: left;
shape-outside: url('/shape-mask.png');
shape-image-threshold: 0.5; /* Alpha threshold */
}
Note:
clip-path clips element visibility. shape-outside affects text
wrapping around floated elements. Use polygon() for custom shapes. Animated
clip-path creates reveal effects.
5. CSS Masking and Advanced Clipping
| Property | Values | Description | Use Case |
|---|---|---|---|
| mask-image | url() | gradient | none |
Image/gradient used as mask | Alpha-based masking |
| mask-mode | alpha | luminance | match-source |
How mask image is interpreted | Alpha vs luminance masking |
| mask-repeat | repeat | no-repeat | space | round |
Mask tiling behavior | Repeating patterns |
| mask-position | position |
Mask positioning | Align mask |
| mask-size | size | cover | contain |
Mask sizing | Scale mask |
| mask-origin | border-box | padding-box | content-box |
Mask positioning area | Box model reference |
| mask-clip | border-box | padding-box | content-box | text |
Mask clipping area | Limit mask area |
| mask-composite | add | subtract | intersect | exclude |
Combine multiple masks | Complex masking |
| mask | image position / size repeat origin clip composite mode |
Shorthand for all mask properties | - |
| -webkit-mask-* | Various | Webkit prefix versions | Better browser support |
Example: Image and gradient masks
/* Image mask (requires webkit prefix for Safari) */
.image-mask {
-webkit-mask-image: url('/mask.png');
mask-image: url('/mask.png');
-webkit-mask-size: cover;
mask-size: cover;
}
/* Gradient mask (fade to transparent) */
.gradient-mask {
-webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 100%);
mask-image: linear-gradient(to bottom, black 0%, transparent 100%);
}
/* Radial gradient mask (vignette effect) */
.vignette {
-webkit-mask-image: radial-gradient(
circle at center,
black 50%,
transparent 100%
);
mask-image: radial-gradient(
circle at center,
black 50%,
transparent 100%
);
}
/* Text mask (image visible through text) */
.text-mask {
background: url('/texture.jpg') center/cover;
-webkit-mask-image: linear-gradient(black, black);
mask-image: linear-gradient(black, black);
-webkit-mask-clip: text;
mask-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
/* Multiple masks */
.multi-mask {
-webkit-mask-image:
linear-gradient(to right, black 50%, transparent),
linear-gradient(to bottom, black 50%, transparent);
mask-image:
linear-gradient(to right, black 50%, transparent),
linear-gradient(to bottom, black 50%, transparent);
-webkit-mask-composite: source-in;
mask-composite: intersect;
}
Example: Advanced masking techniques
/* Fade edges effect */
.fade-edges {
-webkit-mask-image: linear-gradient(
to right,
transparent 0%,
black 5%,
black 95%,
transparent 100%
);
mask-image: linear-gradient(
to right,
transparent 0%,
black 5%,
black 95%,
transparent 100%
);
}
/* Spotlight effect */
.spotlight {
-webkit-mask-image: radial-gradient(
circle 150px at var(--mouse-x, 50%) var(--mouse-y, 50%),
black 0%,
transparent 100%
);
mask-image: radial-gradient(
circle 150px at var(--mouse-x, 50%) var(--mouse-y, 50%),
black 0%,
transparent 100%
);
}
/* Striped mask */
.striped-mask {
-webkit-mask-image: repeating-linear-gradient(
45deg,
black 0px,
black 10px,
transparent 10px,
transparent 20px
);
mask-image: repeating-linear-gradient(
45deg,
black 0px,
black 10px,
transparent 10px,
transparent 20px
);
}
/* SVG mask reference */
.svg-mask {
mask: url(#custom-mask);
}
/* Mask composite operations */
.mask-subtract {
-webkit-mask-image:
radial-gradient(circle at 30% 30%, black 20%, transparent 20%),
radial-gradient(circle at 70% 70%, black 20%, transparent 20%);
mask-image:
radial-gradient(circle at 30% 30%, black 20%, transparent 20%),
radial-gradient(circle at 70% 70%, black 20%, transparent 20%);
-webkit-mask-composite: source-out;
mask-composite: subtract;
}
/* Animated mask */
@keyframes mask-move {
from {
-webkit-mask-position: 0% 0%;
mask-position: 0% 0%;
}
to {
-webkit-mask-position: 100% 100%;
mask-position: 100% 100%;
}
}
.animated-mask {
-webkit-mask-image: linear-gradient(45deg, black 50%, transparent);
mask-image: linear-gradient(45deg, black 50%, transparent);
-webkit-mask-size: 200% 200%;
mask-size: 200% 200%;
animation: mask-move 3s linear infinite;
}
Example: Practical masking use cases
/* Image gallery with shape masks */
.gallery-item {
-webkit-mask-image: url('/hexagon-mask.svg');
mask-image: url('/hexagon-mask.svg');
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-position: center;
mask-position: center;
}
/* Frosted glass with gradient mask */
.frosted-panel {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
-webkit-mask-image: linear-gradient(
to bottom,
black 0%,
black 80%,
transparent 100%
);
mask-image: linear-gradient(
to bottom,
black 0%,
black 80%,
transparent 100%
);
}
/* Progress bar with mask */
.progress-masked {
background: linear-gradient(90deg, blue, purple);
-webkit-mask-image: linear-gradient(
90deg,
black 0%,
black var(--progress, 50%),
transparent var(--progress, 50%)
);
mask-image: linear-gradient(
90deg,
black 0%,
black var(--progress, 50%),
transparent var(--progress, 50%)
);
}
/* Text reveal with mask */
.text-reveal {
background: linear-gradient(90deg, red, blue);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
-webkit-mask-image: linear-gradient(
90deg,
black 0%,
black var(--reveal, 0%),
transparent var(--reveal, 0%)
);
mask-image: linear-gradient(
90deg,
black 0%,
black var(--reveal, 0%),
transparent var(--reveal, 0%)
);
}
Warning: CSS masks require
-webkit- prefix for Safari
support. mask-composite values differ between standard and webkit (use
source-in, source-out, etc. for webkit).
Borders & Shapes Best Practices
- Use
outlinefor focus indicators (doesn't affect layout) - Use
border-imagewith gradients for gradient borders - Use layered box-shadows for realistic depth (2-3 layers)
- Use
filter: drop-shadow()for transparent images instead of box-shadow - Use
clip-pathfor custom shapes,shape-outsidefor text wrapping - Animate
clip-pathfor reveal effects (requires same number of points) - Use CSS masks for alpha-based visibility (gradients, images)
- Include
-webkit-prefix for mask properties (Safari support) - Use
border-radiuspercentages for organic shapes (combine horizontal/vertical radii)