1

I'm trying to code 2048 using HTML/ CSS/ JS

I got the layout of the grid using this Html:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>2048</title>
</head>
<body>
<div class = "wrapper">
    <div class="gridd">
      <div><h1></h1></div>
      <div><h1></h1></div>
      <div><h1></h1></div>
      <div><h1></h1></div>
      <div><h1></h1></div>
      <div><h1></h1></div>
      <div><h1></h1></div>
      <div><h1></h1></div>
      <div><h1></h1></div>
    </div>  
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>

And for it I'm using this CSS:

* {
    margin: 0;
    padding: 0;
}

body {
    background-color: #C2C2C2;
}

h1 {
    font-family: Asap,sans-serif;
    font-size: 24pt;
    margin-top:35%;
    text-align: center;
    color: white;
}


.gridd {
    width: 340px;
    height: 340px; 
    background-color: #B4B4B4;
    border-radius: 15px; 
    padding: 15px; 
    position: absolute; 
    margin: auto;
}

.gridd > div {
    width: 100px; 
    height: 100px; 
    background-color:#787878; 
    border-radius: 15px; 
    margin:5px;
    display: inline-block;
}

.wrapper{
    position: absolute;
    margin: 80px 0 0 200px;

}

I'm simply using this JS code to generate the initial twos on the grid:

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

var y = document.getElementsByTagName("H1");

y[getRandomInt(8)].innerHTML = 2;
y[getRandomInt(8)].innerHTML = 2;

Now, on load I'm getting this unpleasant scene:

2048 wrecked loading

Can someone help me understand what's going on please? And how to fix it. Thanks a lot.

Lith
  • 1,251
  • 6
  • 19
Majd
  • 328
  • 4
  • 12
  • 1
    you dont actually sue a grid while you shoud use one. Read into CSS-grid, this should easily solve the issue for you. Dont use absolute or elative positioning, do a clean 3x3 css grid. – tacoshy Dec 19 '20 at 13:47

3 Answers3

1

This can be simply fixed with changed to css file. use display: grid.

Also, do not use margin-top: 35%;. If you will make h1, or div, smaller or bigger, you will have to change the percentage too. Instead, you can center it via align-items: center.

This is the entire css file to fix the issue:

* {
  margin: 0;
  padding: 0;
}

body {
  background-color: #c2c2c2;
}

h1 {
  font-family: Asap, sans-serif;
  text-align: center;
  color: white;
}

.wrapper {
  margin: 80px 0 0 200px;
  border-radius: 15px;
  background-color: #b4b4b4;
  width: fit-content;
  padding: 10px;
}

.gridd {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  gap: 5px;
}

.gridd > div {
  background-color: #787878;
  border-radius: 15px;
  display: grid;
  align-items: center;
}

It will center your h1 no matter what text size it is and no matter how big your div container.

EDIT

In fact, this entire thing can be made without a wrapper and extra div

HTML:

<div class="grid">
  <h1></h1>
  <h1></h1>
  <h1></h1>
  <h1></h1>
  <h1></h1>
  <h1></h1>
  <h1></h1>
  <h1></h1>
  <h1></h1>
</div>

CSS:

* {
  margin: 0;
  padding: 0;
}

body {
  background-color: #c2c2c2;
}

.grid {
  margin: 80px 0 0 200px;
  border-radius: 15px;
  background-color: #b4b4b4;
  width: fit-content;
  padding: 10px;
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  gap: 5px;
}

.grid > h1 {
  background-color: #787878;
  border-radius: 15px;
  display: grid;
  align-items: center;
  font-family: Asap, sans-serif;
  text-align: center;
  color: white;
}
Lith
  • 1,251
  • 6
  • 19
  • Thanks alot, learning alot from the answers, would you please care to explain to me what is it in my code that was causing the problem? – Majd Dec 19 '20 at 14:54
  • 1
    Mainly, its the overuse of `position: absolute;`. They are tedious to manage, especially if you have multiple of them to control your content areas. If one of the content areas become larger or smaller because your content changed, the layout can change too and mess up. Since JS loads after css and html, the content gets added up and the absolute div container becomes bigger and that messed up the layout. `position: absolute;` should only be used in case when you require a container to go outside his parents container. For example: a drop-down menu list. Hope it helps, @Majd – Lith Dec 19 '20 at 15:01
  • Also, as user `sergey kuznetsov` posted with the answer of using `display: flex` is also correct. But flex is really old. CSS-grid is newer and getting pushed out in real life more and more. But like with every great thing there r cons. Css-grid does not work on all browsers. There are few browsers that are not up to date with all css features. But majority of most popular browsers support is with no issues. – Lith Dec 19 '20 at 15:05
1

Just add flex rules for selector .gridd:

.gridd{
    ...
    display: flex;
    flex-flow: wrap;
}

And replace display: inline-block with flex: auto in the selector .gridd >div:

