I'm beginning my self-studying on web development. Currently working out on JS and trying to create a little "etch-a-sketch" app. I wrote a code which creates canvas with predefined "pixel" size. It work's fine to me. However, in order to make script file as narrow as possible I'm wondering if I can set size properties of pixels entirely by Flexbox properties in CSS. Mathematically speaking I'd like every new element inside parent container to have properties: Width = parentsWidth/nthChild, Height = Width (so every item could always be the biggest possible square regardless of items number).
let initialValue = 100;
const radioValues = document.querySelectorAll('input[name=size]');
let pixelSize = initialValue;
// event listener for chosing size value and setting new canvas
for (let i = 0; i < 3; i++) {
radioValues[i].addEventListener('click', function(e){
initialValue = Number((e.target.value));
pixelSize = initialValue;
//erasing existing pixels
if (document.querySelectorAll('.pixel').length > 0) {
const existingPixel = document.querySelectorAll('.pixel')
for(let i = 0; i < existingPixel.length;i++){
existingPixel[i].remove();
}
}
// building new pixels
for (let i = 0; i < pixelSize; i++){
let container = document.querySelector('.container');
let pixel = document.createElement('div');
pixel.setAttribute('class', 'pixel');
// part to get rid of
if (pixelSize == 400) {
pixel.style.height = "25px";
pixel.style.width = "25px";
}
if (pixelSize == 1600) {
pixel.style.height = "12.5px";
pixel.style.width = "12.5px";
}
container.appendChild(pixel);
}
})
}
.container {
width: 500px;
height: 500px;
margin-left: auto;
margin-right: auto;
border: 1px solid grey;
margin-top: 10%;
display: flex;
flex-wrap: wrap;
padding: 0;
}
.pixel {
height: 50px;
width: 50px;
border:1px solid grey;
margin: 0;
box-sizing: border-box;
}
<form>
<input class="size_selection" type="radio" name="size" value="100" checked> <label for="size_selection">10x10</label>
<input class="size_selection" type="radio" name="size" value="400"> <label for="size_selection">20x20</label>
<input class="size_selection" type="radio" name="size" value="1600"> <label for="size_selection">40x40</label>
</form>
<div class="container"></div>
<button id="clear">Clear</button>
I just refactored your script to use css grid and the corresponding grid-template-rows and grid-template-columns properties to match your grid.
Using grid in this instance makes it much more easy to get the result you want.
Just look around, I made some changes not only to CSS but also to HTML and JS. Hope it helps
let initialValue = 100;
const radioValues = document.querySelectorAll('input[name=size]');
let pixelSize = initialValue;
let container = document.getElementById('container');
// event listener for chosing size value and setting new canvas
for (let i = 0; i < 3; i++) {
radioValues[i].addEventListener('click', function(e) {
initialValue = Number((e.target.value));
pixelSize = initialValue;
//erasing existing pixels
if (document.querySelectorAll('.pixel').length > 0) {
const existingPixel = document.querySelectorAll('.pixel')
for (let i = 0; i < existingPixel.length; i++) {
existingPixel[i].remove();
}
}
// building new pixels
// setting the correct number of columns and rows in the grid
container.style.gridTemplateColumns = 'repeat(' + pixelSize + ', 1fr)';
container.style.gridTemplateRows = 'repeat(' + pixelSize + ', 1fr)';
for (let i = 0; i < pixelSize * pixelSize; i++) {
let pixel = document.createElement('div');
pixel.classList.add('pixel');
container.appendChild(pixel);
}
})
}
radioValues[0].click();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
form {
text-align: center;
margin: 2rem auto;
}
#container {
width: 300px;
height: 300px;
margin: 2rem auto;
border: 1px solid grey;
display: grid;
}
.pixel {
border: 1px solid gray;
}
<body>
<form>
<input class="size_selection" type="radio" name="size" value="10" checked> <label for="size_selection">10x10</label>
<input class="size_selection" type="radio" name="size" value="20"> <label for="size_selection">20x20</label>
<input class="size_selection" type="radio" name="size" value="40"> <label for="size_selection">40x40</label>
</form>
<div id="container">
</div>
<button id="clear">Clear</button>
</body>