Index Of /

CSSBattle patterns

June 14, 2019

A couple of days ago I've noticed a discussion on Twitter about CSSBattle — a web app where you must compose HTML and CSS to match one of the target images. The goal is to match the image perfectly and to do that with the shortest possible code. I thought it's can be refreshing for my mind and tried it. The first target seems easy but actually was not so easy, second... well, I can't even imagine what the competition leaders are using to achieve such results.

I must warn you right away, that it's very, very time consuming if you try to get a good result.

I'll try to tell you what kind of patterns I'm using for now. Maybe this can help you and if you find out how to get even slimmer — don't hesitate to write to me on Twitter.

HTML Tags

There are two HTML-tags I'm using in almost all of the targets: <p> and <img>.

The paragraph is a block element, just like div, but you cannot put a paragraph inside another one — it will be closed automatically. So you don't have to write closing tags. You should keep in mind that paragraphs have initial margins thou.

Images are the natural inline-blocks. You don't have to write any code to use them to create any shapes. There are two things that you need to remember about images: there's a border if you don't set any value to the src attribute (and you will not going to set it — you cannot use images) and it can't contain any other element. Otherwise, images are perfect and I'll show you later how to use them.

There are already two tags you can use — html and body, so theoretically you can have just styles with no HTML-tags at all. And that also means you should keep in mind that you have an initial margin: 8px.

HTML Attributes

You'll find a lot of tips on the project's Tips and Tricks page. My favorites are about attributes:

There's a bunch of ways to stylize elements of the same kind differently: class names, id's, combinator selectors, pseudo-classes. But the shortest way is probably one-letter attributes:

<p a><img b> 
<style>
[a]{...}
[b]{...}

The other thing you can use attributes is to use the style directly on the element. In some cases, style attribute can be shorter — no brackets, no selector and you can even omit the quotes around the value if you use pluses instead of spaces:

<img style=color:fdc57b;box-shadow:317px+217px+0+25px,...>

So if you are using only one element — you probably want the style attribute.

SVG

Unfortunately using SVG is now forbidden.

As well as all of the external resources you can get: images, iframes, etc.

Styles

Since it's a CSS battle, styles are the most tricky part. Here are a few patterns you can use.

Borders for size and color

Using borders you can set the size and color of the <img> much shorter, than using width, height, and background. Especially if the object has a square form. To shorten the record you should use the border style first, then width and color at the end. Here you'll have a square element 50px wide with #fc0 color:

img{border:solid 25px#fc0}

Also, setting borders for the image will replace its default border (good). And if you don't need the element to be square you can always alter the size using border-radius border-width.

Shadows

A mighty weapon in your arsenal. You can use multiple shadows on one element, setting the distance from the element and the size of the shadow. Used with an empty <img> tag it'll give you a lot of square elements (even zero size image is square!):

img{box-shadow:10px 10px 0 25px#d86f45,50px 10px 0 25px#d86f45}

The shadow color can be set using the text color property if it's repeating to save a few characters:

img{color:#d86f45;box-shadow:10px 10px 0 25px,50px 10px 0 25px}

Text color also can be used for borders.

One more thing you should know about shadows is that shadows are cut by the element itself. And to show a moon, for example, all you have to do is:

<div style="width: 100px; height: 100px; border-radius: 50%; box-shadow: 20px 10px 0 10px;"></div>

Transformations

Sometimes transform values (esp. rotate) can give side effects: blur, an outer glow of the background color outside the border, tiny lines between borders, etc. And the site mechanics will not give you a 100% match with the target. You need to be careful with it and change the strategy if that happens: overlap elements or use a different technique.

Clipping

I've tried with several targets to use clip-path, but all of my solutions were shorter with shadows and borders. And the lack of support for multiple clip regions is something I could wish for the next CSS versions.

Units

Don't forget that not every css property requires from the author to specify the units: width, height, margin, padding, border-width, top, right, bottom, left and their derivatives (eg. margin-left) all defaults to px. This can save you a few bytes when you write the styles.

You can save also if you use other units than px. I was using this CSS Unit Converter to get desired values shorter: 128px is equal to 8em. Or you can use inches if you have to set something big. For example, setting the body background-color can be set in your single element solution like this:

<img style=box-shadow:{other shadows},0+0+0+9in#62374e>

I usually achieve the target using px and then tried to convert the values to something shorter

Finally

Remove the closing </style> tag — you don't need it — and, of course, all the comments at the end ;-))

Happy coding!

Andrey “Leechy” Lechev

Some frontender thoughts
Twitter, GitHub, LinkedIn