Search code examples
cssbackgroundlinear-gradients

Responsive checkerboard pattern background


I want to have a responsive checkerboard background that should look like the background in a color selector:

Wanted result

I want the pattern to always show N number of squares-per-width (dynamic).

What I tried:

.chess {
  background-image: 
    linear-gradient(90deg, #999 30px, white 30px), 
    linear-gradient(90deg, white 30px, #999 30px), 
    linear-gradient(90deg, #999 30px, white 30px), 
    linear-gradient(90deg, white 30px, #999 30px), 
    linear-gradient(90deg, #999 30px, white 30px), 
    linear-gradient(90deg, white 30px, #999 30px), 
    linear-gradient(90deg, #999 30px, white 30px);
  background-position: 0 0, 0 30px, 0 60px, 0 90px, 0 120px;
  background-repeat: repeat-x;
  background-size: 60px 30px;
  height: 150px;
  margin: 15px auto;
  width: 30%;
}


.fas {
  text-align: center;
  font-size: 10em
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<div>
  <div class="btn btn-outline-secondary chess">
  <i class="fas fa-car"></i>
  </div>
<div>

The squares are not 1:1 aspect ratio if the container isn't also, and that is not responsive:

div {
  width: 300px;
  height: 100px;
  resize: auto;
  overflow: hidden;

  aspect-ratio: 1/2;
  border: 1px solid red;
  background: repeating-conic-gradient(transparent 0 90deg, grey 0 180deg) 
              0 0 / 25% 25% round;
}
<div></div>

Problems:

  • My result is not responsive. (I have fixed pixel sizes)
  • I would need a lot of code if I have a larger background or smaller elements.
  • I was unable to center the pattern or use background-repeat: round

If it is possible, I do not want any cut-offs in the checkerboard background.

Not like this (cut off on the right and bottom):

enter image description here


Solution

  • Here is an idea that rely on conic-gradient:

    .chess {
      background:
        repeating-conic-gradient(
            #fff 0 90deg,
            grey 0 180deg) 
        0 0/25% 25%;
      margin: 15px;
      padding:10px;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css" rel="stylesheet"/>
    
    <div class="chess fas fa-7x fa-car"></div>
    <div class="chess fas fa-5x fa-car"></div>
    <div class="chess fas fa-10x fa-user"></div>
    <div class="chess fas fa-3x fa-phone"></div>

    CSS responsive checkerboard

    You can also consider round of background-repeat if you want to have the same size and no cut off:

    .chess {
      background:
        repeating-conic-gradient(
            #fff 0 90deg,
            grey 0 180deg) 
        0 0/40px 40px round;
      margin: 15px;
      padding:10px;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css" rel="stylesheet"/>
    
    <div class="chess fas fa-7x fa-car"></div>
    <div class="chess fas fa-5x fa-car"></div>
    <div class="chess fas fa-10x fa-user"></div>
    <div class="chess fas fa-3x fa-phone"></div>

    CSS chessboard reasponsive


    For better support, you can replace the gradient with an SVG to have the same result:

    .chess {
      background:
        url('data:image/svg+xml;utf8,<svg preserveAspectRatio="none"  viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"><rect x="0" y="0" width="5" height="5" fill="grey" /><rect x="5" y="5" width="5" height="5" fill="grey" /><rect x="5" y="0" width="5" height="5" fill="white" /><rect x="0" y="5" width="5" height="5" fill="white" /></svg>') 
        0 0/25% 25%;
      margin: 15px;
      padding:10px;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css" rel="stylesheet"/>
    
    <div class="chess fas fa-7x fa-car"></div>
    <div class="chess fas fa-5x fa-car"></div>
    <div class="chess fas fa-10x fa-user"></div>
    <div class="chess fas fa-3x fa-phone"></div>

    And with a fixed size:

    .chess {
      background:
        url('data:image/svg+xml;utf8,<svg preserveAspectRatio="none"  viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"><rect x="0" y="0" width="5" height="5" fill="grey" /><rect x="5" y="5" width="5" height="5" fill="grey" /><rect x="5" y="0" width="5" height="5" fill="white" /><rect x="0" y="5" width="5" height="5" fill="white" /></svg>') 
        0 0/40px 40px round;
      margin: 15px;
      padding:10px;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css" rel="stylesheet"/>
    
    <div class="chess fas fa-7x fa-car"></div>
    <div class="chess fas fa-5x fa-car"></div>
    <div class="chess fas fa-10x fa-user"></div>
    <div class="chess fas fa-3x fa-phone"></div>