When we talk about CSS shapes, it’s almost like we’re talking about values moreso than properties. What I mean is that the value functions like polygon(), circle(), ellipse(), offset(), path(), etc. are more representative of “CSS shapes” than the properties they are applied to. Multiple properties take them, like shape-outside, clip-path, and offset-path.

Oh hey, so tomorrow (tomorrow!) is Election Day here in the United States. We’re not in the business of making political endorsements or anything like that at CSS-Tricks, though we do endorse that everyone exercise their right to vote.

I have a little time, so I’m going to try to re-create this sticker in CSS and walk through my thought process as I do it. Feel free to follow along if you’d like!

Breaking down the elements

Anytime I’m given a design of any kind, I like to pretend that my eyes have the superpower of X-ray vision and can see through the design as if it were a skeleton. This helps me start to think through how many elements I might use in the HTML.

The alignment is all off. Seems like a good spot to drop in some flexbox. This will allow me to center our elements horizontally. I think going with a single-column layout will take care of the vertical alignment.

The last thing I want to do with the sticker for now is split it up into two halves — a top and a bottom. OK, so yeah, I have explicit elements for those in the HTML (.sticker__top and .sticker__bottom). I could use background-color on each element to make the top half blue and bottom half red, but I actually like the idea of using a linear gradient instead with a hard stop at the halfway mark.

Time to deal with the top half

The top and bottom halves both occupy 50% of the sticker’s height, so the selectors can be combined to hit them both at once. Plus, I’m using flexbox, so I can simply flex those items.

.sticker__top,
.sticker-bottom { flex: 0 50%;
}

The top half is super weird. The way I see it, there’s two rows: one that contains the stars and stripes and the other that contains the heading. I’m going to turn to flexbox again to draw that layout.

That’s not really going to change much at the moment because, well, I haven’t done anything to define elements for the stars and stripes in the HTML. I’m thinking of using the ::before and ::after pseudo elements on .sticker__top to make those. Again, they can be combined since they share some common properties and values.

.sticker__top::before,
.sticker__top::after { content: ""; height: 45%; /* Had to play with this a bit */ margin-top: 2em; /* Move away from the top edge of the sticker */
}

I’m going to cheat and use SVG for the stars. I mean, I guess that’s not cheating but it sorta feels like a deviation from a “pure” CSS way of doing things. Oh well.

That said, the stripes can definitely be made in CSS, again, with the same linear gradient background technique that’s used to split the sticker up into blue and red halves.

If I stop here, the shape of the stars and stripes would be all off and the heading font would be sloppy.

border-radius is still a good way to get the stars and stripes to follow the same circular path as the sticker. The rub is that the bottoms of them have to maintain a flat edge. Since border-radius is a shorthand property, I’m going to drop border-top-left-radius on the stars and border-top-right-radius on the stripes.

It’s also worth noting that the stripes are a little wider than the stars. Maybe a 55-45 split? I don’t know. I’ll go with that and also use relative positioning on the stripes so I can push them to the right a bit to add separation between them and the stars.

The stars and stripes should flex with the size and width of the heading. I had to play with the font family, font size, letter spacing, and text transform to get something that looks pretty nice. In case you’re wondering, I wound up using Raleway for the font. It’s not precise, but close enough… at least to my untrained typographical eye.

Alright, so now the bottom half is making my skin crawl. Gotta tackle that.

Style up the bottom half

So much has already been done. The element for bottom half is already there in the HTML and is sized and positioned the way it should be. I think stripping out the bullet points of the list items and removing the left padding from the unordered list will clean things up a lot.

Now I have to make a few tweaks to .sticker__bottom. Specifically, I’m going to make it a little narrower (80% of the full sticker width) to get it off the edge of the sticker and then round its edges… though it might not actually need rounded corners since content is not going to overflow.

Ding, ready!

I’m going to call this one baked. I know, I know. I should cross-browser test. It would also be wise to find graceful fallbacks for older browsers that do not support flexbox. And, some responsiveness would be nice to have. Maybe someone would like to take those up and share. 😉

Is this the best way to make the sticker? Probably not. For example, I bet there are some interesting things that can be done with clip-path instead of the way I fumbled through background gradients. And, if I had to do it again, I might even consider going with a CSS Grid layout on the parent because there are clearly opportunities to work in two directions instead of one.