af2111
af2111

Reputation: 331

Button Moves Weirdly when text is filled in

This is the misalignment

I wanted to program TicTacToe on a webpage, using plain JavaScript, HTML, and CSS. I've made some logic, so the board can update based on the entries in an array, but when I do that, the buttons aren't in a line anymore, and it looks really bad.

Expected result: text gets filled into the button, the button remains at its place.

Actual result: text gets filled in but the button moves down.

function game() {
    this.board = [
        " ", "x ", " ",
        " ", " ", " ",
        " ", " ", " x"
    ]
    this.printBoard = function(buttons) {
        for(i = 0; i < buttons.length; i++) {
            buttons[i].innerHTML = this.board[i];
        }
    }
}

window.onload = function() {
    let buttons = document.getElementsByClassName("field");
    let myGame = new game();
    myGame.printBoard(buttons);
}
.field {
   display: inline-block;
   border-style: solid;
   background-color: white;
   height: 100px;
   width: 100px;
   font-size: 10px;
}

#board {
   margin-left: 40%;
   margin-top: 20%;
   height: 50%;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My Website</title>
    </head>
    <body>
        <div id="board">
            <div id="row1">
            <button class="field"> </button>
            <button class="field"> </button>
            <button class="field"> </button>
            </div>
            <div id="row2">
            <button class="field"> </button>
            <button class="field"> </button>
            <button class="field"> </button>
            </div>
            <div id="row3">
            <button class="field"> </button>
            <button class="field"> </button>
            <button class="field"> </button>
            </div>
        </div>
    </body>
</html>

Upvotes: 4

Views: 354

Answers (3)

imhvost
imhvost

Reputation: 9959

The answer to question in your context is because buttons have default vertical-align: baseline. So when you add text to one of the buttons, the neighbors are vertically aligned to the baseline of that text.

A solution could be to change vertical-align to e.g. middle.

Or better use more modern layouts, e.g. grid:

function Game() {
  this.board = [
    "", "x", "",
    "", "", "",
    "", "", "o"
  ]
  this.printBoard = function(buttons) {
    for(i = 0; i < buttons.length; i++) {
      buttons[i].innerHTML = this.board[i];
    }
  }
}

window.onload = function() {
  let buttons = document.getElementsByClassName("field");
  let myGame = new Game();
  myGame.printBoard(buttons);
}
* {
  box-sizing: border-box;
}

#board {
   width: min(300px, 100%);
   margin: 0 auto;
   display: grid;
   grid-template-columns: 1fr 1fr 1fr;
   gap: 2px;
}

.field {
   background-color: white;
   aspect-ratio: 1;
   font-size: 48px;
   line-height: 1;
}
<div id="board">
  <button class="field"></button>
  <button class="field"></button>
  <button class="field"></button>
  <button class="field"></button>
  <button class="field"></button>
  <button class="field"></button>
  <button class="field"></button>
  <button class="field"></button>
  <button class="field"></button>
</div>

Upvotes: 2

Roko C. Buljan
Roko C. Buljan

Reputation: 206343

class game {
  fig = {x: "&#x2B55;", o: "&#x274C;"};
  board = Array(9).fill("");
  el = document.querySelector("#board");
  
  constructor() {
    this.printBoard();
  }
  
  printBoard(){
    this.el.innerHTML = this.board.reduce((h, f) => h + `<button>${this.fig[f]||""}</button>`, "");
  }
};

const myGame = new game();
myGame.board[0] = "x";
myGame.board[8] = "o";
myGame.printBoard();
#board {
  display: flex;
  flex-flow: row wrap;
  width: 50vh;
  height: 50vh;
}

#board > button {
  flex-grow: 1; 
  --margin: 0vh; /* Set a desired value */
  width: calc(33.333% - var(--margin) * 2); 
  margin: var(--margin);
  border: 0;
  box-shadow: 0 0 0 0.5px #000;
  background-color: white;
  font-size: 10vh;
  line-height: 0;
  cursor: pointer;
  transition: background 0.3s;
}
#board > button:hover {
  background: #0bf;
}
<div id="board"></div>

Upvotes: 1

Alekos Dordas
Alekos Dordas

Reputation: 810

You need to have some control at the rows. Try display: flex at the #row1, #row2, #row3

Upvotes: 1

Related Questions