I’ve created a sudoku puzzle creator / solver and need a bit of help with some CSS to style it.
Typically they are styled like this:
.
Some naming I’m us
The following is a slight modification of an example in the table element section in HTML5 CR, illustrating the use of colgroup
for grouping columns and tbody
for grouping rows. This grouping lets you set different borders around the groups than otherwise around cells.
<style>
table { border-collapse: collapse; font-family: Calibri, sans-serif; }
colgroup, tbody { border: solid medium; }
td { border: solid thin; height: 1.4em; width: 1.4em; text-align: center; padding: 0; }
</style>
<table>
<caption>Sudoku of the day</caption>
<colgroup><col><col><col></colgroup>
<colgroup><col><col><col></colgroup>
<colgroup><col><col><col></colgroup>
<tbody>
<tr> <td>1 <td> <td>3 <td>6 <td> <td>4 <td>7 <td> <td>9
<tr> <td> <td>2 <td> <td> <td>9 <td> <td> <td>1 <td>
<tr> <td>7 <td> <td> <td> <td> <td> <td> <td> <td>6
<tbody>
<tr> <td>2 <td> <td>4 <td> <td>3 <td> <td>9 <td> <td>8
<tr> <td> <td> <td> <td> <td> <td> <td> <td> <td>
<tr> <td>5 <td> <td> <td>9 <td> <td>7 <td> <td> <td>1
<tbody>
<tr> <td>6 <td> <td> <td> <td>5 <td> <td> <td> <td>2
<tr> <td> <td> <td> <td> <td>7 <td> <td> <td> <td>
<tr> <td>9 <td> <td> <td>8 <td> <td>2 <td> <td> <td>5
</table>
By combining Jukka K. Korpela's answer with Mike's answer and adding a bit of jQuery magic, I have created two solutions.
$(document).ready(function () {
var data = [
1, 0, 3, 6, 0, 4, 7, 0, 9, // 0x0
0, 2, 0, 0, 9, 0, 0, 1, 0, // 0x1
7, 0, 0, 0, 0, 0, 0, 0, 6, // 0x2
2, 0, 4, 0, 3, 0, 9, 0, 8, // 1x0
0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x1
5, 0, 0, 9, 0, 7, 0, 0, 1, // 1x2
6, 0, 0, 0, 5, 0, 0, 0, 2, // 2x0
0, 0, 0, 0, 7, 0, 0, 0, 0, // 2x1
9, 0, 0, 8, 0, 2, 0, 0, 5 // 2x2
];
// Build page content.
$('body').append($('<div>').addClass('wrapper')
.append($('<div>').addClass('col')
.append($('<h1>').html('First Method'))
.append(generateSudokuGrid()))
.append($('<div>').addClass('col')
.append($('<h1>').html('Second Method'))
.append(generateSudokuGrid2())));
// Populate grids with data.
$('table[class^="sudoku"]').each(function (index, grid) {
populateGrid($(grid), data);
});
});
function populateGrid(grid, data) {
grid.find('td').each(function (index, td) {
$(td).text(data[index] || '');
});
}
/* First Method */
function generateSudokuGrid(data) {
return $('<table>').append(multiPush(3, function () {
return $('<colgroup>').append(multiPush(3, function () {
return $('<col>');
}));
})).append(multiPush(3, function () {
return $('<tbody>').append(multiPush(3, function () {
return $('<tr>').append(multiPush(9, function () {
return $('<td>');
}));
}));
})).addClass('sudoku');
}
/* Second Method */
function generateSudokuGrid2(data) {
return $('<table>').append(multiPush(9, function () {
return $('<tr>').append(multiPush(9, function () {
return $('<td>');
}));
})).addClass('sudoku2');
}
function multiPush(count, func, scope) {
var arr = [];
for (var i = 0; i < count; i++) {
arr.push(func.call(scope, i));
}
return arr;
}
/* First Method */
table.sudoku {
border-collapse: collapse;
font-family: Calibri, sans-serif;
}
.sudoku colgroup, tbody {
border: solid medium;
}
.sudoku td {
border: solid thin;
height: 1.4em;
width: 1.4em;
text-align: center;
padding: 0;
}
/* Second Method */
table.sudoku2 {
border-collapse: collapse;
font-family: Calibri, sans-serif;
}
.sudoku2 tr:nth-of-type(3n) {
border-bottom: solid medium;
}
.sudoku2 td:nth-of-type(3n) {
border-right: solid medium;
}
.sudoku2 td {
border: solid thin;
height: 1.4em;
width: 1.4em;
text-align: center;
padding: 0;
}
/* Presentation Formatting [Ignore] */
table[class^="sudoku"] {
margin: 0 auto;
}
.wrapper {
width: 100%;
}
.col {
display: inline-block;
width: 50%;
text-align: center;
margin: 0 auto;
padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Great solution Jukka. I used a combination of this and the following .erb code to dynamically generate the table and pop the contents in.
@current_solution is my array holding the values for each cell.
<table>
<colgroup><col><col><col>
<colgroup><col><col><col>
<colgroup><col><col><col>
<% 3.times do |all_box_rows_value|%>
<tbody>
<% 3.times do |box_row_value| %>
<% all_box_rows = all_box_rows_value * 27 %>
<% all_rows = ((box_row_value +1 ) * 9)-9 %>
<tr><%9.times do |row| %>
<% index = all_box_rows+all_rows+row %>
<% value = @current_solution[index] %><td>
<% colour_class = get_colour_class index %>
<input name="cell[]" type="text" maxlength="1" autocomplete="off" value=<%=value%> >
<% end %>
<% end %>
<% end %>
</table>
I would create the Sudoku board as following:
<section class="sudoku">
<div class="sudoku-row">
<div class="sudoku-square">
<div class="cell"><a class="cell-value"></a></div>
<div class="cell"><a class="cell-value"></a></div>
<div class="cell"><a class="cell-value"></a></div>
<div class="cell"><a class="cell-value"></a></div>
<div class="cell"><a class="cell-value"></a></div>
<div class="cell"><a class="cell-value"></a></div>
<div class="cell"><a class="cell-value"></a></div>
<div class="cell"><a class="cell-value"></a></div>
<div class="cell"><a class="cell-value "></a></div>
</div>
and the LESS will be like this
@cell-size: 50px;
.sudoku {
margin: 70px auto;
width: 478px;
background: #777;
border: 2px solid #000;
box-shadow: 15px 15px 20px #111;
.sudoku-row {
.sudoku-square {
float: left;
border: 1px solid #000;
.cell:nth-child(3n+1) {
clear: both;
}
.cell {
float: left;
position: relative;
height: @cell-size;
width: @cell-size;
background:#fff;
border: 1px solid #000;
box-sizing: content-box;
a {
margin: 0;
padding: 0;
}
a.cell-value {
display: block;
font-size: 30px;
color: #000;
width: @cell-size;
height: @cell-size;
text-align: center;
}
a.cell-value:hover {
text-decoration: none;
}
}
}
clear: both;
}
}
you can find a live demo here
If it were me, I would have used a table with 9 rows and 9 columns.
Then used :nth-of-type(3n) in the CSS selectors to set the border on every third row and column.