How to hide an element if it has this id and class - javascript

I am have this div here which I'm using with the drag and drop API:
<div class="box student" draggable="true" style="background-color: #1DDBCA;margin:10px" id="5"><span>Seymen Ege</span></div>
If I drag this element:
<div class="box c1r1" draggable="true" style="background-color: #1DDBCA;margin:10px;display:inline-block" id=" "><span>Boş</span></div>
and drop it on the div it works fine but I want it to hide itself if it has this " " id and has the student class. But it shouldn't hide it otherwise.
I need to add something to it so that it hides the element if it has the " " id and the "student" class after being dropped. How can I do that?
const boxElements = document.querySelectorAll(".box");
boxElements.forEach(elem => {
elem.addEventListener("dragstart", dragStart);
// elem.addEventListener("drag", drag);
elem.addEventListener("dragend", dragEnd);
elem.addEventListener("dragenter", dragEnter);
elem.addEventListener("dragover", dragOver);
elem.addEventListener("dragleave", dragLeave);
elem.addEventListener("drop", drop);
});
// Drag and Drop Functions
function dragStart(event) {
event.target.classList.add("drag-start");
event.dataTransfer.setData("text", event.target.id);
}
function dragEnd(event) {
event.target.classList.remove("drag-start");
}
function dragEnter(event) {
if (!event.target.classList.contains("drag-start")) {
event.target.classList.add("drag-enter");
}
}
function dragOver(event) {
event.preventDefault();
}
function dragLeave(event) {
event.target.classList.remove("drag-enter");
}
function drop(event) {
event.preventDefault();
event.target.classList.remove("drag-enter");
const draggableElementId = event.dataTransfer.getData("text");
const droppableElementId = event.target.id;
if (draggableElementId !== droppableElementId) {
const draggableElement = document.getElementById(draggableElementId);
const droppableElementBgColor = event.target.style.backgroundColor;
const droppableElementTextContent = event.target.querySelector("span").textContent;
event.target.style.backgroundColor = draggableElement.style.backgroundColor;
event.target.querySelector("span").textContent = draggableElement.querySelector("span").textContent;
event.target.id = draggableElementId;
draggableElement.style.backgroundColor = droppableElementBgColor;
draggableElement.querySelector("span").textContent = droppableElementTextContent;
draggableElement.id = droppableElementId;
}
}
#import url('https://fonts.googleapis.com/css?family=Montserrat');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Montserrat', sans-serif;
background-color: #eee;
color: #333;
}
.box {
width: 80px;
border: 3px solid #333;
border-radius: 0.5rem;
margin: 1.25rem;
display: inline-block;
justify-content: center;
align-items: center;
text-align: center;
font-weight: bold;
user-select: none;
cursor: move;
transition: 0.5s;
}
.box span {
pointer-events: none;
}
/* Drag and Drop Related Styling */
.drag-start {
opacity: 0.4;
}
.drag-enter {
border-style: dashed;
}
.box:nth-child(odd).drag-enter {
transform: rotate(15deg);
}
.box:nth-child(even).drag-enter {
transform: rotate(-15deg);
}
.box:nth-child(odd).drag-start {
transform: rotate(15deg) scale(0.75);
}
.box:nth-child(even).drag-start {
transform: rotate(-15deg) scale(0.75);
}
#media (max-width: 600px) {
html {
font-size: 14px;
}
.box {
width: 4rem;
height: 4rem;
margin: 0.5rem;
}
}
<div class="box student" draggable="true" style="background-color: #1DDBCA;margin:10px" id="5"><span>Seymen Ege</span></div>
<div class="box c1r1" draggable="true" style="background-color: #1DDBCA;margin:10px;display:inline-block" id=" "><span>Boş</span></div>

As #connexo said, working with space characters within ids or classes leads to invalid HTML, so to get the desired result you can use another class (e.g. 'drag-end') to set the desired properties:
.student.drag-end {
display: none;
}
For instance, the above css will apply to the element <element class="student drag-end">

Having empty IDs or IDs with space is not a good way. I would use a data attribute
Anyway:
function dragEnd(event) {
const tgt = event.target
if (tgt) {
tgt.classList.remove("drag-start");
if (tgt.id.trim() === "" && tgt.classList.contains("student")) {
tgt.remove()
}
}
}
const boxElements = document.querySelectorAll(".box");
boxElements.forEach(elem => {
elem.addEventListener("dragstart", dragStart);
// elem.addEventListener("drag", drag);
elem.addEventListener("dragend", dragEnd);
elem.addEventListener("dragenter", dragEnter);
elem.addEventListener("dragover", dragOver);
elem.addEventListener("dragleave", dragLeave);
elem.addEventListener("drop", drop);
});
// Drag and Drop Functions
function dragStart(event) {
event.target.classList.add("drag-start");
event.dataTransfer.setData("text", event.target.id);
}
function dragEnd(event) {
const tgt = event.target
if (tgt) {
tgt.classList.remove("drag-start");
console.log(tgt.className)
if (tgt.id.trim() === "" && tgt.classList.contains("student")) {
tgt.remove()
}
}
}
function dragEnter(event) {
if (!event.target.classList.contains("drag-start")) {
event.target.classList.add("drag-enter");
}
}
function dragOver(event) {
event.preventDefault();
}
function dragLeave(event) {
event.target.classList.remove("drag-enter");
}
function drop(event) {
event.preventDefault();
event.target.classList.remove("drag-enter");
const draggableElementId = event.dataTransfer.getData("text");
const droppableElementId = event.target.id;
if (draggableElementId !== droppableElementId) {
const draggableElement = document.getElementById(draggableElementId);
const droppableElementBgColor = event.target.style.backgroundColor;
const droppableElementTextContent = event.target.querySelector("span").textContent;
event.target.style.backgroundColor = draggableElement.style.backgroundColor;
event.target.querySelector("span").textContent = draggableElement.querySelector("span").textContent;
event.target.id = draggableElementId;
draggableElement.style.backgroundColor = droppableElementBgColor;
draggableElement.querySelector("span").textContent = droppableElementTextContent;
draggableElement.id = droppableElementId;
}
}
#import url('https://fonts.googleapis.com/css?family=Montserrat');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Montserrat', sans-serif;
background-color: #eee;
color: #333;
}
.box {
width: 80px;
border: 3px solid #333;
border-radius: 0.5rem;
margin: 1.25rem;
display: inline-block;
justify-content: center;
align-items: center;
text-align: center;
font-weight: bold;
user-select: none;
cursor: move;
transition: 0.5s;
}
.box span {
pointer-events: none;
}
/* Drag and Drop Related Styling */
.drag-start {
opacity: 0.4;
}
.drag-enter {
border-style: dashed;
}
.box:nth-child(odd).drag-enter {
transform: rotate(15deg);
}
.box:nth-child(even).drag-enter {
transform: rotate(-15deg);
}
.box:nth-child(odd).drag-start {
transform: rotate(15deg) scale(0.75);
}
.box:nth-child(even).drag-start {
transform: rotate(-15deg) scale(0.75);
}
#media (max-width: 600px) {
html {
font-size: 14px;
}
.box {
width: 4rem;
height: 4rem;
margin: 0.5rem;
}
}
<div class="box student" draggable="true" style="background-color: #1DDBCA;margin:10px" id="5"><span>Seymen Ege</span></div>
<div class="box c1r1" draggable="true" style="background-color: #1DDBCA;margin:10px;display:inline-block" id=" "><span>Boş</span></div>

