Home > Blockchain >  Divs generated in javascript appearing with no height
Divs generated in javascript appearing with no height

Time:10-08

Context: I'm working through the Odin Project and trying to make an etch-a-sketch board. The project asks for you to make a board that you can draw on when your mouse hovers over, but it has to be made out of a grid of small divs that you add to the DOM from your javascript.

Problem: When the divs get generated to make the grid, they appear with a width of x (user generated) but a height of 0. So you can't hover over them. I expect to see a large blue square but instead it is blank unless I go out of my way to add in a height value in the css. The divs are created in the for-loop of line 14 of the javascript file here: https://jsfiddle.net/krmanski/ry12xumq/9/

function generateCanvas(gridSize){
    //create the gridlines
    //divide canvas into A x A where A = the number provided by user
    let canvas = document.querySelector(".main-grid-container");
    canvas.style.gridTemplateColumns = `repeat(${gridSize}, 1fr)`;
    canvas.style.gridTemplateRows = `repeat(${gridSize}, 1fr)`;
    alert("canvas should be generated");


    let divsTotal = (gridSize * gridSize);
    for(let i = 0; i < divsTotal; i  ){
        let div = document.createElement("div");
        div.classList.add("grid-item");
        div.style.backgroundColor="blue";
        
        //this will allow our divs to change color when hovered over
        div.addEventListener("mouseover", function(){
            div.style.backgroundColor="black";
        })

        canvas.appendChild(div);
    }
}

I have looked at other people's solutions on github and youtube and nearly all of them use the exact same code I do in my for-loop, and they apply no CSS at any point to tell their divs to have height. I am thinking of starting from a blank slate because I just can't figure out the problem but at this point I'm just idly curious what is the problem and why my divs are appearing with 0 height.

CodePudding user response:

Setting align-items: center on .main-grid-container is what prevents your divs from being stretched vertically. I recommend simply removing that declaration, the initial value normal will achieve the desired effect.

CodePudding user response:

Is this the sort of effect that you were after? The following uses css variables to determine width/height of the individual grid squares based upon simple arithmetic of the canvas with divided by the number of grid-items. The CSS variables are updated within the generateCanvas function

//wait until the HTML and CSS are loaded before you run the javascript
document.addEventListener("DOMContentLoaded", function() {
  generateCanvas(16);
});



function generateCanvas(size) {
  // Find the doc root to access variables
  let root = document.documentElement;
  
  let canvas = document.querySelector(".main-grid-container");
      canvas.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
      canvas.style.gridTemplateRows = `repeat(${size}, 1fr)`;
      
      // important to clear the grid otherwise it will grow 
      // on each invocation of this function!
      canvas.innerHTML = '';

  // calculate the size of the containg canvas
  let box = canvas.getBoundingClientRect();
  let w = box.width / size;
  let h = box.height / size;
  
  // update the variables with new sizes
  root.style.setProperty('--w', `${w}px`);
  root.style.setProperty('--h', `${h}px`);

  
  for (let i = 0; i < Math.pow(size, 2); i  ) {
    let div = document.createElement("div");
        div.classList.add("grid-item");
        div.title = i;

    div.addEventListener("mouseover", ()=>div.style.backgroundColor = "black" )
    canvas.appendChild(div);
  }
}

function selectSize() {
  //has the user type a number and returns that number, but only if it is between 0 and 100
  let userInput = prompt("What should be the size of the board?")
  let message = document.querySelector("#message")


  if (userInput == "") {
    message.innerText = "Please provide a number only";
  } else if (userInput < 0 || userInput > 100) {
    message.innerText = "Please only provide a number between 1 and 100"
  } else {
    message.innerText = `You selected a ${userInput} x ${userInput} sized grid for your canvas`
    generateCanvas(userInput);
  }

}






const buttonPress = e => {
  //takes in the id of the button that was pressed.
  let buttonID = e.target.id;
  console.log(buttonID);
  //alert(`button ${buttonID} was pressed`);
  switch (buttonID) {
    case "modify-grid":

      selectSize();
      break;

    case "black":
      alert('you pressed black');
      break;

    case "red":
      alert('you pressed red');
      break;

    case "reset":
      alert('you pressed reset');
      break;

  }
}

//get all buttons and make them listen for a click to run a function
let buttons = document.querySelectorAll(".button");
buttons.forEach(button => button.addEventListener("click", buttonPress));
@import url('https://fonts.googleapis.com/css?family=Muli&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Comforter Brush&display=swap');
@import url('https://fonts.googleapis.com/css?family=Quicksand&display=swap');

/* 
  Two variables to dictate width and height of grid elements.
  These values are updated by javascript.
*/
:root {
  --w:1px;
  --h:1px;
}

h3 {
  font-family: 'Quicksand', sans-serif;
  font-weight: 700;
  font-style: normal;
  letter-spacing: -.02em;
  color: rgb(15, 45, 0);
  font-size: 18px;
  line-height: 1.15;
}

.header {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px;
  margin: 20px;
  border: solid;
  border-color: black;
  flex-direction: column;
}

.main-program-space {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px;
  margin: 20px;
  border: solid;
  border-color: black;
  flex-direction: column;
}

.buttons-flexbox {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  margin: 20px;
  border: solid;
  border-color: red;
  list-style: none;
  flex-direction: row;
  gap: 20px;
}


/* This will make our buttons look cool and change when hovered over */

.button {
  align-items: center;
  background-image: linear-gradient(144deg, #AF40FF, #5B42F3 50%, #00DDEB);
  border: 0;
  border-radius: 8px;
  box-shadow: rgba(151, 65, 252, 0.2) 0 15px 30px -5px;
  box-sizing: border-box;
  color: #FFFFFF;
  display: flex;
  font-family: Phantomsans, sans-serif;
  font-size: 20px;
  justify-content: center;
  line-height: 1em;
  max-width: 100%;
  min-width: 140px;
  padding: 3px;
  text-decoration: none;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  white-space: nowrap;
  cursor: pointer;
  min-width: 150px;
  min-height: 50px;
}

.button:active,
.button:hover {
  outline: 0;
}

.main-grid-container {
  display: grid;
  justify-content: center;
  align-items: center;

  margin: 20px;
  border: none;
  width: 500px;
  height: 500px;
  
  padding:10px;
  border:1px solid black;
}

.bottom-text {
  display: flexbox;
  justify-content: center;
  align-items: center;
  padding: 10px;
  margin: 20px;
  border: solid;
  border-color: red;
}

.footer-flexbox {
  display: flexbox;
  justify-content: center;
  align-items: center;
  padding: 10px;
  margin: 20px;
  border: solid;
  border-color: black;
}

.footer {
  display: flexbox;
  justify-content: center;
  align-items: center;
  padding: 10px;
  margin: 20px;
  border: solid;
  border-color: red;
}

.grid-item {
  display: flex;
  flex: 1;
  margin: 0;
  
  background: blue;
  
  width: var(--w);
  height: var(--h);
}
<div >
  <h3>The html is working but what about CSS</h3>
  <p id="message">(messages from main.js will print here)</p>
</div>

<div >
  <ul >
    <li><button id="modify-grid" >Modify Grid</span></button></li>
    <li><button id="black" >Black</button></li>
    <li><button id="red" >Red</button></li>
    <li><button id="reset" >Reset</button></li>
  </ul>

  <div >

  </div>

  <div >
    <h3>XXXXX bottom text XXXXX</h3>
  </div>

</div>

<div >
  <div >
    <h3>XXXXX footer XXXXX</h3>
  </div>
</div>

  • Related