CSS art

An ongoing collection of little challenges to stretch my CSS brain, with rendered examples, code, and the occasional creative workaround.An ongoing collection of little challenges to stretch my CSS brain.

Creative Coding

CSS Battle

My solutions to CSS Battle targets, with one extra constraint:
recreate each image using a single div and whatever CSS can muster.

Ongoing collection · Updated Nov 2026Code golf, Single div, CSS art

Intro

CSS Battle (opens in a new tab) is a game of code golf: you get a target image and rebuild it with HTML and CSS, and the shorter your code, the better your score. I played by a different rule. Instead of chasing the fewest characters, I gave myself one div per challenge. With only one element to work with, I had to lean on everything CSS can draw by itself.

::before and ::after turned one div into three shapes. box-shadow became a copy machine, stamping out repeats of a shape wherever I needed them. Gradients drew stripes and rings without extra elements, and border-radius and transform bent plain squares into petals, leaves and arches.

Battle #4

  • box-shadow
  • border-radius
  • transform
View target (opens in a new tab)
Show the CSSHide the CSS
<div></div>

body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
}
body div {
  display: flex;
  position: relative;
  height: 300px;
  width: 400px;
  background: #62306D;
}
body div::before, body div::after {
  left: 50%;
  top: 50%;
  margin-left: -150px;
  content: "";
  position: absolute;
  background: #F7EC7D;
  height: 100px;
  width: 100px;
}
body div::before {
  border-radius: 0 0 50% 50%;
  box-shadow: 200px 0px #F7EC7D;
}
body div::after {
  transform: translateY(-100px) translateX(100px);
  border-radius: 50% 50% 0 0;
}

Daily target, Nov 1 2024

  • border-radius
  • linear-gradient
View target (opens in a new tab)
Show the CSSHide the CSS
<div></div>

body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
body div {
  height: 300px;
  width: 400px;
  position: relative;
  background: #515697;
}
body div:after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 50%;
  margin-left: -162px;
  height: 275px;
  width: 324px;
  background: #E38F66;
  z-index: 1;
  border-radius: 50% 50% 0 0;
}
body div:before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 50%;
  margin-left: -162px;
  height: 100px;
  width: 324px;
  background-image: linear-gradient(to right, #E38F66 0 10%, #515697 10% 20%, #E38F66 20% 30%, #515697 30% 40%, #E38F66 40% 60%, #515697 60% 70%, #E38F66 70% 80%, #515697 80% 90%, #E38F66 90% 100%);
  z-index: 5;
}

Battle #188

  • box-shadow
  • border-radius
  • transform
View target (opens in a new tab)
Show the CSSHide the CSS
<div></div>

body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  position: relative;
}
body div {
  z-index: -4;
  display: flex;
  height: 300px;
  width: 400px;
  background: #FFFD9B;
  display: flex;
  align-items: center;
  justify-content: center;
}
body div::before {
  z-index: -1;
  position: absolute;
  content: "";
  width: 20px;
  height: 240px;
  border-radius: 20px;
  box-shadow: -80px 0px #969610, 80px 0px #969610;
}
body div::after {
  z-index: -1;
  position: absolute;
  content: "";
  width: 20px;
  height: 340px;
  border-radius: 20px;
  background: #646521;
  transform: rotate(90deg);
  box-shadow: -80px 0px #969610, 80px 0px #969610;
}

body::before {
  z-index: -1;
  content: "";
  z-index: 100;
  position: absolute;
  width: 20px;
  height: 240px;
  border-radius: 20px;
  background: #646521;
}

Battle #15

  • box-shadow
  • border-radius
  • transform
View target (opens in a new tab)
Show the CSSHide the CSS
<div></div>

body {
  height: 100vh;
  background: white;
  display: flex;
  align-items: center;
  justify-content: center;
}
body div {
  height: 300px;
  width: 400px;
  background: #09042A;
}
body div::before {
  content: "";
  position: absolute;
  height: 150px;
  width: 150px;
  transform: translateX(75px) translateY(75px);
  border-radius: 50%;
  background: #7B3F61;
  box-shadow: 100px 0 #E78481;
}
body div::after {
  content: "";
  position: absolute;
  height: 76px;
  width: 82px;
  background: #09042A;
  border-radius: 0 82px;
  transform: translateX(159px) translateY(112px) rotate(47deg);
}

Daily target, Nov 11 2024

  • box-shadow
  • border-radius
  • transform
View target (opens in a new tab)
Show the CSSHide the CSS
<div class='frame'></div>