Related

JavaScript If and else statement w/function calls not producing expected result

I have a mobile menu that includes four list items. When you click on the "Features" list item, another unordered list is supposed to populate below it, and when you click it again, it's supposed to close it.
Here's my issue:
Inside the addEventListener function, I am calling two other functions (displayType and displayTypeCheck) inside the if, and else statement. When I do this and click on the "Features" list item, it opens but does not close when I click it again.
If I don't use the displayType and displayTypeCheck functions in the if and else statement and click on the "Features" list item, the UL will both open and close.
Why does the if and else statement that calls the other two functions not work, and how do I get it to work?
In the provided Javascript code below, the if and else statement that's commented out works, and the block that's not commented out is the code that doesn't entirely work.
const menuIcon = document.querySelector(".mobile-menu-icon");
const mobileMenu = document.querySelector(".mobile-menu");
const closeMenuIcon = document.querySelector(".close-menu-icon");
const featuresMobile = document.querySelector(".features-mobile");
const featuresMobileDropdown = document.querySelector(".features-mobile-dropdown");
const overlay = document.querySelector(".overlay");
function displayType(element, displayValue) {
element.style.display = displayValue;
}
function displayTypeCheck(element, displayValue) {
element.style.display === displayValue;
}
menuIcon.addEventListener("click", function () {
displayType(mobileMenu, 'block');
displayType(overlay, 'block');
});
closeMenuIcon.addEventListener("click", function () {
displayType(mobileMenu, 'none');
displayType(overlay, 'none');
});
featuresMobile.addEventListener("click", function () {
// if (featuresMobileDropdown.style.display === "block") {
// featuresMobileDropdown.style.display = "none";
// } else {
// featuresMobileDropdown.style.display = "block";
// }
if (displayTypeCheck(featuresMobileDropdown, "block")) {
displayType(featuresMobileDropdown, "none");
} else {
displayType(featuresMobileDropdown, "block");
}
});
#import url("https://fonts.googleapis.com/css2?family=Epilogue:wght#500;700&display=swap");
:root {
--almostWhite: hsl(0, 0%, 98%);
--mediumGray: hsl(0, 0%, 41%);
--almostBlack: hsl(0, 0%, 8%);
--navDropDownColor: #e9ecef;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
body {
min-height: 100vh;
font-family: "Epilogue", sans-serif;
background-color: var(--almostWhite);
}
header {
padding: .9375rem 2.5rem .9375rem 2.5rem;
max-width: 100rem;
margin: auto;
}
header nav {
display: flex;
align-items: center;
justify-content: flex-end;
}
header nav ul li {
cursor: pointer;
}
.register {
border: .125rem solid var(--mediumGray);
padding: .625rem .9375rem;
border-radius: .8125rem;
}
.mobile-menu-icon {
height: 3.125rem;
}
.mobile-menu-icon {
display: block;
cursor: pointer;
}
.mobile-menu .mobile-nav-links {
margin-top: 4.375em;
padding-left: .9375em;
color: var(--mediumGray);
}
.mobile-menu ul li {
padding: .625em;
}
.mobile-menu .mobile-nav-links li ul {
margin-left: .625em;
margin-top: .625em;
display: none;
}
.mobile-menu {
background-color: white;
width: 18.75em;
height: 100vh;
position: absolute;
top: 0;
right: 0;
z-index: 2;
display: none;
}
.close-menu-icon {
margin-left: auto;
margin-right: 1.25em;
margin-top: 1.25em;
display: block;
cursor: pointer;
height: 3.125em;
}
.login-register-mobile-container {
color: var(--mediumGray);
width: 90%;
margin: 3.125em auto;
}
.login-register-mobile-container span {
display: block;
text-align: center;
cursor: pointer;
}
.login-register-mobile-container span:first-child {
margin-bottom: 1.25em;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(.1875rem);
z-index: 1;
display: none;
}
<header>
<nav>
<img class="mobile-menu-icon" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Hamburger_icon.svg/2048px-Hamburger_icon.svg.png" alt="" />
<div class="mobile-menu">
<img
class="close-menu-icon"
src="https://cdn4.iconfinder.com/data/icons/user-interface-131/32/close-512.png"
alt=""
/>
<ul class="mobile-nav-links">
<li class="features-mobile">Features
<ul class="features-mobile-dropdown">
<li>Todo List</li>
<li>Calenders</li>
<li>Reminders</li>
<li>Planning</li>
</ul>
</li>
<li class="company-mobile">Company</li>
<li>Careers</li>
<li>About</li>
</ul>
<div class="login-register-mobile-container">
<span class="login">Login</span>
<span class="register">Register</span>
</div>
</div>
</nav>
<div class="overlay"></div>
</header>
You forgot the return statement.
function displayTypeCheck(element, displayValue) {
return element.style.display === displayValue;
}
Otherwise the function will always return undefined which is a falsey value.
Within the displayTypeCheck function, you aren't returning the boolean result of the conditions.
Without the return statement, it is returning void
function displayTypeCheck(element, displayValue) {
return element.style.display === displayValue;
}

Range slider resetting to default on firefox

So I'm making an Etch-a-Sketch with a range slider to change the grid size, but the slider keeps resetting to its default size (16x16) as soon as I move the mouse after changing the value (if I change the value and don't move the mouse, the size doesn't reset). For some reason this doesn't happen on Chrome: the value and grid size both change and stay that way until I change them again.
Here's the JSFiddle: https://jsfiddle.net/CamiCoding/7zpt14cs/
HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Etch-a-Sketch</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class="title">
<h1>Etch-a-Sketch</h1>
</div>
<div class="btns">
<button id="blackBtn">Black</button>
<button id="rainbowBtn">Rainbow</button>
<button id="colorBtn">Color</button>
<button id="eraserBtn">Eraser</button>
<button id="resetBtn">Reset</button>
<div class="colorPicker">
<input type="color" id="color" value="#000000">
<span>Pick a color</span>
</div>
<div class="sliderAndValue">
<input type="range" min="2" max="100" value="16" id="slider">
<p class="value">16</p>
</div>
</div>
<div class="grid">
</div>
<script src="script.js" defer></script>
</body>
</html>
CSS:
#font-face {
src: url("../fonts/sf-atarian-system.regular.ttf");
font-family: Atarian;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-family: Atarian;
background-color: #D1D1D1;
}
.title h1 {
font-size: 80px;
margin: 0px;
}
.btns {
display: flex;
flex-direction: row;
width: 700px;
height: 50px;
justify-content: space-evenly;
margin-top: 20px;
margin-bottom: 20px;
}
.btns button {
font-family: Atarian;
font-size: 24px;
height: 40px;
width: 80px;
border-radius: 5px;
transition: transform 0.2s ease-in-out;
}
.btns button:hover {
transform: scale(1.2);
}
.btns .active {
background-color: #505050;
color: white;
}
.colorPicker {
display: flex;
flex-direction: column;
align-items: center;
font-size: 20px;
}
.color span {
text-align: center;
}
#color {
width: 90px;
}
.sliderAndValue {
-webkit-appearance: none;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-size: 24px;
}
#slider {
-webkit-appearance: none;
width: 150px;
height: 10px;
background: #000;
outline: none;
border: 4px solid gray;
border-radius: 4px;
}
/* for firefox */
#slider::-moz-range-thumb {
width: 5px;
height: 20px;
background: #000;
cursor: pointer;
border: 4px solid gray;
border-radius: 4px;
}
/* for chrome/safari */
#slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 5px;
height: 20px;
background: #000;
cursor: pointer;
border: 4px solid gray;
border-radius: 4px;
}
.cell {
border: 1px solid black;
}
.cell.active {
background-color: black;
}
.grid {
display: inline-grid;
grid-template-columns: repeat(16, 2fr);
grid-template-rows: repeat(16, 2fr);
border: 5px solid gray;
border-radius: 5px;
height: 700px;
width: 700px;
background-color: white;
}
JS:
const grid = document.querySelector('.grid');
const resetBtn = document.getElementById('resetBtn');
const eraserBtn = document.getElementById('eraserBtn');
const blackBtn = document.getElementById('blackBtn');
const colorBtn = document.getElementById('colorBtn')
const colorValue = document.getElementById('color');
const slider = document.getElementById('slider');
const sliderValue = document.querySelector('.value');
const DEFAULT_COLOR = '#000000';
const DEFAULT_MODE = 'black';
const DEFAULT_SIZE = 16;
let currentColor = DEFAULT_COLOR;
let currentMode = DEFAULT_MODE;
let mouseDown = false
document.body.onmousedown = () => (mouseDown = true)
document.body.onmouseup = () => (mouseDown = false)
function setCurrentColor(newColor) {
currentColor = newColor;
}
function setCurrentMode(newMode) {
activateButton(newMode);
currentMode = newMode;
}
blackBtn.onclick = () => setCurrentMode('black');
rainbowBtn.onclick = () => setCurrentMode('rainbow');
eraserBtn.onclick = () => setCurrentMode('eraser');
colorBtn.onclick = () => setCurrentMode('color');
resetBtn.onclick = () => createGrid();
function createGrid() {
removeCells(grid);
let val = document.getElementById('slider').value;
sliderValue.textContent = val;
grid.style.gridTemplateColumns = (`repeat(${val}, 2fr`);
grid.style.gridTemplateRows = (`repeat(${val}, 2fr`);
for(let i = 0; i < val * val; i++) {
const cell = document.createElement('div');
cell.classList.add('cell');
cell.addEventListener('mouseover', changeColor);
cell.addEventListener('mousedown', changeColor);
grid.appendChild(cell);
}
}
function activateButton(newMode) {
if (currentMode === 'rainbow') {
rainbowBtn.classList.remove('active');
} else if (currentMode === 'color') {
colorBtn.classList.remove('active');
} else if (currentMode === 'eraser') {
eraserBtn.classList.remove('active');
} else if (currentMode === 'black') {
blackBtn.classList.remove('active');
}
if (newMode === 'rainbow') {
rainbowBtn.classList.add('active');
} else if (newMode === 'color') {
colorBtn.classList.add('active');
} else if (newMode === 'eraser') {
eraserBtn.classList.add('active');
} else if (newMode === 'black') {
blackBtn.classList.add('active');
}
}
function changeColor(e) {
if (e.type === 'mouseover' && !mouseDown) return;
if (currentMode === 'rainbow') {
const randomR = Math.floor(Math.random() * 256);
const randomG = Math.floor(Math.random() * 256);
const randomB = Math.floor(Math.random() * 256);
e.target.style.backgroundColor = `rgb(${randomR}, ${randomG}, ${randomB})`;
} else if (currentMode === 'color') {
e.target.style.backgroundColor = colorValue.value;
} else if (currentMode === 'eraser') {
e.target.style.backgroundColor = '#ffffff';
} else if (currentMode === 'black') {
e.target.style.background = '#000000';
}
}
slider.addEventListener('input', function(){
let val = document.getElementById('slider').value;
sliderValue.textContent = val;
removeCells(grid);
grid.style.gridTemplateColumns = (`repeat(${val}, 2fr`);
grid.style.gridTemplateRows = (`repeat(${val}, 2fr`);
for (let i = 0; i < val * val; i++) {
const cell = document.createElement('div');
cell.classList.add('cell');
cell.addEventListener('mouseover', changeColor);
cell.addEventListener('mousedown', changeColor);
grid.appendChild(cell);
}
});
function removeCells(parent){
while(grid.firstChild){
grid.removeChild(grid.firstChild);
}
}
window.onload = () => {
createGrid(DEFAULT_SIZE);
activateButton(DEFAULT_MODE);
}
I do have another question regarding this same project, but about a different issue, please let me know if I should post a different question for it or if I should post it here too!
Thanks a lot in advance :).
I was able to track down the source of the issue, and fix it. Sounds weird, but document.body.onmousedown and document.body.onmouseup were creating the issue.
Replacing them with addEventListener seems to fix it.
I also removed some repeated code (in slider's input listener), by making maximum use of createGrid() function.
const grid = document.querySelector('.grid');
const resetBtn = document.getElementById('resetBtn');
const eraserBtn = document.getElementById('eraserBtn');
const blackBtn = document.getElementById('blackBtn');
const colorBtn = document.getElementById('colorBtn')
const colorValue = document.getElementById('color');
const slider = document.querySelector('#slider');
const sliderValue = document.querySelector('.value');
const DEFAULT_COLOR = '#000000';
const DEFAULT_MODE = 'black';
const DEFAULT_SIZE = 16;
let currentColor = DEFAULT_COLOR;
let currentMode = DEFAULT_MODE;
let mouseDown = false
document.body.addEventListener("mousedown", () => (mouseDown = true))
document.body.addEventListener("mouseup", () => (mouseDown = false))
function setCurrentColor(newColor) {
currentColor = newColor;
}
function setCurrentMode(newMode) {
activateButton(newMode);
currentMode = newMode;
}
blackBtn.onclick = () => setCurrentMode('black');
rainbowBtn.onclick = () => setCurrentMode('rainbow');
eraserBtn.onclick = () => setCurrentMode('eraser');
colorBtn.onclick = () => setCurrentMode('color');
resetBtn.onclick = () => createGrid();
function createGrid(val = 16) {
slider.value = val;
sliderValue.textContent = val;
removeCells(grid);
grid.style.gridTemplateColumns = (`repeat(${val}, 2fr`);
grid.style.gridTemplateRows = (`repeat(${val}, 2fr`);
for (let i = 0; i < val * val; i++) {
const cell = document.createElement('div');
cell.classList.add('cell');
cell.addEventListener('mouseover', changeColor);
cell.addEventListener('mousedown', changeColor);
grid.appendChild(cell);
}
}
function activateButton(newMode) {
if (currentMode === 'rainbow') {
rainbowBtn.classList.remove('active');
} else if (currentMode === 'color') {
colorBtn.classList.remove('active');
} else if (currentMode === 'eraser') {
eraserBtn.classList.remove('active');
} else if (currentMode === 'black') {
blackBtn.classList.remove('active');
}
if (newMode === 'rainbow') {
rainbowBtn.classList.add('active');
} else if (newMode === 'color') {
colorBtn.classList.add('active');
} else if (newMode === 'eraser') {
eraserBtn.classList.add('active');
} else if (newMode === 'black') {
blackBtn.classList.add('active');
}
}
function changeColor(e) {
if (e.type === 'mouseover' && !mouseDown) return;
if (currentMode === 'rainbow') {
const randomR = Math.floor(Math.random() * 256);
const randomG = Math.floor(Math.random() * 256);
const randomB = Math.floor(Math.random() * 256);
e.target.style.backgroundColor = `rgb(${randomR}, ${randomG}, ${randomB})`;
} else if (currentMode === 'color') {
e.target.style.backgroundColor = colorValue.value;
} else if (currentMode === 'eraser') {
e.target.style.backgroundColor = '#ffffff';
} else if (currentMode === 'black') {
e.target.style.background = '#000000';
}
}
slider.addEventListener('input', function(e) {
let val = parseInt(document.getElementById('slider').value);
createGrid(val);
});
function removeCells(parent) {
while (grid.firstChild) {
grid.removeChild(grid.firstChild);
}
}
window.onload = () => {
createGrid(DEFAULT_SIZE);
activateButton(DEFAULT_MODE);
}
#font-face {
src: url("../fonts/sf-atarian-system.regular.ttf");
font-family: Atarian;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-family: Atarian;
background-color: #D1D1D1;
}
.title h1 {
font-size: 80px;
margin: 0px;
}
.btns {
display: flex;
flex-direction: row;
width: 700px;
height: 50px;
justify-content: space-evenly;
margin-top: 20px;
margin-bottom: 20px;
}
.btns button {
font-family: Atarian;
font-size: 24px;
height: 40px;
width: 80px;
border-radius: 5px;
transition: transform 0.2s ease-in-out;
}
.btns button:hover {
transform: scale(1.2);
}
.btns .active {
background-color: #505050;
color: white;
}
.colorPicker {
display: flex;
flex-direction: column;
align-items: center;
font-size: 20px;
}
.color span {
text-align: center;
}
#color {
width: 90px;
}
.sliderAndValue {
-webkit-appearance: none;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-size: 24px;
}
#slider {
-webkit-appearance: none;
width: 150px;
height: 10px;
background: #000;
outline: none;
border: 4px solid gray;
border-radius: 4px;
}
/* for firefox */
#slider::-moz-range-thumb {
width: 5px;
height: 20px;
background: #000;
cursor: pointer;
border: 4px solid gray;
border-radius: 4px;
}
/* for chrome/safari */
#slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 5px;
height: 20px;
background: #000;
cursor: pointer;
border: 4px solid gray;
border-radius: 4px;
}
.cell {
border: 1px solid black;
}
.cell.active {
background-color: black;
}
.grid {
display: inline-grid;
grid-template-columns: repeat(16, 2fr);
grid-template-rows: repeat(16, 2fr);
border: 5px solid gray;
border-radius: 5px;
height: 700px;
width: 700px;
background-color: white;
user-select: none;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Etch-a-Sketch</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class="title">
<h1>Etch-a-Sketch</h1>
</div>
<div class="btns">
<button id="blackBtn">Black</button>
<button id="rainbowBtn">Rainbow</button>
<button id="colorBtn">Color</button>
<button id="eraserBtn">Eraser</button>
<button id="resetBtn">Reset</button>
<div class="colorPicker">
<input type="color" id="color" value="#000000">
<span>Pick a color</span>
</div>
<div class="sliderAndValue">
<input type="range" min="2" value="16" id="slider">
<p class="value">16</p>
</div>
</div>
<div class="grid">
</div>
<script src="script.js" defer></script>
</body>
</html>

Changing background color doesn't work well

I am trying to change the background color of my webpage using a hamburger menu. There are 4 color options on my hamburger menu. I managed to get a change on the background when clicking on the color of my choice. But that change only happens once. When I clicked another color and come back to click that same color from earlier on, it doesn't respond. The color seems to change only once, and not more than that.
The repository to my GitHub code is here: https://github.com/tand100b/Winc_Academy
const changeColorButton1 = document.getElementById("color1");
changeColorButton1.addEventListener("click", function() {
changeClassRedBackground();
});
const changeColorButton2 = document.getElementById("color2");
changeColorButton2.addEventListener("click", function() {
changeClassOrangeBackground();
});
const changeColorButton3 = document.getElementById("color3");
changeColorButton3.addEventListener("click", function() {
changeClassPurpleBackground();
});
const changeColorButton4 = document.getElementById("color4");
changeColorButton4.addEventListener("click", function() {
changeClassGreenBackground();
});
const changeClassRedBackground = function() {
const bodyElement = document.body;
bodyElement.classList.add("red-background");
}
const changeClassOrangeBackground = function() {
const bodyElement = document.body;
bodyElement.classList.add("orange-background");
};
const changeClassPurpleBackground = function() {
const bodyElement = document.body;
bodyElement.classList.add("purple-background");
};
const changeClassGreenBackground = function() {
const bodyElement = document.body;
bodyElement.classList.add("green-background");
};
body {
background-color: pink;
}
.red-background {
background-color: red;
}
.orange-background {
background-color: orange;
}
.purple-background {
background-color: purple;
}
.green-background {
background-color: green;
}
.btn-toggle-nav {
width: 60px;
height: 20%;
background-color: #f98f39;
background-image: url("https://i.stack.imgur.com/tniUv.png");
background-repeat: no-repeat;
background-size: 60%;
background-position: center;
cursor: pointer;
}
.btn-toggle-nav:hover {
opacity: 0.5;
}
.navbar ul {
padding-top: 15px;
/* visibility: hidden; */
}
.navbar ul li {
line-height: 60px;
list-style: none;
background-color: white;
width: 300px;
padding-top: 0px;
padding-top: 0px;
}
.navbar ul li a {
display: block;
height: 60px;
padding: 0 10px;
text-decoration: none;
font-family: arial;
font-size: 16px;
}
.navbar {
background-color: red;
width: 50px;
padding: 0 5px;
height: calc(100vh-60px);
z-index: 1000;
}
.list {
margin-top: 0px;
}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<div class="btn-toggle-nav"></div>
<aside class="navbar">
<ul class="list">
<li><a id="color1" href="#">Red</a></li>
<li><a id="color2" href="#">Orange</a></li>
<li><a id="color3" href="#">Purple</a></li>
<li><a id="color4" href="#">Green</a></li>
</ul>
</aside>
Can someone please look at my code and suggest what I can do?
Firstly, I suggest declaring variable bodyElement only once at the top of the file because each time it would be the same body element:
const bodyElement = document.body
Next, we create function that will check if body has any style classes in its classList. If it's not empty (length more than one) we remove all classes, and do nothing otherwise:
const isBodyHasStyle = () => bodyElement.classList.length ? bodyElement.classList = '' : null
Then, on each button click we going to call our new function:
changeColorButton1.addEventListener("click", function() {
isBodyHasStyle()
changeClassRedBackground();
});
Do the same with other buttons.
You need to make sure that you don't have multiple classes conflicting with each other, also try to DRY your code, here is an alternative I came up with:
const changeColor = (e) => {
const bodyElement = document.querySelector('body');
const colorIdMap = {
"color1": "red-background",
"color2": "orange-background",
"color3": "purple-background",
"color4": "green-background"
}
bodyElement.className = colorIdMap[e.target.id];
}
const btns = document.querySelectorAll('.list li');
btns.forEach(btn => btn.addEventListener('click', changeColor))
An easier way to accomplish this is by setting a data attribute on the background, based on the selected color. Just add a color data value to each of the menu items and set the body background to that color.
const toggleMenu = (event) => {
event.target.closest('.navbar').classList.toggle('open');
};
const changeColor = (event) => {
document.body.dataset.background = event.target.dataset.color;
toggleMenu(event); /* do not call ~ to stay open */
};
document.querySelector('.btn-toggle-nav')
.addEventListener('click', toggleMenu)
document.querySelectorAll('.color-picker')
.forEach(e => e.addEventListener('click', changeColor));
/* CSS reset */
html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
body { display: flex; background-color: #222; }
ul { list-style-type: none; margin: 0; }
body[data-background="red"] { background-color: red }
body[data-background="orange"] { background-color: orange }
body[data-background="purple"] { background-color: purple }
body[data-background="green"] { background-color: green }
body[data-background="default"] { /* Do not set the background-color */ }
a[data-color="red"] { color: red; }
a[data-color="orange"] { color: orange; }
a[data-color="purple"] { color: purple; }
a[data-color="green"] { color: green; }
a[data-color="default"] { color: #222; }
.list {
position: absolute;
display: none; /* hide menu (default) */
flex-direction: column;
gap: 0.5em;
padding: 0.5em;
width: 6em;
left: 2em;
background: #444;
}
.list li a { text-decoration: none; font-weight: bold; }
.list li a:hover { text-decoration: underline; }
.navbar {
position: relative;
width: 2em;
background-color: #444;
}
.navbar.open .list {
display: flex; /* show menu */
}
.btn-toggle-nav {
width: 2em;
height: 2em;
background-image: url("https://i.stack.imgur.com/tniUv.png");
background-repeat: no-repeat;
background-size: 60%;
background-position: center;
cursor: pointer;
}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<aside class="navbar">
<div class="btn-toggle-nav"></div>
<ul class="list">
<li><a class="color-picker" href="#" data-color="red">Red</a></li>
<li><a class="color-picker" href="#" data-color="orange">Orange</a></li>
<li><a class="color-picker" href="#" data-color="purple">Purple</a></li>
<li><a class="color-picker" href="#" data-color="green">Green</a></li>
<li><a class="color-picker" href="#" data-color="default">Default</a></li>
</ul>
</aside>

How to pass item id in event listener to update list input item?

I have managed to build a To Do List on my own and have implemented the addTodo and add to/get from local storage functionality. I now need to add the update functionality to update a Todo list item. I understand that I first need to attach an event listener to the ul and find the closest li item id or something like that. Then I need to pass an update function to the event listener to update the input value in the list. Here is what I have so far. How would I create the event listener and update function to update a list item?
Output needed: Text of added item needs to update (to local storage) after user clicks on text and changes text of item.
Note: The snippet won't work because local storage is not allowed (as far as I know). You will need to see the codepen
// select DOM elements
const todoForm = document.querySelector('.todo-form');
const todoInput = document.querySelector('.todo-input');
const todoItemsList = document.querySelector('.todo-items');
// array which stores every todo item
// each item will be an object with id, name, completed boollean
let todos = [];
// add an event listener on form
todoForm.addEventListener('submit', function(e) {
e.preventDefault();
// input param from addTodo is todoInput.value
addTodo(todoInput.value);
});
document.addEventListener('click', (e) => {
if (e.target.classList.contains('checkbox')) {
if (e.target.checked) e.target.closest('.item').classList.add('checked');
else e.target.closest('.item').classList.remove('checked');
}
});
// todoItemsList.addEventListener('input', (e) => {
// const taskId = e.target.item.id;
// console.log(taskId);
// });
// todoItemsList.addEventListener('input', (e) => {
// const taskId = e.target.closest('li').id
// console.log(taskId)
// // updateTask(taskId, e.target)
// })
function addTodo(input) {
if (input !== '') {
const todo = {
id: Date.now(),
name: input,
completed: false,
};
todos.push(todo);
addToLocalStorage(todos);
todoInput.value = '';
}
}
// todos is passed as parameter because it exists outside function environment
function renderTodos(todos) {
// clear list
todoItemsList.innerHTML = '';
// run through each item inside todos
todos.forEach((item) => {
// checkbox
let cb = document.createElement('input');
cb.type = 'checkbox';
cb.classList.add('checkbox');
cb.checked = false;
// delete button
const deleteButton = document.createElement('button');
deleteButton.className = 'delete-button';
deleteButton.innerText = 'x';
// lists
const li = document.createElement('li');
li.classList.add('item');
li.setAttribute('data-key', item.id);
li.appendChild(cb);
li.append(item.name);
li.append(deleteButton);
todoItemsList.append(li);
});
}
function addToLocalStorage(todos) {
// name key 'todos" and value todos array
// convert array to string and store it
localStorage.setItem('todos', JSON.stringify(todos));
renderTodos(todos);
}
function getFromLocalStorage() {
const reference = localStorage.getItem('todos');
if (reference) {
// converts string back to an array and store in todos array
todos = JSON.parse(reference);
renderTodos(todos);
}
}
getFromLocalStorage();
* {
padding: 0;
margin: 0;
}
body {
width: 100vw;
min-height: 100vh;
display: flex;
justify-content: center;
background: hsl(194, 100%, 70%);
font-family: 'Roboto', sans-serif;
}
button {
display: inline-block;
padding: 0.35em 1.2em;
border: 0.1em solid hsl(0, 0%, 0%);
margin: 0 0.3em 0.3em 0;
background: hsl(0, 0%, 0%);
border-radius: 0.12em;
box-sizing: border-box;
text-decoration: none;
font-family: 'Roboto', sans-serif;
font-weight: 300;
color: hsl(0, 0%, 100%);
text-align: center;
transition: all 0.2s;
}
button:hover {
cursor: pointer;
background-color: hsl(0, 0%, 100%);
color: hsl(214, 11%, 13%);
}
ul {
list-style-type: none;
}
.container {
min-width: 700px;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
h1 {
color: hsl(0, 0%, 100%);
font-size: 3rem;
}
/* To Do Form */
.todo-form {
margin: 40px 0px;
}
.todo-input {
width: 250px;
border: none;
outline: none;
border-radius: 5px;
padding: 10px;
margin-right: 10px;
font-size: 1rem;
}
.todo-items {
min-width: 350px;
height: auto;
}
/* Item style */
.item {
height: auto;
background-color: #fff;
margin: 1em;
padding: 10px;
font-size: 1.2rem;
vertical-align: middle;
border-radius: 5px;
}
.checkbox {
width: 1.5em;
height: 1.5em;
margin-right: 20px;
vertical-align: middle;
}
.delete-button {
display: inline-flex;
justify-content: center;
align-items: center;
float: right;
width: 25px;
height: 25px;
background-color: hsl(348, 93%, 56%);
border: none;
outline: none;
/* border-radius: 7px; */
/* padding: 2px 5px; */
/* margin-left: 10px; */
font-size: 0.8rem;
font-weight: 550;
text-align: center;
vertical-align: middle;
}
.delete-button:hover {
background: pink;
}
.checked {
text-decoration: line-through;
}
.text-container {
min-width: 100px;
height: 50px;
background: red;
}
<div class="container">
<h1>To Do</h1>
<form class="todo-form">
<input type="text" class="todo-input" placeholder="add a todo item">
<button type="submit" class="add=button">Add</button>
</form>
<ul class="todo-items">
</ul>
</div>
You actually don't need ID here. You can maintain use the index of the element to determine what todo it belongs to. Check below code
todoItemsList.addEventListener('click', (e) => {
// Anywhere inside UL clicked
let clickedElement = e.target;
if (clickedElement.classList.contains('delete-button') || clickedElement.classList.contains('checkbox')) {
// Either checkbox or delete button is clicked
let listElement = clickedElement.parentNode;
let listElementsArray = todoItemsList.querySelectorAll('li');
let index = Array.prototype.indexOf.call(listElementsArray, listElement);
if (clickedElement.classList.contains('delete-button')) {
//Delete button clicked
listElement.remove();
todos.splice(index, 1);
} else if (clickedElement.classList.contains('checkbox')) {
//Checkbox clicked
todos[index].completed = e.target.checked;
}
console.log(todos);
// Update in localstorage
localStorage.setItem('todos', JSON.stringify(todos));
}
});
Note: Here I have used Array.prototype.indexOf.call instead of listElementsArray.indexOf because listElementsArray is a node list which doesn't support indexOf natively.
I reworked your code a bit because I was getting lost in it...
the part that interests you is at the end, with :
todoList.onclick = ({target}) =>
{
if (!target.matches('li input[type=checkbox], button.delete-button')) return
let li = target.closest('li')
, idx = todos.findIndex(x=>x.id==li.dataset.key)
;
switch (target.tagName.toLowerCase())
{
case 'input':
todos[idx].completed = target.checked
break;
case 'button':
todos.splice(idx, 1)
todoList.removeChild(li)
break;
}
todos.update_LocalStorage()
}
it is an event delegation arranged to manage either the checkbox or the delete button
full code
const
todoForm = document.querySelector('#todo-form')
, todoList = document.querySelector('#todo-items')
, todos = JSON.parse( localStorage.getItem('todos') || '[]')
;
todos.UI_add = item =>
{
let li = document.createElement('li')
li.dataset.key = item.id
li.innerHTML = `
<input type="checkbox" ${item.completed ? 'checked':''} >
<span>${item.name}</span>
<button class="delete-button">x</button>`
todoList.appendChild(li)
}
todos.update_LocalStorage = _ =>
{
localStorage.setItem('todos', JSON.stringify(todos))
}
todoForm.onsubmit = e =>
{
e.preventDefault()
let str = todoForm['todo-text'].value.trim()
if (str !== '')
{
let item = { id: Date.now(), name:str, completed: false }
todos.push( item )
todos.UI_add( item )
todos.update_LocalStorage()
todoForm['todo-text'].value = ''
todoForm['todo-text'].focus()
}
}
todoList.onclick = ({target}) =>
{
if (!target.matches('li input[type=checkbox], button.delete-button')) return
let li = target.closest('li')
, idx = todos.findIndex(x=>x.id==li.dataset.key)
;
switch (target.tagName.toLowerCase())
{
case 'input':
todos[idx].completed = target.checked
break;
case 'button':
todos.splice(idx, 1)
todoList.removeChild(li)
break;
}
todos.update_LocalStorage()
}
// init user interface list
todos.forEach(todos.UI_add)
* {
padding: 0;
margin: 0;
}
body {
width: 100vw;
min-height: 100vh;
display: flex;
justify-content: center;
background: hsl(194, 100%, 70%);
font-family: 'Roboto', sans-serif;
}
button {
display: inline-block;
padding: 0.35em 1.2em;
border: 0.1em solid hsl(0, 0%, 0%);
margin: 0 0.3em 0.3em 0;
background: hsl(0, 0%, 0%);
border-radius: 0.12em;
box-sizing: border-box;
text-decoration: none;
font-family: 'Roboto', sans-serif;
font-weight: 300;
color: hsl(0, 0%, 100%);
text-align: center;
transition: all 0.2s;
}
button:hover {
cursor: pointer;
background-color: hsl(0, 0%, 100%);
color: hsl(214, 11%, 13%);
}
.container {
min-width : 700px;
display : flex;
flex-direction : column;
align-items : center;
padding : 20px;
}
h1 {
color : hsl(0, 0%, 100%);
font-size : 3rem;
}
form#todo-form {
margin : 40px 0;
}
form#todo-form input {
width : 250px;
border : none;
outline : none;
border-radius : 5px;
padding : 10px;
margin-right : 10px;
font-size : 1rem;
}
ul#todo-items {
min-width : 350px;
height : auto;
list-style : none;
}
ul#todo-items li {
height : auto;
background-color : #fff;
margin : 1em;
padding : 10px;
font-size : 1.2rem;
vertical-align : middle;
border-radius : 5px;
}
ul#todo-items li input[type=checkbox] {
width : 1.5em;
height : 1.5em;
margin-right : 20px;
vertical-align : middle;
}
.delete-button {
display : inline-flex;
justify-content : center;
align-items : center;
float : right;
width : 25px;
height : 25px;
background-color : hsl(348, 93%, 56%);
border : none;
outline : none;
font-size : 0.8rem;
font-weight : 550;
text-align : center;
vertical-align : middle;
}
.delete-button:hover {
background: pink;
}
ul#todo-items li input:checked + span {
text-decoration: line-through;
}
<div class="container">
<h1>To Do</h1>
<form id="todo-form">
<input type="text" name="todo-text" placeholder="add a todo item">
<button type="submit"> Add </button>
</form>
<ul id="todo-items"> </ul>
</div>

