CSS Funstuff: C-c-combo Breaker!!!
Tags: css, codenewbie, design, webdev
Published: 2022-04-03 01:44:48

_Hi y'all! I'm back with another fun CSS tutorial that will both teach you some CSS skills **and** show you how to make something awesome!_

## Before we get started!

For this tutorial, I highly recommend that you familiarize yourself with CSS Combinators if you haven't already. To help you out with that, you can grab the free guide I've put together [from my Gumroad page.](https://rolandixor.gumroad.com/l/xqulv)

### Update: You can now play it online!!!

If you'd like to skip to the fun stuff, or if you're just not familiar with CSS OR don't feel like coding...

You can [play the game from my website!](https://rolandixor.pro/games/css/combo-breaker/)

*Once you're up to speed on that...*

## Let's dive in!

We always like to set the box-sizing, margin, and padding properties for all our elements, so you can add the following code to your CSS.

```css
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
```

We're also going to be using a single custom property for this tutorial, `--bg`, which will be used for setting the background colour of the elements in the combo.

```css
:root {
   --bg: rgb(35, 135, 235);
}
```

Finally in terms of setup, let's set some properties on the body. Some of these are shared with other projects in the series, but the rest of them are specific to the layout we're going to use this time.

**For that, let's use the following CSS code:**

```css
body {
   align-items: center;
   background-color: rgb(35, 35, 35);
   color: white;
   display: flex;
   flex-flow: column;
   font-family: 'Lato', sans-serif;
   font-size: 1.365em;
   font-weight: 300;
   gap: 15px;
   height: 100vh;
   justify-content: center;
   letter-spacing: .135em;
   width: 100vw;
}
```

With all this place, you should have a blank canvas to build upon. Remember to link up your CSS to your HTML if you haven't already.

## Building our HTML:

There are lot of "moving" parts to this, so get ready to do some typing... _or_ just copy and paste. Yeah, I recommend copying and pasting this one.

**The HTML code:**

```css
   <body>
      <h1>ComboBreaker</h1>
      <main>
          <input class="combo-0" type="checkbox">
          </input>
          <input class="combo-1" type="checkbox">
          </input>
          <input class="combo-2" type="checkbox">
          </input>
          <input class="combo-1" type="checkbox">
          </input>
          <input class="combo-0" type="checkbox">
          </input>
          <input class="combo-1" type="checkbox">
          </input>
          <input class="combo-2" type="checkbox">
          </input>
       </main>
   </body>
```
## What are we building?
Well... By now, you can probably tell that we're going to be creating some kind of a simple game, and yes... IN CSS!!!

You can add the goal below your `<main>` element if you'd like:

```html
<p>
   The goal is to try to turn all of the circles
   white. Can you unlock the combo?
</p>
```

### Doing things with style!
Before we get to the logic of the "game", let's add some simple styling to the `<main>`, `<h1>` and `<p>` elements.

```css
main {
  align-items: center;
  display: flex;
  gap: 15px;
  justify-content: center;
}

h1 {
  margin: 2.35vh;
}

p {
  margin: 7.35vh;
}
```

We'll follow this up by styling the inputs and their associated pseudo-elements:

```css
[class*='combo']::after {
  aspect-ratio: 1/1;
  background-color: var(--bg);
  border-radius: 50%;
  content: '';
  display: block;
  position: absolute;
  inset: -50% 0 0 0;
  transition: all 1s ease-in-out;
  width: 50px;
}

[class*='combo']::before {
  aspect-ratio: 1/1;
  background-color: #ffffff00;
  border: 5px solid transparent;
  outline: 2px solid white;
  border-radius: 50%;
  content: '';
  display: block;
  position: absolute;
  inset: 435% 0 0 17px;
  transition: all 1s ease-in-out;
  width: 10px;
}

[class*='combo']:checked:before {
  aspect-ratio: 1/1;
  background-color: white;
  border: 2px solid transparent;
  outline: 2px solid white;
  border-radius: 50%;
  content: '';
  display: block;
  position: absolute;
  transition: all 1s ease-in-out;
}

input {
  aspect-ratio: 1/1;
  position: relative;
  width: 50px;
}
```

This should give you something like this:

![Screenshot of the result so far](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2hjupbvd4v2srjhbrrk.png)

## Building The Logic
Now, here's where things get tricky, and I have to admit, this took me a while to figure it all out.

But, it's well worth it because it demonstrates that CSS is more than just a "descriptive language", it's got logic and interaction, too. For the sake of simplicity, I've kept things down to a single line and just three possible combinations, but you can make this as complex as you'd like, and it should still work.

You just have to understand how CSS combinators work.

### The code:

For each of our inputs, we'll modify the variable we added at the beginning. It will set the background color for each one.

Thanks to the power of CSS combinators, there's only one combination that will turn all of the circles white (unless you find another)!

```css
.combo-0:checked,
.combo-0:checked + .combo-1,
.combo-1:checked ~ .combo-0,
.combo-0:checked ~ .combo-2:checked,
.combo-2 + .combo-1:checked,
.combo-0:checked + .combo-1 {
  --bg: white;
}

.combo-0:checked ~ .combo-2 {
  --bg: rgb(35, 135, 35);
}

.combo-1:checked + .combo-2 {
  --bg: blue;
}

.combo-1,
.combo-1:checked + .combo-2:checked,
.combo-2:checked {
  --bg: red;
}
```

All together, that should give you something like this:

![Screenshot of the result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjzlgh10o5ygx8z95tgi.png)

## *...and that's it!*

The "game" is complete! But it's no fun if you don't play it! Can you crack the combo? Try it! I've got a video of me playing around with it below. **Note though:** I won't give away the solution!

{% embed https://youtu.be/Hn1nk9ZTe6g %}

You can [grab the full project](https://rolandixor.gumroad.com/l/kqazw) from my Gumroad Page. I'll be releasing an updated version in the near future, so keep an eye out!