body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
}
body div {
  display: flex;
  justify-content: center;
  position: relative;
  height: 300px;
  width: 400px;
  background: #328FC1;
  overflow: hidden;
}
body div::before {
  content: "";
  position: absolute;
  transform: translateY(-30px);
  width: 110px;
  height: 40px;
  border-radius: 50px;
  background: #ffffff;
  box-shadow: 0px 40px #ffffff, 0px 80px #ffffff, 0px 120px #ffffff, 0px 160px #ffffff, 0px 200px #ffffff, 0px 240px #ffffff, 0px 280px #ffffff, 0px 320px #ffffff, 0px 360px #ffffff;
}

Battle #9

  • border-radius
  • transform
View target (opens in a new tab)
Show the CSSHide the CSS
<div></div>

body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
}
body::before {
  content: "";
  position: absolute;
  height: 50px;
  width: 50px;
  border-radius: 50%;
  background: #393E46;
  z-index: 4;
}
body::after {
  content: "";
  position: absolute;
  height: 150px;
  width: 400px;
  background: #4CAAB3;
}
body div {
  overflow: hidden;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 300px;
  width: 400px;
  background: #222730;
}
body div::before {
  content: "";
  position: absolute;
  background: #4CAAB3;
  height: 150px;
  width: 150px;
  z-index: 3;
  transform: rotate(45deg);
}
body div::after {
  content: "";
  position: absolute;
  background: #222730;
  height: 250px;
  width: 250px;
  z-index: 2;
  transform: rotate(45deg);
}

Battle #7

  • box-shadow
  • border-radius
  • transform
View target (opens in a new tab)
Show the CSSHide the CSS
<div class='frame'></div>

body{
  height:100vh;
  display:flex;
  align-items:center;
  justify-content:center;
  background:white;
  .frame{
    position:relative;
    display:flex;
    align-items:center;
    justify-content:center;
    height:300px;
    width:400px;
    background:#0B2429;
    &::before {
      content:"";
      position:absolute;
      height:145px;
      width:145px;
      border-radius:65% 0;
      background:#998235;
      box-shadow: -60px 0px #1A4341;
    }
    &::after {
      content:"";
      position:absolute;
      height:145px;
      width:145px;
      border-radius:65% 0;
      background:#F3AC3C;
      transform:translate(60px);
    }
  }
}

Battle #6

  • border-radius
  • conic-gradient
View target (opens in a new tab)
Show the CSSHide the CSS
<div></div>

body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
}
body div {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 300px;
  width: 400px;
  background: #E3516E;
}
body div::before {
  content: "";
  position: absolute;
  height: 200px;
  width: 200px;
  border-radius: 50%;
  background-image: conic-gradient(#FADE8B 25%, transparent 25% 50%, #F7F3D7 50% 75%, #51B5A9 75% 100%);
}

Battle #5

  • box-shadow
  • border-radius
  • transform
View target (opens in a new tab)
Show the CSSHide the CSS
<div></div>

body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
}
body div {
  z-index: 1;
  position: relative;
  height: 300px;
  width: 400px;
  background: #0B2429;
}
body div::before, body div::after {
  top: 50%;
  right: 50%;
  content: "";
  position: absolute;
  height: 120px;
  width: 120px;
  background: #F3AC3C;
}
body div::before {
  border-radius: 50% 0% 50% 50%;
  box-shadow: 60px -60px #998235;
}
body div::after {
  border-radius: 50%;
  z-index: -1;
  transform: translate(120px, -120px);
}

Battle #3

Show the CSSHide the CSS
<div></div>

body {
  margin: 0;
  height: 100vh;
  width: 100vw;
  background: white;
  display: flex;
  align-items: center;
  justify-content: center;
}
body div {
  height: 300px;
  width: 400px;
  background: #6592CF;
  display: flex;
  align-items: center;
  justify-content: center;
}
body div::after {
  content: "";
  height: 150px;
  width: 300px;
  background-image: radial-gradient(circle, #EEB850 0px 25px, #243D83 25px 75px, transparent 75px 125px, #243D83 125px 100px);
}

Battle #2

Show the CSSHide the CSS
<div></div>

body {
  margin: 0;
  height: 100vh;
  width: 100vw;
  background: white;
  display: flex;
  align-items: center;
  justify-content: center;
}
body div {
  height: 300px;
  width: 400px;
  background: #62374e;
}
body div::after {
  content: "";
  position: absolute;
  transform: translateY(50px) translateX(50px);
  width: 50px;
  height: 50px;
  background-color: #fdc57b;
  box-shadow: 0 150px #fdc57b, 250px 0 #fdc57b, 250px 150px #fdc57b;
}
Back to topNext · Drawing with Code