简体   繁体   中英

Pure css Chessboard with div & no classes or ids, is it possible?

I have the following layout

<div id="chess">
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>

Is it possible to make a chess board using only css and without changing the above html? That means no classes or ids. I've been searching for ideas an such for 2 days now. I tried with nth-child() and some variations but no success.

I am awfully curious if this can be done. It was given as an assignment to someone.

So please, any ideas?

This is an interesting problem. I think a chess board is better expressed as a table than as a series of divs, as a screen reader would dictate the rows and columns where the figures are located. With a table:

table tr:nth-child(odd) td:nth-child(even) {
  background: #000;
}
table tr:nth-child(even) td:nth-child(odd) {
  background: #000;
}

http://jsfiddle.net/9kWJZ/

You don't have to hardcode each :nth-child() . Here's one way to shorten it. Each selector corresponds to a row on the chessboard:

#chess div:nth-child(-2n+8), 
#chess div:nth-child(8) ~ div:nth-child(-2n+15), 
#chess div:nth-child(16) ~ div:nth-child(-2n+24),
#chess div:nth-child(24) ~ div:nth-child(-2n+31),
#chess div:nth-child(32) ~ div:nth-child(-2n+40),
#chess div:nth-child(40) ~ div:nth-child(-2n+47),
#chess div:nth-child(48) ~ div:nth-child(-2n+56),
#chess div:nth-child(56) ~ div:nth-child(-2n+63) {
    background-color: #000;
}

jsFiddle preview

The following approach makes use of the fact that the coloring pattern repeats every 16 squares (counting from top left to bottom right). So, the first rule #chess div:nth-child(16n+1) colors the squares 1,17,33 and 49 (in other words, "the first column"). This is repeated with additional rules for all colored squares from 3 to 16 each representing a separate column.

With the given markup, it doesn't matter if you use nth-of-type or nth-child , however with additional markup it might, so nth-child is kind of the more obvious choice.

 for(i=0;i<64;i++){chess.appendChild(document.createElement("div"))}
 #chess div{ width:22px;height:22px;border:1px solid black; float:left; } #chess div:nth-of-type(16n+16), #chess div:nth-of-type(16n+14), #chess div:nth-of-type(16n+12), #chess div:nth-of-type(16n+10), #chess div:nth-of-type(16n+7), #chess div:nth-of-type(16n+5), #chess div:nth-of-type(16n+3), #chess div:nth-of-type(16n+1){ background-color:black; } #chess div:nth-of-type(8n+1){ clear:left; }
 <div id="chess"></div>

In pure CSS, the accepted answer looks right - however, if you want to shorten this up with SCSS, you can do some maths:

#chess {
  div {
    background: #fff;
    /* even children on odd rows, odd children on even rows */
    @each $offset in 2 4 6 8 9 11 13 15 {
      &:nth-child(16n + #{$offset}) {
        background: #000;
      }
    }
  }
}

of course it can be done...

