Building a stamp border in CSS

Building a stamp border in CSS

For Valentine’s Day this year, I'm running a special event with the folks who have purchased one of my courses. For this event, I wanted to create a landing page that had a scrapbook / hand-made-card kind of vibe.

I wound up creating a “stamp” style effect, and I wanted to write up a lil’ tutorial, so you could see how it works, and use it yourself!


Let's start with the final code. It looks scary, but don't worry! We’ll break it down.

Screenshot of code. For the raw text, see the Codepen at the end of this article
Credit to T. Afif, who came up with the original implementation

Step 1: We need a background image! Essentially we want to create a square with a hole punched out. The hole should be a circle with the radius equal to "--radius". It defaults to 8px, but it can be set to any number.

Here's what we need to create:

A white square with a punched hole in the center

Once we have this image, we can tile it across the entire area. For now, we want a "Connect 4" board like this:

A white box with a bunch of evenly spaced punched holes

Here's the code at this point:

(To keep things simple, I'm using hardcoded values rather than the

The radial-gradient is “transparent” from 0% to 98%, and then fades to “white” in those final 2%. This produces a sort of anti-aliasing effect. If we bump it up to 100%, we get a pixellated edge.

Here's a lil’ diagram explaining this gradient:

A circle that is transparent for most of it, with a border that fades to white

Remember, we're creating a square image that can be repeated. That square has a size of 24×24 pixels, because it includes the diameter of the circle (16px) and some extra space on each side:

The original square-with-cutout diagram, but with all the measurements labeled. 24px total.


Step 2: we want the holes to run along the edge of the box.

First, let's shift it up and to the left with background-position. We want to shift it up by half of its size (so, 12px in each direction).

This is the result:

The same "Connect 4" board, except now the top and left edges are correct, with the holes running along the edge.

The top and left edge look great! But the right and bottom aren't quite right. Unless our box happens to be a perfect multiple of 24px, we won't get that nice stamp effect.

Fortunately, we can solve this problem with a single tweak: background-repeat: round.

 Woohoo! The same "connect 4" card with punched holes, but all 4 edges are correct.

Amazing, right? round is similar to repeat, but it rounds the number of repeated images. So, instead of having 20.236 copies running horizontally, it rounds it to 20, and adds a bit of space between each instance.

As a result, it always fits perfectly. ?


Step 3: the last problem is that we only want the holes to run along the edge, not across the entire card.

We can solve this by “painting over” the holes in the middle, by adding a linear-gradient that is solid white, and insetting it by half of the image size (12px).

A white box is covering all of the holes except the ones along the edges. The box is 12px from each edge.

Here's the code for just the white rectangle:

And that's pretty much it!

We can apply both backgrounds by comma-separating all the values, so we wind up with 2 gradients applied to the same item. And instead of hardcoding all the numbers, we'll use a --radius CSS variable, and calc() for all the calculations.

You can see the effect “in context” on my custom “Valentine’s Day” page.

(Also! If you've purchased either “CSS for JavaScript Developers” or “The Joy of React”, you'll have received a 50%-off coupon you can gift to your valentine, or a friend / co-worker. The coupons only last a few more days!)


Finally, you can poke around with this code yourself here: https://codepen.io/joshwcomeau/pen/VwRqQGP

Thanks again to T. Afif for coming up with such an elegant solution! My original approach used dozens of SVGs ??. I'm way happier with this.

Hope this was helpful ??






要查看或添加评论,请登录

Joshua Comeau的更多文章

  • ?Little Details ?

    ?Little Details ?

    I'm spending some time adding some micro-animations to my course platform. the GIF above shows an interaction I've been…

    9 条评论

社区洞察

其他会员也浏览了