Shapes Clippath
The CSS clip-path property crops an element into a non-rectangular shape like a circle, polygon, or arrow, while shape-outside lets surrounding text wrap around that shape for magazine-style layouts.
Part of the free HTML & CSS course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll be able to cut any element into a circle, hexagon or arrow with clip-path , animate those clips for reveal effects, wrap paragraphs around shapes with shape-outside , and fade an image edge with a CSS mask — the toolkit behind every "how did they do that?" layout.
What You'll Learn
💡 Think of It Like This
clip-path is a cookie cutter. You press a shaped cutter onto a sheet of dough and only the dough inside the cutter stays — but the whole sheet is still on the table underneath. The element keeps its full rectangle for layout and clicks; you've only changed what shows through .
shape-outside is a stone dropped in a stream. The water (your text) doesn't flow through the stone — it bends and hugs the outline as it passes. And a mask is a stencil with a gradient : where the stencil is solid the paint lands fully, where it fades the paint fades too, so you can dissolve an edge into nothing.
1. The Four Basic Shapes
clip-path defines a clipping region: everything inside the shape is visible, everything outside is hidden (but still in the DOM). You build that region with a shape function. Four cover almost everything:
Function
Shape
Example
circle()
Round, radius + centre
circle(50% at 50% 50%)
ellipse()
Oval, two radii
ellipse(40% 60% at 50% 50%)
inset()
Rectangle pulled in from edges
inset(10% round 12px)
polygon()
Any shape from x% y% points
polygon(50% 0%, 0% 100%, 100% 100%)
Run the worked example. Each tile is an ordinary < div > with a background colour — only the clip-path line differs. Read the comments to see how each function maps to a shape.
2. polygon() — The Coordinate Workhorse
polygon() is the one you'll reach for most. Each point is an x% y% pair measured from the element's own box: 0% 0% is the top-left corner, 100% 100% the bottom-right. List the points in order around the outline — walk the perimeter clockwise — and the browser joins them with straight lines.
That single rule gives you hexagons, stars, arrows and diagonal section edges. The worked example below annotates a hexagon point by point so you can see the walk.
3. shape-outside — Wrap Text Around a Shape
By default, text wraps around the rectangular box of a floated element, even if the element looks round. shape-outside changes the wrapping contour to a shape you choose, so paragraphs hug a circle or a pentagon like a magazine layout.
Three things must be true for it to work: the element is floated , it has an explicit width and height , and the text is a sibling after it. Use the same shape for shape-outside (the wrap) and clip-path or border-radius (the look) so they line up.
4. Animating clip-path — Reveals & Morphs
Because clip-path is animatable, you can grow a circle from nothing to reveal an image, or morph one polygon into another. The catch: the browser can only tween between two values that use the same function with the same number of points . A circle() animates to another circle() ; a 4-point polygon morphs to another 4-point polygon. Mismatched counts jump instantly instead of sliding.
5. mask-image & Creative Sections
Where clip-path makes a hard edge, mask-image can make a soft one. A mask uses an image (often a gradient) as an alpha stencil: where the mask is opaque the element shows, where it's transparent the element fades out. A linear-gradient mask dissolves an edge into nothing — perfect for fading the bottom of a hero image.
Combine these tricks for the layouts people notice: a diagonal clip-path section edge, plus a masked fade. The example shows both.
🎯 Your Turn #1 — Clip a hexagon and an inset card
Fill in the blanks marked ___ to clip one tile into a hexagon and another into an inset rounded rectangle. Run it and check the expected result in the comments.
🎯 Your Turn #2 — Wrap text and add a reveal
One float needs shape-outside so the text hugs the circle, and one box needs a hover transition so its circle clip grows. Fill in the blanks, then verify against the comments.
🧩 Mini-Challenge — A diagonal hero from scratch
Support is faded now — only an outline is given. Build a hero section with a slanted bottom edge. Lean on sections 1, 2 and 5 if you get stuck.
⚠️ Common Errors (and the fix)
- The clipped-away corners still catch clicks. clip-path hides pixels but keeps the full rectangular hit area, so the invisible corners still register hover and clicks (and can steal them from elements behind). Fix: add pointer-events: none to the clipped element, or make a smaller inner element the click target.
- Overflow leaks past the parent. A clipped image inside a box can still spill or show scrollbars on the wrapper. Fix: set overflow: hidden on the parent so anything outside the clip is contained.
- shape-outside does nothing. It only applies to a floated element that has an explicit width and height . Miss the float or the size and the browser silently wraps text around the plain rectangle. Fix: add float: left (or right) and a fixed size.
- Animation jumps instead of sliding. Transitioning a 3-point shape to a 6-point shape (or circle() to polygon() ) can't interpolate. Fix: match the function and the point count on both sides — add duplicate vertices to the simpler shape if needed.
- Polygon looks tangled. Listing points out of order makes edges cross. Fix: order the points by walking the outline once, clockwise or counter-clockwise — don't jump between opposite corners.
- mask works in Safari but not "everywhere". Some engines still want the prefix. Fix: write -webkit-mask-image alongside mask-image , and treat the effect as progressive enhancement so unsupported browsers just see the un-masked element.
📋 Quick Reference
Goal
Use this
Clip to a circle
clip-path: circle(50% at 50% 50%);
Clip to an oval
clip-path: ellipse(40% 60% at 50% 50%);
Inset rounded rectangle
clip-path: inset(10% round 12px);
Custom shape
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
Slant a section edge
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
Animate a clip
transition: clip-path .5s ease; (same shape + point count)
Wrap text around a shape
float:left; shape-outside: circle(50%);
Fade an edge
mask-image: linear-gradient(black, transparent);
Stop clipped corners catching clicks
pointer-events: none;
❓ Frequently Asked Questions
🎉 Lesson Complete
You can now cut, wrap and fade elements into shapes most sites never attempt. The essentials:
- ✅ circle() , ellipse() , inset() and polygon() clip an element to a shape
- ✅ Polygon points are x% y% pairs listed in order around the outline
- ✅ Animate clip-path only between same-shape, same-point-count values
- ✅ shape-outside wraps text around a shape — but needs float + size
- ✅ mask-image with a gradient fades an edge into nothing
- ✅ Clipping is visual only — the full box still catches clicks unless you set pointer-events: none
Next up: Filters & Blend Modes , where you'll blur, tint and blend layers for even richer visual effects.
Practice quiz
What does the clip-path property do to an element?
- Deletes part of it from the DOM
- Changes its background colour
- Crops it to a shape — everything inside the shape shows, everything outside is hidden
- Moves it off-screen
Answer: Crops it to a shape — everything inside the shape shows, everything outside is hidden. clip-path defines a clipping region: the visible part is whatever falls inside the shape; the rest is hidden but still in the DOM.
How is each point in polygon() written?
- As an x% y% pair relative to the element's own box
- As an angle in degrees
- As pixel offsets from the center
- As a single radius value
Answer: As an x% y% pair relative to the element's own box. Each polygon() point is an x y pair in percentages of the element's box: 0% 0% is top-left, 100% 100% is bottom-right.
What does clip-path: polygon(50% 0%, 0% 100%, 100% 100%) produce?
- A circle
- A square
- A hexagon
- A triangle (top-center, bottom-left, bottom-right)
Answer: A triangle (top-center, bottom-left, bottom-right). Three points — top-center, bottom-left, bottom-right — joined by straight lines form a triangle.
Why must polygon() points be listed in order around the outline?
- For performance
- Jumping between non-adjacent points makes the edges cross, producing a tangled shape
- Browsers require alphabetical order
- Order doesn't matter
Answer: Jumping between non-adjacent points makes the edges cross, producing a tangled shape. The browser joins points in the order given, so walk the perimeter clockwise (or counter-clockwise); jumping around creates crossed, tangled edges.
Why is a clipped element's hidden area still clickable?
- clip-path is purely visual — the element keeps its full rectangular box for layout and hit-testing
- A browser bug
- Because of z-index
- It isn't clickable
Answer: clip-path is purely visual — the element keeps its full rectangular box for layout and hit-testing. clip-path only changes what's visible, not the geometry. The full rectangle still registers clicks; add pointer-events: none to stop the invisible area catching them.
Why might a clip-path transition jump instantly instead of animating smoothly?
- The duration is too short
- clip-path can't be animated
- The two shapes use different functions or different numbers of points, so the browser can't interpolate
- The element has no background
Answer: The two shapes use different functions or different numbers of points, so the browser can't interpolate. Interpolation needs the same shape function and the same point count on both sides — a circle() to circle() or a 4-point polygon to another 4-point polygon.
What three conditions must be true for shape-outside to take effect?
- Any element, any size, any position
- The element must be floated, have an explicit width and height, and the text must be a sibling after it
- It must be position: absolute
- It only needs a background image
Answer: The element must be floated, have an explicit width and height, and the text must be a sibling after it. shape-outside only works on a floated element with an explicit size, with the wrapping text as a following sibling; otherwise text wraps the plain rectangle.
What is the key difference between clip-path and shape-outside?
- They are the same property
- shape-outside crops the element
- clip-path only works on images
- clip-path changes the element's own visible shape; shape-outside changes how nearby text wraps around it
Answer: clip-path changes the element's own visible shape; shape-outside changes how nearby text wraps around it. clip-path cuts the element's appearance; shape-outside controls the contour that surrounding text flows around. They're independent and often paired.
How does a gradient mask-image fade an element's edge?
- By blurring the pixels
- It acts as an alpha stencil — where the mask is opaque the element shows, where transparent it fades out
- By lowering the element's opacity uniformly
- By cropping it to a circle
Answer: It acts as an alpha stencil — where the mask is opaque the element shows, where transparent it fades out. mask-image uses the image's alpha: a linear-gradient from black to transparent dissolves that edge into nothing, e.g. fading the bottom of a hero image.
Which clip-path polygon slants only the BOTTOM edge of a section?
- polygon(50% 0%, 0% 100%, 100% 100%)
- circle(50%)
- polygon(0 0, 100% 0, 100% 85%, 0 100%)
- inset(10%)
Answer: polygon(0 0, 100% 0, 100% 85%, 0 100%). Keeping the top two points flat (0 0 and 100% 0) and offsetting the bottom two (100% 85% vs 0 100%) cuts the bottom edge on a diagonal.
Continue this course
- Previous: Advanced Positioning
- Next: Filters & Blend Modes