Styling a sudoku grid

偶尔善良 提交于 2019-12-02 02:50:17
Jukka K. Korpela

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>
Mr. Polywhirl

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>

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.

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

dwkns

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>
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!