0

I'm trying to create a simple tic-tac-toe application using HTML, CSS, Javascript.

I've set the X and O images in HTML like so:

<body>
  <div class="wrapper">
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
    <div>
      <img src="X.png" alt="X" id="X">
      <img src="O.png" alt="O" id="O">
    </div>
  </div>
</body>
</html>

I'm using CSS grid to arrange each div in my HTML as a cell (inside the X and O will show up).

  <style>
    .wrapper{
      display:grid;
      grid-template-columns:100px 100px 100px;
      grid-template-rows:100px 100px 100px;
      grid-gap:10px;
    }

    .wrapper > div{
      background:#eee;
      padding:1em;
    }

    #X{
      height: 50%;
      width: 50%;
    }

    #O{
      height: 50%;
      width: 50%;
    }

  </style>

The resulting web page looked like this:

tic-tac-toe

Now as you can see, the X and O aren't centered inside each of their respective boxes. My intention is to make X and O overlap on top of each other (so that I can use javascript to enable and disable their visibility later on). I initially thought I could solve this problem via margin or padding. So I set the left-padding for the X images like this:

#X{
      height: 50%;
      width: 50%;
      padding-left: 16px
    }

This successfully centered the X image in each box on the horizontal axis.

enter image description here

However, when I tried to add padding-top to X (to centre it vertically), X went back to its initial position (as seen in the first image).

So how would I centre the X (and eventually, the O) in their respective boxes?

Vktr
  • 89
  • 8

3 Answers3

1

You can achieve this by taking advantage of the relative and absolute positioning. Using these along with transform will nicely overlap and center each of of your images in the grid.

Just to note; you're using id="X" on multiple elements. ID's need to be unique and so you can't use the same one more than once - I've replaced these with classes in the snippet below.

.wrapper{
      display:grid;
      grid-template-columns:100px 100px 100px;
      grid-template-rows:100px 100px 100px;
      grid-gap:10px;
    }

    .wrapper > div{
      background:#eee;
      padding:1em;
      position:relative;
    }

    .X, .O {
      position:absolute;
      top:50%;
      left:50%;
      transform:translate3d(-50%, -50%, 0)
    }
<div class="wrapper">
  <div>
    <img src="https://placeimg.com/50/50/animals" alt="X" class="X">
    <img src="https://placeimg.com/50/50/arch" alt="O" class="O">
  </div>
  <div>
    <img src="https://placeimg.com/50/50/animals" alt="X" class="X">
    <img src="https://placeimg.com/50/50/arch" alt="O" class="O">
  </div>
</div>
MattHamer5
  • 1,431
  • 11
  • 21
  • Your solution worked. However, I managed to create the desired affect by removing the line `transform:translate3d(-50%, -50%, 0)` and setting both `top` and `left` to 25%. What's the point of using `transform:translate3d(-50%, -50%, 0)` if I can just use `top` and `left`? Aren't they both technically translating the element position? – Vktr Oct 22 '19 at 05:12
  • Furthermore, since I plan on controlling the visibility of each X and O individually (based on user input), do you think it would be a good idea to give each X and O a unique id instead of class (for example: X_topleft, O_topleft, X_topright, etc.)? Or is there a simpler way around this? – Vktr Oct 22 '19 at 05:36
  • And using `top:25%;` and `left:25%` won't center everything perfectly, whereas setting them as `50%` and then using the `translate` function will do. See these two examples of **[Setting top to 25%](https://jsfiddle.net/hevu6ozg/)** vs **[Transform3d](https://jsfiddle.net/a7ghy0kc/)** – MattHamer5 Oct 22 '19 at 07:16
0

If you want 2 elements to overlap with each other you should give them position: absolute; Also you should make a div around it which has position: relative;

.column{
  position: relative;
  width: 200px;
  height: 200px;
}

.column img{
  position: absolute;
  width: 200px;
  height: 200px;
}
<div class="column">
   <img src="https://www.pinclipart.com/picdir/middle/99-992857_inner-page-closing-comments-tic-tac-toe-x.png" alt="X" id="X">
   <img src="http://pluspng.com/img-png/letter-o-png-open-2000.png" alt="O" id="O">
</div>

But in your code you should make it so both elements are on display: none;, this way it wont use any space until you make the element display: block; Since only 1 element will be display: block; at the time you want have to worry about overlapping images.

Jeremy
  • 1,384
  • 3
  • 10
  • 24
0

Try this:

.wrapper > div{
   display: flex;
   justify-content: center;
   align-items: center;
   flex-direction: column;  /* <-- if you want the images to be under each other*/
}