body {
    background-image:
    -moz-linear-gradient(45deg, #000 25%, transparent 25%,transparent 75%, #000 75%, #000 100%),
    -moz-linear-gradient(45deg, #000 25%, transparent 25%,transparent 75%, #000 75%, #000 100%);
    background-image:
    -webkit-linear-gradient(45deg, #000 25%, transparent 25%,transparent 75%, #000 75%, #000 100%),
    -webkit-linear-gradient(45deg, #000 25%, transparent 25%,transparent 75%, #000 75%, #000 100%);
    -moz-background-size:100px 100px;
    background-size:100px 100px;
    -webkit-background-size:101px 101px;
    background-position:0 0, 50px 50px;
}

You can't use nth-child(odd) or nth-child(even) to colour the squares, because not all the "odd" or "even" squares are the same colour. Counting from the top-left as position "1", the first row's white squares would be 1, 3, 5, 7. Continuing into the second row, the white squares would be 10, 12, 14, 16. The third row would be back to odd numbers, 17, 19, 21, and 23.

You could therefore manually colour each of the squares as follows:

#chess {
    /* 8 squares at 30x30px per square */
    width: 240px;
    height:240px;
    background:#000;
}

#chess div {
    width:30px;
    height:30px;
    float:left;
}

#chess div:nth-child(1), /* first row */
#chess div:nth-child(3),
#chess div:nth-child(5),
#chess div:nth-child(7),
#chess div:nth-child(10), /* second row */
#chess div:nth-child(12),
#chess div:nth-child(14),
#chess div:nth-child(16)
/* ... up to 64 ... */
{
    background:#fff;
}

I realize I'm late to the game, and there are already several good answers to this question.

I'd just like to add a solution I find easy to manage when dealing with advanced :nth-child selectors. It's somewhat verbose and not as elegant as a few other suggestions, but I find it easy to read and deal with.

By chaining the :nth-child pseudo classes you can limit your selection to certain ranges only. In pseudo code it can be laid out as:

:nth-child( start of range ):nth-child( children to select ):nth-child( end of range )

This can be used to color the chess board row by row like this:

/* Start at 1st square, color odd squares until the 8th */
#chess :nth-child(n+1):nth-child(odd):nth-child(-n+8),

/* Even squares from 9th to 16th */
#chess :nth-child(n+9):nth-child(even):nth-child(-n+16),

/* Odd squares from 17th to 24th */
#chess :nth-child(n+17):nth-child(odd):nth-child(-n+24),

/* Even squares from 25th to 32nd */
#chess :nth-child(n+25):nth-child(even):nth-child(-n+32),

/* Odd squares from 33rd to 40th */
#chess :nth-child(n+33):nth-child(odd):nth-child(-n+40),

/* Even squares from 41st to 48th */
#chess :nth-child(n+41):nth-child(even):nth-child(-n+48),

/* Odd squares from 49th to 56th */
#chess :nth-child(n+49):nth-child(odd):nth-child(-n+56),

/* Even squares from 57th to 64th */
#chess :nth-child(n+57):nth-child(even):nth-child(-n+64) {
    background: #000;
}

 #chess { width: 320px; height: 320px; border: 1px solid #000; } #chess div { float: left; width: 40px; height: 40px; background: #fff; } #chess :nth-child(n+1):nth-child(odd):nth-child(-n+8), #chess :nth-child(n+9):nth-child(even):nth-child(-n+16), #chess :nth-child(n+17):nth-child(odd):nth-child(-n+24), #chess :nth-child(n+25):nth-child(even):nth-child(-n+32), #chess :nth-child(n+33):nth-child(odd):nth-child(-n+40), #chess :nth-child(n+41):nth-child(even):nth-child(-n+48), #chess :nth-child(n+49):nth-child(odd):nth-child(-n+56), #chess :nth-child(n+57):nth-child(even):nth-child(-n+64) { background: #000; }
 <div id="chess"> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> </div>

Try this :

table.CHESS {
    border-collapse: collapse;
}

table.CHESS td {
    width: 50px;
    height: 50px;
    border: solid gray 1px;
}

table tr:nth-child(odd) td:nth-child(odd) {
    background: #000;
}

table tr:nth-child(even) td:nth-child(even) {
    background: #000;
}

For those who need a CSS3 chess board with each square having an id so that you can use it with JavaScript, I can propose this solution:

https://github.com/vpcom/CSS3-Chess-Board

A demo is available here: http://vincentperrin.com/cr/css3/css3-chess-board/

It's done with Sass (SCSS notation) but you can use the processed CSS file also available. For those who like, this kind of things can also be done with Jade.

Enjoy!

If using 2 overlapped containers is acceptable, I think there is a more straightforward and "static" approach without using fancy css features:

 .chess { position: absolute; display: grid; grid-template-columns: repeat(4, 25%); grid-template-rows: repeat(4, 25%); } #up > div { height: 50px; width: 50px; margin: 0px 50px 50px 0px; background-color: #000; } #down > div { height: 50px; width: 50px; margin: 50px 0px 0px 50px; background-color: #000; }
 <html> <div id = "cont"> <div id = "up" class="chess"> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> </div> <div id = "down" class="chess"> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div> </div> </div> </html>

Inspired by BoltClocks fiddle

 for(i=0;i<64;i++){chess.appendChild(document.createElement("div"))}
 #chess { width: 8em; height: 8em; margin: 0.5em; border: 2px solid #808080; } #chess div { float: left; width: 1em; height: 1em; margin-left: 1em; background-color: #000; } #chess div:nth-child(8n+5){ margin-left: 0; } #chess div:nth-child(32) ~ div{ /* we dont need those :D*/ display: none; }
 <div id="chess"></div>

Probably my favorite one, using grid:

 for(i=0;i<64;i++){chess.appendChild(document.createElement("div"))}
 #chess { width: 8em; height: 8em; margin: 0.5em; border: 2px solid #808080; display: grid; grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(8, 1fr); place-items: stretch; } #chess div:nth-child(2n) { background-color: #000; } /* swapping these 2 rules greatly helps understanding */ #chess div:nth-child(9n+1) { /* background-color:red; */ grid-row-start: 8; }
 <div id="chess"></div>

Done. Sample: http://jsfiddle.net/LFVQU/1/

<style type="text/css">
    #chess{
     width:800px;   
     height:800px;
     border:1px;
     border:1px solid #999;
    }
    #chess div{
     width:100px;
     height:100px;  
     float:left;  
    }