.gridd >div{
    ...  
    flex: auto;
}

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

var y = document.getElementsByTagName("H1");

y[getRandomInt(8)].innerHTML = 2;
y[getRandomInt(8)].innerHTML = 2;
*{margin: 0;
padding: 0;
}

body{
    background-color: #C2C2C2;
}

h1{
    font-family: Asap,sans-serif;
    font-size: 24pt;
    margin-top:35%;
    text-align: center;
    color: white;
}


.gridd{
    width: 340px;
    height: 340px; 
    background-color: #B4B4B4;
    border-radius: 15px; 
    padding: 15px; 
    position: absolute; 
    margin: auto;
    
    display: flex;
    flex-flow: wrap;
}

.gridd >div{
    width: 100px; 
    height: 100px; 
    background-color:#787878; 
    border-radius: 15px; 
    margin:5px;
    
    flex: auto;
}

.wrapper{
    position: absolute;
    margin: 80px 0 0 200px;

}
<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>2048</title>
</head>
<body>

<div class = "wrapper">
    <div class = "gridd" >
        <div> <H1></H1> </div>

        <div> <H1></H1> </div>

        <div> <H1></H1> </div>

        <div> <H1></H1> </div>

        <div> <H1></H1> </div>

        <div> <H1></H1> </div>

        <div> <H1></H1> </div>

        <div> <H1></H1> </div>

        <div> <H1></H1> </div>
        
    </div>  
</div>
</body>
<!--script type="text/javascript" src="script.js"></script(-->
</html>
s.kuznetsov
  • 14,870
  • 3
  • 10
  • 25
  • Thanks alot, learning alot from the answers, would you please care to explain to me what is it in my code that was causing the problem? – Majd Dec 19 '20 at 14:54
  • @Majd, In general, your problem can be solved in different ways. My way with `flex` is like one of the options. And the reason for the violation of the order of the `gridd >div` is the default rule `display: block` you have `h1`. – s.kuznetsov Dec 19 '20 at 15:06
0

If you want to style a grid layout, you should also use a grid. The tool for it is called CSS-Grid. It delcared by using display: grid;. To have th grid 3 column wide, you use grid-template-columns: repeat(3, min-content);. Thatw ay you have 3 columns with the width of the children. To have a gap between the different chidlren cards, you use grid-gap: 15px;

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

var y = document.getElementsByTagName("H1");

y[getRandomInt(8)].innerHTML = 2;
y[getRandomInt(8)].innerHTML = 2;
* {
  margin: 0;
  padding: 0;
}

body {
  background-color: #C2C2C2;
}

h1 {
  font-family: Asap, sans-serif;
  font-size: 24pt;
  margin-top: 35%;
  text-align: center;
  color: white;
}

.gridd {
  width: min-content;
  padding: 15px;
  display: grid;
  grid-template-columns: repeat(3, min-content);
  grid-gap: 15px;
  margin: auto;
  background-color: #B4B4B4;
  border-radius: 15px; 
}

.gridd>div {
  width: 100px;
  height: 100px;
  background-color: #787878;
  border-radius: 15px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <link rel="stylesheet" type="text/css" href="style.css">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>2048</title>
</head>

<body>

  <div class="wrapper">
    <div class="gridd">
      <div>
        <H1></H1>
      </div>

      <div>
        <H1></H1>
      </div>

      <div>
        <H1></H1>
      </div>

      <div>
        <H1></H1>
      </div>

      <div>
        <H1></H1>
      </div>

      <div>
        <H1></H1>
      </div>

      <div>
        <H1></H1>
      </div>

      <div>
        <H1></H1>
      </div>

      <div>
        <H1></H1>
      </div>

    </div>
  </div>
</body>
<!--script type="text/javascript" src="script.js"></script(-->

</html>
tacoshy
  • 10,642
  • 5
  • 17
  • 34
  • should NOT be using `margin-top: 35%;` to center the text. In fact, even in your example, the text is not centered. the bottom has `27px` left while the top is `35px`. Also, this would not automatically change it if `h1` text size would be changed. instead, should use `align-items: center` or `transform`, but since css-grid already is in use, `align-items: center` does the job – Lith Dec 19 '20 at 14:05
  • after you edited your code. I just copied your code, merged it, and implemented a grid. All other stylings are purely your code. You asked how to fix the misaligning you caused yb absolute and relative positioning, which was fixed. it never was about somethign else. – tacoshy Dec 19 '20 at 14:18
  • ? I'm... not the person who asked this question. I'm just a person who provided an answer and info, to any other reader, why `margin-top: 35%;` in this case should not be used. Sorry for misunderstanding or getting you upset in any way, but I'm not Majd (the question author). – Lith Dec 19 '20 at 14:23
  • Thanks alot, learning alot from the answers, would you please care to explain to me what is it in my code that was causing the problem? – Majd Dec 19 '20 at 14:54