Scribe: Style the board so there are clear gaps between the mini grids
authorCarl Worth <cworth@cworth.org>
Sat, 6 Jun 2020 18:53:44 +0000 (11:53 -0700)
committerCarl Worth <cworth@cworth.org>
Sat, 6 Jun 2020 18:53:44 +0000 (11:53 -0700)
Thanks to Richard for helping me figure out how to force the square
aspect ratio at the top-level. Below that, it's just two levels of CSS
"grid" for the boxes and the one of "flex" to get the centered
content.

scribe/scribe.css
scribe/scribe.jsx

index 4eaea8ffc0d555a7550aed606a42c1c0a2240f5f..ff113ab11d1cd056ebec9cfff75ae07f7be3d6b5 100644 (file)
@@ -1,32 +1,65 @@
-ol, ul {
-  padding-left: 30px;
+/* We want our board to be the largest square that can
+ * fit. Unfortunately, it requires a bit of CSS magic to make that
+ * happen. We can set a wdith easily enough, but what we can't easily
+ * do is to set the height to be exactly the same as the width.
+ *
+ * So here's the magic to get that to happen. On the board container
+ * we set the height to 0 and the bottom padding to 100% (which just
+ * happens to be defined as relative to the _width_). So, now we have
+ * a square element. Hurrah!
+ *
+ * The problem is that this element has a nominal height of 0, so if
+ * any child sas "height: 100%" that will result in a 0-height child
+ * and won't be what we want.
+ *
+ * So the last piece of the magic is to use absolute palcement of the
+ * board (which require position:relative on its parent) and set all
+ * of its edges (top, left, bottom, right) to the extents of the
+ * container.
+ *
+ * Ta-da! Now our board element is square and does not have any
+ * dimensions of 0 so child elements can compute their sizes
+ * naturally.
+ */
+.board-container {
+    position: relative;
+    width: 100%;
+    height: 0;
+    padding-bottom: 100%;
 }
 
-.board-row:after {
-  clear: both;
-  content: "";
-  display: table;
+.board {
+    position: absolute;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+
+    display: grid;
+    grid-template-columns: 1fr 1fr 1fr;
+    grid-template-rows: 1fr 1fr 1fr;
+    grid-gap: 1em;
 }
 
-.status {
-  margin-bottom: 10px;
+.mini-grid {
+    width: 100%;
+    height: 100%;
+
+    display: grid;
+    grid-template-columns: 1fr 1fr 1fr;
+    grid-template-rows: 1fr 1fr 1fr;
+
+    border-radius: 6px;
+    border: 3px solid #999;
 }
 
 .square {
-  background: #fff;
-  color: black;
-  border: 1px solid #999;
-  float: left;
-  font-size: 20px;
-  font-weight: bold;
-  line-height: 25px;
-  width: 25px;
-  height: 25px;
-  margin-right: -1px;
-  margin-top: -1px;
-  padding: 0;
-  text-align: center;
-  border-radius: 4px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 5vmin;
+    border-bottom: 1px solid #999;
+    border-right: 1px solid #999;
 }
 
 .square.open {
@@ -40,11 +73,3 @@ ol, ul {
 .square.open:hover {
     background-color: var(--accent-color-bright);
 }
-
-.square:focus {
-  outline: none;
-}
-
-.kbd-navigation .square:focus {
-  background: #ddd;
-}
index e7654b417eba2dfdc746a07d91f2a021de4bf2bb..d81932b7b847e6bb813993fd06a20a336a90d0ec 100644 (file)
@@ -165,147 +165,59 @@ function Square(props) {
   );
 }
 
-class Board extends React.Component {
-  render_square(i,j) {
-    const value = this.props.squares[i][j];
+function MiniGrid(props) {
+  function grid_square(j) {
+    const value = props.squares[j];
     return (
       <Square
         value={value}
-        active={this.props.active && ! value}
-        onClick={() => this.props.onClick(i,j)}
+        active={props.active}
+        onClick={() => props.onClick(j)}
       />
     );
   }
 
-  render() {
-    return (
-      <div>
-        <div className="board-row">
-          {this.render_square(0,0)}
-          {this.render_square(0,1)}
-          {this.render_square(0,2)}
-          {" "}
-          {this.render_square(1,0)}
-          {this.render_square(1,1)}
-          {this.render_square(1,2)}
-          {" "}
-          {this.render_square(2,0)}
-          {this.render_square(2,1)}
-          {this.render_square(2,2)}
-        </div>
-        <div className="board-row">
-          {this.render_square(0,3)}
-          {this.render_square(0,4)}
-          {this.render_square(0,5)}
-          {" "}
-          {this.render_square(1,3)}
-          {this.render_square(1,4)}
-          {this.render_square(1,5)}
-          {" "}
-          {this.render_square(2,3)}
-          {this.render_square(2,4)}
-          {this.render_square(2,5)}
-        </div>
-        <div className="board-row">
-          {this.render_square(0,6)}
-          {this.render_square(0,7)}
-          {this.render_square(0,8)}
-          {" "}
-          {this.render_square(1,6)}
-          {this.render_square(1,7)}
-          {this.render_square(1,8)}
-          {" "}
-          {this.render_square(2,6)}
-          {this.render_square(2,7)}
-          {this.render_square(2,8)}
-        </div>
-
-        <div className="board-row">
-        </div>
-
-        <div className="board-row">
-          {this.render_square(3,0)}
-          {this.render_square(3,1)}
-          {this.render_square(3,2)}
-          {" "}
-          {this.render_square(4,0)}
-          {this.render_square(4,1)}
-          {this.render_square(4,2)}
-          {" "}
-          {this.render_square(5,0)}
-          {this.render_square(5,1)}
-          {this.render_square(5,2)}
-        </div>
-        <div className="board-row">
-          {this.render_square(3,3)}
-          {this.render_square(3,4)}
-          {this.render_square(3,5)}
-          {" "}
-          {this.render_square(4,3)}
-          {this.render_square(4,4)}
-          {this.render_square(4,5)}
-          {" "}
-          {this.render_square(5,3)}
-          {this.render_square(5,4)}
-          {this.render_square(5,5)}
-        </div>
-        <div className="board-row">
-          {this.render_square(3,6)}
-          {this.render_square(3,7)}
-          {this.render_square(3,8)}
-          {" "}
-          {this.render_square(4,6)}
-          {this.render_square(4,7)}
-          {this.render_square(4,8)}
-          {" "}
-          {this.render_square(5,6)}
-          {this.render_square(5,7)}
-          {this.render_square(5,8)}
-        </div>
+  return (
+    <div className="mini-grid">
+      {grid_square(0)}
+      {grid_square(1)}
+      {grid_square(2)}
+      {grid_square(3)}
+      {grid_square(4)}
+      {grid_square(5)}
+      {grid_square(6)}
+      {grid_square(7)}
+      {grid_square(8)}
+    </div>
+  );
+}
 
-        <div className="board-row">
-        </div>
+class Board extends React.Component {
+  mini_grid(i) {
+    const squares = this.props.squares[i];
+    return (
+      <MiniGrid
+        squares={squares}
+        active={this.props.active}
+        onClick={(j) => this.props.onClick(i,j)}
+      />
+    );
+  }
 
-        <div className="board-row">
-          {this.render_square(6,0)}
-          {this.render_square(6,1)}
-          {this.render_square(6,2)}
-          {" "}
-          {this.render_square(7,0)}
-          {this.render_square(7,1)}
-          {this.render_square(7,2)}
-          {" "}
-          {this.render_square(8,0)}
-          {this.render_square(8,1)}
-          {this.render_square(8,2)}
-        </div>
-        <div className="board-row">
-          {this.render_square(6,3)}
-          {this.render_square(6,4)}
-          {this.render_square(6,5)}
-          {" "}
-          {this.render_square(7,3)}
-          {this.render_square(7,4)}
-          {this.render_square(7,5)}
-          {" "}
-          {this.render_square(8,3)}
-          {this.render_square(8,4)}
-          {this.render_square(8,5)}
-        </div>
-        <div className="board-row">
-          {this.render_square(6,6)}
-          {this.render_square(6,7)}
-          {this.render_square(6,8)}
-          {" "}
-          {this.render_square(7,6)}
-          {this.render_square(7,7)}
-          {this.render_square(7,8)}
-          {" "}
-          {this.render_square(8,6)}
-          {this.render_square(8,7)}
-          {this.render_square(8,8)}
+  render() {
+    return (
+      <div className="board-container">
+        <div className="board">
+          {this.mini_grid(0)}
+          {this.mini_grid(1)}
+          {this.mini_grid(2)}
+          {this.mini_grid(3)}
+          {this.mini_grid(4)}
+          {this.mini_grid(5)}
+          {this.mini_grid(6)}
+          {this.mini_grid(7)}
+          {this.mini_grid(8)}
         </div>
-
       </div>
     );
   }