#chess div{background: #fff}
#chess div:nth-child(1), #chess div:nth-child(3), #chess div:nth-child(5), #chess div:nth-child(7),
#chess div:nth-child(10), #chess div:nth-child(12), #chess div:nth-child(14), #chess div:nth-child(16),
#chess div:nth-child(17), #chess div:nth-child(19), #chess div:nth-child(21), #chess div:nth-child(23),
#chess div:nth-child(26), #chess div:nth-child(28), #chess div:nth-child(30), #chess div:nth-child(32),
#chess div:nth-child(33), #chess div:nth-child(35), #chess div:nth-child(37), #chess div:nth-child(39),
#chess div:nth-child(42), #chess div:nth-child(44), #chess div:nth-child(46), #chess div:nth-child(48),
#chess div:nth-child(49), #chess div:nth-child(51), #chess div:nth-child(53), #chess div:nth-child(55),
#chess div:nth-child(58), #chess div:nth-child(60), #chess div:nth-child(62), #chess div:nth-child(64)
{
    background-color:#000;
} 
</style>
#chess {width:256px; height:256px; border:1px solid;}  
#chess div {width:32px; height:32px; display:inline-block; }
#chess div:nth-child(16n+1), #chess div:nth-child(16n+3),
#chess div:nth-child(16n+5), #chess div:nth-child(16n+7),
#chess div:nth-child(16n+10),#chess div:nth-child(16n+12),
#chess div:nth-child(16n+14),#chess div:nth-child(16n+16) {
  background-color:black;
}

