0

I'm trying to make an 8by8 chessboard: https://codepen.io/sammyslamma/pen/gJeOwY

  
    .flex-container {
      display: flex;
      flex-flow: row;
      flex-wrap: wrap;
      height: 336px;
      width: 336px;
    }
    
    .chessboard {
      border: 1px solid black;
      width: 40px;
      height: 40px;
    }
    
    .chessboard div:nth-child(odd) {
      background-color: blue;
    }
    <div class="flex-container">
      <div id="tile">
        <script>
        for(x=0; x<64;x++) {
          var tile = document.createElement('div');
          tile.className = "chessboard";
          document.getElementById('tile').appendChild(tile);}
        </script>
      </div>
    </div>

I created 64 divs under the class name "chessboard". How do I make the squares go across so it forms an 8 by 8? I tried setting height and width and flex-basis to 12.5% as well.

Thank you for the help!

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
pythonnoob
  • 65
  • 1
  • 7
  • 2
    check this out: https://codepen.io/anon/pen/rgdaNQ – kukkuz May 24 '19 at 01:38
  • 1
    It would be great if you could describe what problems you're seeing in your question as well. – Ben Hull May 24 '19 at 01:53
  • 2
    Apply the flex properties to `#tile` not `.flex-container`. See the duplicate for details. – Michael Benjamin May 24 '19 at 01:54
  • 1
    I don't agree that this question is a duplicate - the title of the question is solved by the linked answers, but the underlying question of "How to make an 8x8 chessboard" is a separate problem, I think. – Ben Hull May 24 '19 at 02:04
  • 1
    @Beejamin the problem here is not how to create a chessboard but a miss use of flexbox properties explained in the duplicate ... each user will have a different need and a different situation but the issue remain the same : *flexbox is limited to parent/child related* which make this a perfect duplicate. You understand this, you can fix your code and you will have the chessboard – Temani Afif May 24 '19 at 11:16
  • Got it, thank you so much! Just to clear, the reason @Beejamin's code works and mine doesn't is because the flexbox properties are only applied to its direct child. So Beejamin renamed flex-container to #tile as well, which meant the 64 tile elements would take on the flexbox properties. Or I could have changed my code so that tile is set to flexbox from the beginning? – pythonnoob May 24 '19 at 13:15
  • @TemaniAfif, I know what you mean, but I still disagree. There are two parts to this question based on the title alone: The chessboard and the flexbox. The linked question answers one, but not both. Consider the question "What angle do I hold my steak knife to cut down a tree?", there is room for discussion of both the best angle, and also for "Don't use a steak knife, it's the wrong tool for the job" :) – Ben Hull May 24 '19 at 15:23
  • @Beejamin if you fix the flexbox issue the chessboard will work fine ... Imagine someone is building a wordpress site using woocommerce and 20 other plugins and he is having a 500 error making all the site not working. Is wordpress or any of the plugins relevant if the error is caused by a small php script? not it's not because fixing the php script will make the site to work again. Same thing here. there is a small flexbox issue, if you fix all the code is fine. – Temani Afif May 24 '19 at 15:27

3 Answers3

1

There are a couple of key mistakes in your example:

display: flex affects an element's direct children - in this case, the element #tile is acting as the child, and your .chessboard elements are not affected.

For your colouring, the selector .chessboard div:nth-child(odd) selects odd-child divs inside .chessboard, not the chessboard elements themselves.

That said, I don't think either of these is what you want if you actually want to make a literal chess board, for a couple of reasons:

  1. A chess board is not a single array of squares, it's an 8x8 grid. Flexbox will wrap children wherever they fit, but you don't ever want 7 or 9 squares in a row.
  2. Continuous 'odd' numbering is not correct, you want odd numbers in even numbered rows, and even numbers in odd-numbered rows.

People have suggested using CSS grid, and that could work, however HTML has a built in 2D grid structure, the good old <table> element! Example here: https://codepen.io/anon/pen/rgdNgq?editors=1111 (I've used Haml to simplify the HTML creation instead of javascript, but it's otherwise just 8 <tr> with 8 <td>'s in each).

The key CSS is:

.chess-board {
  border: 1px solid gray;
  border-collapse: collapse;
  border-spacing: 0;
}

.chess-board td {
  padding: 0;
  width: 4rem;
  height: 4rem;
}

.chess-board tr:nth-child(odd) td:nth-child(even),
.chess-board tr:nth-child(even) td:nth-child(odd){
  background: #222;
}

This is great for an actual chess-board because you can only ever have 8 x 8, guaranteed. CSS Grid can do it too, of course, but the main power of CSS grid is that the grid can change, which we don't want in this case.

The other good thing about a table structure is that you can address each row and column easily, because there's a structure grouping each row. With un-grouped cells, you need to always calculate a cell's number, which is easy enough, but just another step.

Ben Hull
  • 7,524
  • 3
  • 36
  • 56
0

Just put class="flex-item" in inner div

.flex-item {
 display: flex;
 flex-wrap: wrap;
}
Himanshu Pandey
  • 688
  • 2
  • 8
  • 15
0

Using your code, and grids instead of flexbox.

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
  grid-gap: 1px;
  max-width: 640px
}

.chessboard {
  border: 1px solid black;
  width: 80px;
  height: 80px;
  margin: 1px 
}
<div id="tile" class="container">
  <script>
   for(x=0; x<64;x++) {
     var tile = document.createElement('div');
     tile.className = "chessboard";
     document.getElementById('tile').appendChild(tile);}
   </script>
 </div>
NVRM
  • 11,480
  • 1
  • 88
  • 87