Repeating Square Dots Backgrounds in CSS

Chris Coyier Chris Coyier on

I saw this reasonable ask for help the other day.

Post by @pawelgrzybek@mastodon.social
View on Mastodon

Note that the example above has little circular dots, and what Paweł is asking about are little square dots. This is the example look from atproto.com:

Repeating a Small Area

My first thought is we’re obviously not drawing all these dots in one big graphic. We’re drawing one, leaving empty space, and using our ol’ pal background-repeat: repeat;

In order for the repeating to work, we need to define a smaller space via background-size. So let’s say it’s…

html {
  background-size: 100px 100px;
  background-repeat: repeat;
}Code language: CSS (css)

Now we’ve got a 100px square that will repeat over the entire background. We just need to fill that 100px square with a smaller square that repeats.

Drawing the Square Dot

Again my first thought was that we could make it look like we’re drawing a small square dot by actually letting a background-color show through and covering up everywhere else. So like a three-layer system:

html {
  background: 
    linear-gradient(to bottom, transparent 10px, white 10px),
    linear-gradient(to right, transparent 10px, white 10px),
    black;
}Code language: CSS (css)

If we flatten out that visual, you can see the three shapes smoosh down into a small square, which we then repeat.

That’s what’s going on here exactly:

Uh Oh — Transparency?

The problem with the above is that we need a solid color to be the “mask” that covers all the area except the mask. This means we can’t have, for example, one big image behind the dots or a gradient or anything (without more exotic trickery). The problem is we don’t have proper transparency.

What we want to be doing is drawing the dot with one “gradient”, if we can, and leaving the rest of the area empty/transparent.

Enter Conic Gradients

I didn’t think of this! Eric Meyer had the clever idea. The idea is that you can use conic-gradient to describe what we want in one go. “Hard stop” color stops are in use here, the classic trick to make a gradient just bands of solid color, not actually gradients. But in this case, three-quarters of the area is transparent, and the last bit is the dot color.

html {
  background-image: 
    conic-gradient(
      from 0deg at 5px 5px, 
      transparent 75%, black 75% 100%
    );
}Code language: CSS (css)

This took me a sec to understand, but it’s essentially setting the center of the conic gradient at a specific spot, then forcing most of the way around to be transparent and leaving the last bit as the dot.

Then we use the same concept as before where we set a smaller background-size and let it naturally repeat, and we’ve got square dots with a transparent background!

Want to expand your CSS skills?

3 responses to “Repeating Square Dots Backgrounds in CSS”

  1. Ana Tudor Ana Tudor says:

    There’s no need for from 0deg, that’s the default. There’s also no need to set the final stop to 100% – again, that’s the default.

    And there’s no need to repeat 75% – if the position of the second stop is smaller than that of the first, it will get taken to be equal to that of the first, 75% in this case. So we can take the second stop position to be 0%.

    This is what I always do for such patterns. Fun fact, this is very similar to the “lined paper” effect along both axes, in which case we want 25% to be transparent, not 75%. This means having the conic gradient at a line thickness from the top left corner along both axes, as well as starting from 90deg – 3 o’clock.

    Something that can be seen on this card https://codepen.io/thebabydino/pen/YPpqaWM

    Also, when not setting a background-size, combined with a transparent thick border and a background-position that’s half the line thickness along both axes, we can get a nice frame effect https://codepen.io/thebabydino/pen/gbMjEEd

    • That pure-css card parallax is insane! I couldn’t believe there was no JS until I inspected it myself and figured out how they did it. Incredible. Eventually with sibling-index that should become even easier, too.

      • Ana Tudor Ana Tudor says:

        That parallax technique is old, I first used it over a decade ago for a demo, even if the linked one I made recently.

        And I really would not recommend using it on an actual website, it’s a performance and accessibility nightmare. I’d rather see exposing pointer position to CSS become a reality https://github.com/w3c/csswg-drafts/issues/6733

        Especially since this in particular won’t become easier with sibling-index().

        sibling-index() gives you the index of the element you apply it to among its siblings. But here you need the index of another element that may not even be a sibling of the element you apply it on now that we have :has().

        That is, here sibling-index() could give you the index of a .trap element if you needed to style that .trap element … which you don’t, the .trap elements are just invisible divs to catch the hover. What you do need is the index of the currently hovered .trap element in order to style the actual .card element. And when styling the .card element, sibling-index() gives you the index of the .card element among its siblings, not the index of the currently hovered .trap element.

Leave a Reply

Your email address will not be published. Required fields are marked *

$966,000

Frontend Masters donates to open source projects through thanks.dev and Open Collective, as well as donates to non-profits like The Last Mile, Annie Canons, and Vets Who Code.