jQuery - whenever reset is clicked it does not reset blocks

The reset button makes the grid disappear.
There are two functions that are causing this problem:
reset()
main()
The reason why the grid is disappearing is because of the .empty() method that is attached to the containerGrid and that is inside the main function and because of the $resetButton.on("click", reset), the reset parameter should have () with an argument passed in.
Here is what I tried:
$resetButton.on("click", reset());
This helps with not deleting the grid, but it does not erase the color or gradient blocks anymore.
/*---------------------------
Variables
---------------------------*/
const $containerGrid = $(".containerGrid");
let boxSide = 16;
const $gridLength = $("#gridLength");
const $gradientButton = $("#gradient");
const $randomButton = $("#random");
const $resetButton = $("#reset");
/*-- -------------------------
Buttons & input
---------------------------*/
$gridLength.on("input", gridLength);
$gradientButton.on("click", incrementOpacity);
$randomButton.on("click", getRandomColors);
$resetButton.on("click", reset(16));
/*---------------------------
Corresponding to Event listeners
---------------------------*/
function gridLength() {
if (event.target.value !== 16) {
reset(event.target.value);
}
}
function incrementOpacity() {
$(".cell").off("mouseenter");
$(".cell").mouseenter((event) => {
let opacity = parseFloat(event.target.style.opacity);
if (opacity <= 0.9) {
$(event.target).css({
"opacity": `${opacity + 0.1}`,
"backgroundColor": "#f5f5f5"
});
}
});
}
function setRandomColors() {
return Math.floor((Math.random() * 256));
}
function getRandomColors() {
$(".cell").off("mouseenter");
$(".cell").mouseenter((event) => {
$(event.target).css({
"backgroundColor": `rgb(${setRandomColors()}, ${setRandomColors()}, ${setRandomColors()})`,
"opacity": "1"
})
});
}
function reset(length) {
boxSide = length;
main();
$(".cell").css({
"opacity": "0.1",
"border": "0.5px solid black",
"backgroundColor": "transparent"
});
}
/*-- -------------------------
Creates the Grid
------------------------------*/
function main() {
$($containerGrid).empty();
for (let row = 0; row < boxSide; row++) {
for (let column = 0; column < boxSide; column++) {
createCell();
}
}
$(".cell").css("height", `${(300 / boxSide) - 1}px`);
$(".cell").css("width", `${(300 / boxSide) - 1}px`);
}
function createCell() {
const $cell = $('<div class="cell"></div>');
$cell.css("opacity", "0.1");
$containerGrid.append($cell);
}
main();
* {
margin: 0;
padding: 0;
outline: 0;
font-family: Arial, Helvetica, sans-serif;
color: var(--font-color);
}
:root {
--linear-color1: #e66465;
--linear-color2: #9198e5;
--font-color: #ffffff;
--black-color: #000000;
}
body,
html {
background: linear-gradient(190deg, var(--linear-color1), var(--linear-color2));
height: 100vh;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.title header h1 {
margin: 1em 0em 1em 0;
}
.containerGrid {
display: flex;
flex-wrap: wrap;
width: 300px;
height: 300px;
margin-bottom: 3em;
}
.cell {
height: 15px;
width: 15px;
border-radius: 3px;
border: 0.5px solid var(--black-color);
}
.options {
display: flex;
justify-content: space-around;
}
button,
input {
background-color: transparent;
padding: .5em;
border: 1px solid var(--font-color);
border-radius: 3px;
transition: 1s all ease;
}
button:hover,
input:hover {
background-color: var(--font-color);
color: var(--black-color);
}
button:focus,
input:focus {
background-color: var(--font-color);
color: var(--black-color);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- ------------------------- How to Play --------------------------->
<div class="container">
<div class="title">
<header>
<h1>Etch a Sketch</h1>
</header>
</div>
<!-- ------------------------- Grid --------------------------->
<section>
<div class="containerGrid">
</div>
<div class="options">
<input type="number" id="gridLength" value="16" min="3" max="64">
<button type="submit" id="gradient">Gradient</button>
<button type="submit" id="random">Random</button>
<button type="reset" id="reset">Reset</button>
</div>
</section>
</div>
Expected: to just erase the the colorful and gradient blocks and the leave the grid size alone
Actual result: The grid does not disappear but it will not erase the colored and gradients blocks anymore. It should just reset everything except for the grid size
You set click event to your reset button the wrong way. The below code should work:
$resetButton.on("click", function() {
reset(16);
});
Full code:
/*---------------------------
Variables
---------------------------*/
const $containerGrid = $(".containerGrid");
let boxSide = 16;
const $gridLength = $("#gridLength");
const $gradientButton = $("#gradient");
const $randomButton = $("#random");
const $resetButton = $("#reset");
/*-- -------------------------
Buttons & input
---------------------------*/
$gridLength.on("input", gridLength);
$gradientButton.on("click", incrementOpacity);
$randomButton.on("click", getRandomColors);
$resetButton.on("click", function() {
reset(16);
});
/*---------------------------
Corresponding to Event listeners
---------------------------*/
function gridLength() {
if (event.target.value !== 16) {
reset(event.target.value);
}
}
function incrementOpacity() {
$(".cell").off("mouseenter");
$(".cell").mouseenter((event) => {
let opacity = parseFloat(event.target.style.opacity);
if (opacity <= 0.9) {
$(event.target).css({
"opacity": `${opacity + 0.1}`,
"backgroundColor": "#f5f5f5"
});
}
});
}
function setRandomColors() {
return Math.floor((Math.random() * 256));
}
function getRandomColors() {
$(".cell").off("mouseenter");
$(".cell").mouseenter((event) => {
$(event.target).css({
"backgroundColor": `rgb(${setRandomColors()}, ${setRandomColors()}, ${setRandomColors()})`,
"opacity": "1"
})
});
}
function reset(length) {
boxSide = length;
main();
$(".cell").css({
"opacity": "0.1",
"border": "0.5px solid black",
"backgroundColor": "transparent"
});
}
/*-- -------------------------
Creates the Grid
------------------------------*/
function main() {
$($containerGrid).empty();
for (let row = 0; row < boxSide; row++) {
for (let column = 0; column < boxSide; column++) {
createCell();
}
}
$(".cell").css("height", `${(300 / boxSide) - 1}px`);
$(".cell").css("width", `${(300 / boxSide) - 1}px`);
}
function createCell() {
const $cell = $('<div class="cell"></div>');
$cell.css("opacity", "0.1");
$containerGrid.append($cell);
}
main();
* {
margin: 0;
padding: 0;
outline: 0;
font-family: Arial, Helvetica, sans-serif;
color: var(--font-color);
}
:root {
--linear-color1: #e66465;
--linear-color2: #9198e5;
--font-color: #ffffff;
--black-color: #000000;
}
body,
html {
background: linear-gradient(190deg, var(--linear-color1), var(--linear-color2));
height: 100vh;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.title header h1 {
margin: 1em 0em 1em 0;
}
.containerGrid {
display: flex;
flex-wrap: wrap;
width: 300px;
height: 300px;
margin-bottom: 3em;
}
.cell {
height: 15px;
width: 15px;
border-radius: 3px;
border: 0.5px solid var(--black-color);
}
.options {
display: flex;
justify-content: space-around;
}
button,
input {
background-color: transparent;
padding: .5em;
border: 1px solid var(--font-color);
border-radius: 3px;
transition: 1s all ease;
}
button:hover,
input:hover {
background-color: var(--font-color);
color: var(--black-color);
}
button:focus,
input:focus {
background-color: var(--font-color);
color: var(--black-color);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- ------------------------- How to Play --------------------------->
<div class="container">
<div class="title">
<header>
<h1>Etch a Sketch</h1>
</header>
</div>
<!-- ------------------------- Grid --------------------------->
<section>
<div class="containerGrid">
</div>
<div class="options">
<input type="number" id="gridLength" value="16" min="3" max="64">
<button type="submit" id="gradient">Gradient</button>
<button type="submit" id="random">Random</button>
<button type="reset" id="reset">Reset</button>
</div>
</section>
</div>

Categories