I think answers using float/clear are better, just what I came up with.

 const HelloWorld = { template: '#tmpl', name: "HelloWorld", methods: { board (s) { return Array.from({length:s**2}).map((_,i)=>(parseInt(i/s,10)+1)%2===i%s%2) }, }, }; new Vue({ el: '#app', components: { HelloWorld }, template: '<HelloWorld />' })
 .hello { display: grid; grid-template-columns: repeat(8, 20px); } .square { width: 20px; height: 20px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <script type="text/x-template" id="tmpl"> <div class="hello"> <div class="square" v-for="(square, idx) in board(8)" :key="idx" :style="{ background: square ? '#FFF' : '#000' }" ></div> </div> </script> <div id="app"></div>

Not pure CSS but less of code solution

Let me suggest you more clean css:

.divTableRow:nth-child(odd) .divTableCell:nth-child(even), .divTableRow:nth-child(even) .divTableCell:nth-child(odd) {
        background: #999;
    }

 .divTableRow:nth-child(odd) .divTableCell:nth-child(even), .divTableRow:nth-child(even) .divTableCell:nth-child(odd) { background: #999; } .divTable { display: table; width: 60%; float: left; } .divTableRow { display: table-row; } .divTableHeading { background-color: #EEE; display: table-header-group; } .divTableCell, .divTableHead { display: table-cell; padding: 3px 10px; height: 12.5%; width: 12.5%; text-align: center; } .divTableHeading { background-color: #EEE; display: table-header-group; font-weight: bold; } .divTableFoot { background-color: #EEE; display: table-footer-group; font-weight: bold; } .divTableBody { background: white; display: table-row-group; }
 <div class="divTable"> <div class="divTableBody"> <div class="divTableRow"> <div class="divTableCell"> <div id="black-rock1" class="draggable black">♜</div> </div> <div class="divTableCell"> <div id="black-knight1" class="draggable black">♞</div> </div> <div class="divTableCell"> <div id="black-bishop1" class="draggable black">♝</div> </div> <div class="divTableCell"> <div id="black-queen" class="draggable black">♛</div> </div> <div class="divTableCell"> <div id="black-king" class="draggable black">♚</div> </div> <div class="divTableCell"> <div id="black-bishop2" class="draggable black">♝</div> </div> <div class="divTableCell"> <div id="black-knight2" class="draggable black">♞</div> </div> <div class="divTableCell"> <div id="black-rack2" class="draggable black">♜</div> </div> </div> <div class="divTableRow"> <div class="divTableCell"> <div id="black-pawn1" class="draggable black">♟</div> </div> <div class="divTableCell"> <div id="black-pawn2" class="draggable black">♟</div> </div> <div class="divTableCell"> <div id="black-pawn3" class="draggable black">♟</div> </div> <div class="divTableCell"> <div id="black-pawn4" class="draggable black">♟</div> </div> <div class="divTableCell"> <div id="black-pawn5" class="draggable black">♟</div> </div> <div class="divTableCell"> <div id="black-pawn6" class="draggable black">♟</div> </div> <div class="divTableCell"> <div id="black-pawn7" class="draggable black">♟</div> </div> <div class="divTableCell"> <div id="black-pawn8" class="draggable black">♟</div> </div> </div> <div class="divTableRow"> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> </div> <div class="divTableRow"> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> </div> <div class="divTableRow"> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> </div> <div class="divTableRow"> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> <div class="divTableCell">&nbsp;</div> </div> <div class="divTableRow"> <div class="divTableCell"> <div id="white-pawn1" class="draggable white">♙</div> </div> <div class="divTableCell"> <div id="white-pawn2" class="draggable white">♙</div> </div> <div class="divTableCell"> <div id="white-pawn3" class="draggable white">♙</div> </div> <div class="divTableCell"> <div id="white-pawn4" class="draggable white">♙</div> </div> <div class="divTableCell"> <div id="white-pawn5" class="draggable white">♙</div> </div> <div class="divTableCell"> <div id="white-pawn6" class="draggable white">♙</div> </div> <div class="divTableCell"> <div id="white-pawn7" class="draggable white">♙</div> </div> <div class="divTableCell"> <div id="white-pawn8" class="draggable white">♙</div> </div> </div> <div class="divTableRow"> <div class="divTableCell"> <div id="white-rock1" class="draggable white">♖</div> </div> <div class="divTableCell"> <div id="white-knight1" class="draggable white">♘</div> </div> <div class="divTableCell"> <div id="white-bishop1" class="draggable white">♗</div> </div> <div class="divTableCell"> <div id="white-queen" class="draggable white">♕</div> </div> <div class="divTableCell"> <div id="white-king" class="draggable white">♔</div> </div> <div class="divTableCell"> <div id="white-bishop2" class="draggable white">♗</div> </div> <div class="divTableCell"> <div id="white-knight2" class="draggable white">♘</div> </div> <div class="divTableCell"> <div id="white-rack2" class="draggable white">♖</div> </div> </div> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM