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>