Trying to get all four counters to finish at the same time.
e.g.
Counter four should stay at zero until counter three reaches value of 14, then switch to 1.
Counter one should increment by following counter two and three.
https://jsfiddle.net/IhaveVoicesinMyhead/0j9q1b85/2/#&togetherjs=f3xchiJM9f
const counter = document.querySelectorAll('.counter');
const speed = 200;
counter.forEach(counter => {
const updateCount = () => {
const target = +counter.getAttribute('data-target');
const count = +counter.innerText;
const increment = target / speed;
if (count < target) {
counter.innerText = Math.ceil(count + increment);
setTimeout(updateCount, 80);
} else {
count.innerText = target;
}
}
updateCount();
});
.counters {
margin-top: 2em;
}
.counters .container-max-width {
display: flex;
position: relative;
flex-flow: row nowrap;
justify-content: center;
align-items: stretch;
background-color: #fff;
font-size: 1rem;
text-transform: uppercase;
}
.counters .container-max-width .counter {
font-size: 3.25em;
}
.counters .container-max-width span {
color: #848484;
padding: 0;
}
.counters .container-inner-width {
display: grid;
grid-gap: 200px;
grid-template-columns: repeat(4, 1fr);
padding: 85px 0 85px 0;
text-align: center;
}
<section class="counters">
<div class="container-max-width">
<div class="container-inner-width">
<div>
<div class="counter counter-one" data-target="4">0</div>
<span>counter one</span>
</div>
<div>
<div class="counter counter-two" data-target="10">0</div>
<span>counter two</span>
</div>
<div>
<div class="counter counter-three" data-target="15">0</div>
<span>counter three</span>
</div>
<div>
<div class="counter counter-four" data-target="1">0</div>
<span>counter four</span>
</div>
</div>
</div>
</section>
Here's a simple example of how you can create multiple timers that all end at the same time. I separated the logic behind it (countUp()) from the view (createTimer()), so you should be able to adapt the countUp() function to whatever needs you have. Just give it your desired final value, how long you want it to execute (in ms), and what you want it to do at each step.
const counter1 = document.getElementById('counter1')
const counter2 = document.getElementById('counter1')
function countUp({ to, onStep, duration, _currentValue = 0 }) {
onStep(_currentValue)
if (_currentValue === to) return
setTimeout(() => {
countUp({ to, onStep,duration, _currentValue: _currentValue + 1 })
}, duration / to)
}
function createTimer(to) {
const timerEl = document.createElement('div')
document.body.appendChild(timerEl)
const onStep = currentValue => {
timerEl.innerText = currentValue
}
countUp({ to, duration: 3000, onStep })
}
createTimer(1)
createTimer(10)
createTimer(20)
Note that this doesn't account for setTimeout() drift (setTimeout doesn't always execute the callback as soon as the you asked it to), so you shouldn't use this solution for longer-lasting or very precise timers. You can add some more math to it if you want to account for drift.
Related
I'm going through The Odin Project and I'm working on completing Tic Tac Toe. I have almost everything completed but I'm stuck with coming up with the logic that checks what symbol (X or O) is being stored in each board and how to check for a winner. The directions say to store everything inside an array so I was doing that but I can't figure out how to update the array to store whichever symbol and check for a winner.
You’re going to store the gameboard as an array inside of a Gameboard object, so start there! Your players are also going to be stored in objects… and you’re probably going to want an object to control the flow of the game itself.
This is what I have completed so far.
I have a player function that stores each players name and the symbol that represents them.
const player = (name, symbol) => {
return { name, symbol };
};
const Player1 = player("Player X", "X");
const Player2 = player("Player O", "O");
I have a for loop that loops through my main div and creates 9 divs that represent the 9 squares for the game.
const createGameBoard = function () {
for (i = 0; i < 9; i++) {
gameBoardElements(); // Function that appends div to main board class
}
};
createGameBoard();
This is the function I'm using when I click on one of the divs. At the top I have the variable turn = 0 and after every click, it goes up by one. Using the modulus operator and my player function I'm making the text inside the board div either X or O and I'm changing the class so the div has a different background color. I know I could use the style feature but I don't like changing my html too much.
const board = document.querySelectorAll(".game-board");
board.forEach((el) => el.addEventListener("click", selectBoard));
// Decides which symbol to add to board: X or O
function selectBoard(e) {
e.target.appendChild(
createPElement(`${turn % 2 === 0 ? Player1.symbol : Player2.symbol}`)
);
turn++;
e.target.className = "complete-board";
e.target.removeEventListener("click", selectBoard); // prevent additional clicks
}
What I've tried
I've tried creating the array myGameBoard and appending each div to it inside the createGameBoard function
let myGameBoard = [
{board: 1, value: ""}
{board: 2, value: ""}
etc...
];
But I couldn't find a way to update the value of each div after I click to make it either an X or an O.
const currentTurn = document.getElementById("current-turn");
const getGameBoard = document.getElementById("board");
const btn = document.getElementById("btn");
let turn = 0;
// Main Player function. Gives default name and symbol
const player = (name, symbol) => {
return { name, symbol };
};
const Player1 = player("Player X", "X");
const Player2 = player("Player O", "O");
console.log(Player1);
// Creates a div and appends to board div
const gameBoardElements = function () {
const getBoard = document.getElementById("board");
const createBoard = document.createElement("div");
getBoard.appendChild(createBoard);
createBoard.className = "game-board";
};
// For loop that creates 9 divs and adds to board div
const createGameBoard = function () {
for (i = 0; i < 9; i++) {
gameBoardElements(); // Function that appends div to main board class
}
};
createGameBoard();
// Creates the [p] element that displays either X or O inside the gameboard div
function createPElement(symbol) {
let p = document.createElement("p");
p.textContent = symbol;
p.className = "text";
return p;
}
// Selects all game boards and assigns two event listener functions
const board = document.querySelectorAll(".game-board");
board.forEach((el) => el.addEventListener("click", selectBoard));
board.forEach((el) => el.addEventListener("click", updateBoard));
// Decides which symbol to add to board: X or O
function selectBoard(e) {
e.target.appendChild(
createPElement(`${turn % 2 === 0 ? Player1.symbol : Player2.symbol}`)
);
turn++;
e.target.className = "complete-board";
e.target.removeEventListener("click", selectBoard); // prevent additional clicks
}
// Updates the [p] tag that shows whose turn it is at the top
function updateBoard() {
currentTurn.textContent = `${
turn % 2 === 0 ? `${Player1.name} turn` : `${Player2.name} turn`
}`;
}
// Reset button text display
btn.addEventListener("mouseover", function () {
this.textContent = "Reset >>";
});
btn.addEventListener("mouseout", function () {
this.textContent = "Reset >";
});
body {
background-color: #fffdfa;
}
.title {
font-size: 42px;
font-family: "Dancing Script", cursive;
}
.current-turn {
font-size: 24px;
}
.content {
background-color: #fffdfa;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 700px;
width: 800px;
margin: 0 auto;
border-radius: 8px;
}
.board {
display: flex;
flex-flow: row wrap;
align-content: center;
justify-content: space-evenly;
gap: 10px;
background-color: #fff;
height: 500px;
width: 600px;
}
.board div,
.complete-board {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid #000;
background-color: #3c4048;
width: 175px;
height: 150px;
}
.board div:hover {
background-color: #f4e06d;
transform: scale(1.1);
transition: 0.8s;
box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.5);
}
.complete-board {
background-color: #f4e06d !important;
}
.text {
font-size: 64px;
}
.btn {
display: inline-block;
background-color: #4649ff;
padding: 0.5em 2em;
margin-top: 20px;
cursor: pointer;
font-family: "Poor Story", cursive;
font-size: 2rem;
letter-spacing: 0.4rem;
transition: all 0.3s;
text-decoration: none;
}
.btn:hover {
box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.5);
}
.parallelogram {
transform: skew(-20deg);
}
.skew-fix {
display: inline-block;
transform: skew(20deg);
}
<div class="content">
<p class="title">Tic Tac Toe</p>
<p class="current-turn" id="current-turn">Player X Turn</p>
<div id="board" class="board"></div>
<a id="btn" class="btn parallelogram" onclick="reset()">
<span class="skew-fix">Reset ></span>
</a>
</div>
The winning logic will include checking the element if
it is any one of the corner elements or if it is the element at the center.
it is any of the other elements.
If it is case 1, you will check all horizontal/vertical/diagonal elements if they are the same.
If it is case 2, you will check for all horizontal/vertical elements if they are the same.
If any of the above two statements are true, then you have won the game.
I hope I gave you some hint or logic.
I just wanna run a function when my height of my div reaches the bottom of the page on scroll? Is their any way to do that using JavaScript?
The most contemporary JS solution is to use an intersection observer. (MDN). It is less resource intensive than older solutions that listen to the scroll event. With the intersection observer you can decide exactly where you want the function to trigger and you can reuse it like this example shows:
class CountUp {
constructor(triggerEl, counterEl) {
const counter = document.querySelector(counterEl)
const trigger = document.querySelector(triggerEl)
let num = 0
const countUp = () => {
if (num <= counter.dataset.stop)
++num
counter.textContent = num
}
const observer = new IntersectionObserver((el) => {
if (el[0].isIntersecting) {
const interval = setInterval(() => {
(num < counter.dataset.stop) ? countUp() : clearInterval(interval)
}, counter.dataset.speed)
}
}, { threshold: [0] })
observer.observe(trigger)
}
}
// Initialize any number of counters:
new CountUp('#start1', '#counter1')
new CountUp('#start2', '#counter2')
p {
font-weight: bold;
text-align: center;
margin-top: 5%;
font-size: 2rem;
color: green;
}
.start-counter {
text-align: center;
padding: 0 0 5rem;
}
.counter {
text-align: center;
/* transition: .1s ease; */
font-size: 14rem;
color: red;
font-weight: bold;
font-family: sans-serif;
padding: 0 0 30rem;
}
<p>Scroll down ↓</p>
<div style="height:100vh;"></div>
<div id="start1" class="start-counter">Counter starts counting here!</div>
<div id="counter1" class="counter" data-stop="199" data-speed="20">0</div>
<p>Scroll down ↓</p>
<div style="height:100vh;"></div>
<div id="start2" class="start-counter">Counter starts counting here!</div>
<div id="counter2" class="counter" data-stop="300" data-speed="20">0</div>
I coded a game for 2 people:
Initialization is done with player1 ()
with the displayScore () function I can reiterate the score as much as I want (here everything is fine)
but when I switch to the other player with the changePlayer (player) function, the event goes well with player2 I can also reiterate but the concern is that the first player continues to play while my functions and variables are well partitioned
the problem comes from the event of the first which continues despite my stopPropagation () which I did not forget to report.
Where's the problem I've been on for a day and a half.
I join the two files html and js and also css
Thank you in advance,
cordially.
jeu de dés
<body>
<div id="launchGame">
<h1>NEW GAME</h1>
</div>
<div id="players">
<div id="player_1"><h2>PLAYER 1</h2><span id="score_player_1">Score :</span></div>
<picture><img id="dice">img</picture>
<div id="player_2"><h2>PLAYER 2</h2><span id="score_player_2">Score :</span></div>
</div>
<div id="current_score">
<div id="current_score_1"><p>current<span id="round_player_1"></span></p></div>
<div id="controls_game">
<h3 id="roll_dice"><img src="images/re_game.png">ROLL DICE</h3>
<h3 id="hold"><img src="images/charge_score.png">HOLD</h3>
</div>
<div id="current_score_2"><p>current<span id="round_player_2"></span></p></div>
</div>
</body>
(function(){
window.addEventListener("DOMContentLoaded", function() {
const launch = document.getElementById("launchGame");
const rollDice = document.getElementById("roll_dice");
function currentPlayer(player) {
const hold = document.getElementById("hold");
if (player.getElementsByTagName("img").length < 1) {
player.firstChild.style.position = "relative";
var currentPlayer = new Image();
currentPlayer.src = "images/current_player.png";
currentPlayer.setAttribute("class", player.getAttribute("id"));
currentPlayer.style.position = "absolute";
player.firstChild.appendChild(currentPlayer);
} else {
player.getElementsByTagName("img")[0].style.visibility = "visible";
}
changePlayer(player);
rollDice.addEventListener("click", function(e) {
e.stopPropagation();
displayScore(player);
}, {capture:false, once: false, useCapture: true});
}
function player1() {
let player1 = document.getElementById("player_1");
currentPlayer(player1);
}
function player2() {
let player2 = document.getElementById("player_2");
currentPlayer(player2);
}
function changePlayer(player) {
hold.addEventListener("click", function(e) {
e.stopPropagation();
player.getElementsByTagName("img")[0].style.visibility = "hidden";
if (player.getAttribute("id") === "player_1") {
console.log(player.getAttribute("id"));
player2();
} else if (player.getAttribute("id") === "player_2") {
console.log(player.getAttribute("id"));
player1();
}
}, {capture:false, once:true, useCapture: true});
}
function displayScore(player) {
let scoreDice = getScoreDice();
let scorePlayer = document.getElementById("round_" +
player.getAttribute("id"));
scorePlayer.textContent = scoreDice();
}
function getScoreDice() {
var result = 0;
var faceDice = Math.floor(Math.random()*7);
if ((faceDice > 0) && (faceDice < 7)) {
result = faceDice;
} else {
result = faceDice+1;
}
function innerGetScoreDice() {
return result;
}
return innerGetScoreDice;
}
launch.addEventListener("click", player1(), {capture:false, once:true});
});
})()
body {
margin: 0;
padding: 0;
background-color: silver;
background: linear-gradient(to left, white, white 50%, rgb(228, 227, 227) 50%, rgb(228, 227, 227));
text-align: center;
color: gray;
}
h1 {
width: 40%;
margin: 1% auto 5%;
font-size: 1.5rem;
}
h1::before {
content: "⊕ ";
font-size: 2rem;
align-items: center;
color: tomato;
}
h2 {
height: 30px;
line-height: 30px;
}
h3 {
margin: 7% 0;
}
span {
display: block;
margin-top: 50%;
}
img {
max-width: 10%;
vertical-align: middle;
margin-right: 3%;
}
#players, #final_score, #current_score, #current_score_1, #current_score_2, #controls_game {
display: flex;
}
#players, #final_score, #current_score {
flex-direction: row;
justify-content:space-evenly;
align-items: center;
}
#players {
justify-content:space-around;
margin: 1% 1% 10%;
}
#current_score_1, #current_score_2 {
border-radius: 20%;
padding: 2% 4%;
background-color: tomato;
color: white;
}
#controls_game {
flex-direction: column;
max-width: 33%;
}
In function changePlayer(player), isn't variable 'hold' undefined ?
No
The variable hold is defined and ok
All variables are ok
Problems is in event of first players
Bubble or capture
I don't now whats this
I am currently working on a web project that has some incrementation animation and I've created a counter function like this :
const counters = document.querySelectorAll('.counter');
counters.forEach(counter => {
const updateCount = () => {
const target = +counter.getAttribute('data-target');
const count = +counter.innerText;
const speed = target / 1000; //this will not work accurate if using Math.ceil or floor to round number up
if (count < target) {
counter.innerText = count + speed;
setTimeout(updateCount,1);
} else {
counter.innerText = target;
}
}
updateCount();
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html , body {
width: 100%;height: 100%;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
/* HEADER */
.counter {
font-size: 20px;
font-weight: bold;
padding: 5px;
}
<span data-target="20" class="counter">0</span>
<span data-target="100" class="counter">0</span>
<span data-target="50" class="counter">0</span>
<span data-target="250000" class="counter">0</span>
The problem is the number display in the web is decimal. I've tried math.ceil,math.floor, ... But they seem to mess up the speed of the counter . Is there a way of display only the integer part WITHOUT
messing with the speed ?
You need to pass the incremented value to the function itself instead of reading the printed value.
See the comments on the code.
const counters = document.querySelectorAll('.counter');
counters.forEach(counter => {
/* expecting a parameter */
const updateCount = (count) => {
const target = +counter.getAttribute('data-target');
/* at the first function call without argument
* read the innerText value, otherwise read it from
* the argument (change const with var)
*/
var count = count || +counter.innerText;
const speed = target / 1000;
if (count < target) {
/* print the value with parseInt() so you keep
* the integer part only
*/
counter.innerText = parseInt(count + speed, 10);
/* call the function passing the original sum of
* count + speed
*/
setTimeout(function() {
updateCount(count+speed)
}, 1);
}
else {
/* use parseInt() */
counter.innerText = parseInt(target, 10);
}
}
updateCount();
});
.counter {
font-size: 20px;
font-weight: bold;
padding: 5px;
display: block;
}
<span data-target="20" class="counter">0</span>
<span data-target="100" class="counter">0</span>
<span data-target="50" class="counter">0</span>
<span data-target="250000" class="counter">0</span>
As a side note, you can also pass a second target argument to the function, instead of continuously access the DOM to read it, exactly as I've done for count, since it doesn't change.
The same value is being used for the calculation and displaying the value so if you round it off you lose the precision. If on the first iteration it does 1.3+3=4.3 on the next iteration the 4.3 will be rounded up and the sum would be 5+3. That's what's making the speed seem off.
Adding another hidden attribute to the span (count-value in the code below) gives you a way to store the whole number with all the decimals to use in the calculations and then you can display the number without decimals to the users without it throwing off the sum.
const counters = document.querySelectorAll('.counter');
counters.forEach(counter => {
const updateCount = () => {
const target =+counter.getAttribute('data-target');
//update count with the full value
const count =+counter.getAttribute('count-value');
const speed = target / 1000; //this will not work accurate if using Math.ceil or floor to round number up
if (count < target) {
//set the innertext to the rounded up value
counter.innerText = Math.ceil(count + speed);
//update the hidden attribute with the full value
counter.setAttribute('count-value', count + speed);
setTimeout(updateCount,1);
} else {
counter.innerText = target;
}
}
updateCount();
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html , body {
width: 100%;height: 100%;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
/* HEADER */
.counter {
font-size: 20px;
font-weight: bold;
padding: 5px;
}
<span data-target="20" count-value="0" class="counter">0</span>
<span data-target="100" count-value="0" class="counter">0</span>
<span data-target="50" count-value="0" class="counter">0</span>
<span data-target="250000" count-value="0" class="counter">0</span>
This might help you : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed
example with an extra data-attribute:
const counters = document.querySelectorAll('.counter');
counters.forEach(counter => {
const updateCount = () => {
const target = +counter.getAttribute('data-target');
const count = +counter.getAttribute('data-count');
const speed = target / 1000; //this will not work accurate if using Math.ceil or floor to round number up
if (count < target) {
counter.setAttribute('data-count', count + speed);
let stripped = (count + speed).toFixed(0);
counter.innerText = stripped
setTimeout(updateCount, 1);
} else {
counter.innerText = target;
}
}
updateCount();
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
/* HEADER */
.counter {
font-size: 20px;
font-weight: bold;
padding: 5px;
}
<span data-target="20" class="counter">0</span>
<span data-target="100" data-count="0" class="counter">0</span>
<span data-target="50" data-count="0" class="counter">0</span>
<span data-target="250000" data-count="0" class="counter">0</span>
I am building a timer that has a pause and resume function. I found out the user can set multiple intervals when the timer is clicked more than once.
How can I prevent users from setting multiple intervals?
I tried inserting ($('.clock)).off("click") once the interval has set, but then couldn't figure out how to resume it. I thought I could do a statement pause = true, but not sure how I can use it in my code.
let currentMins = 10
let currentCount = 10*60
let pause = true
$(document).ready(function(){
// --- SET TIME --- //
$('select').on('change', function(){
const timePair = {
pappardelle : 7,
penne : 10,
farfalle : 11,
bucatini : 8,
angelhair : 4,
gnocchi : 1,
orecchiette : 10,
justboiledeggs : 11
}
const selected = this.value
for(let keys in timePair){
let toPrint = ''
if(selected.split(' ').join('').toLowerCase() == keys){
toPrint = timePair[keys]
$('#mins').html(toPrint)
$('.clock').html(toPrint+':00')
currentMins = toPrint
currentCount = timePair[keys]*60
console.log('current counts on set: ',currentCount)
}
}
})
// --- UPDATE CLOCK --- //
//basic increment and decrement setting
$('.decrement').click(function(){
if((currentMins)>1){
currentMins-=1
currentCount-=60
$('#mins').html(currentMins)
$('.clock').html(currentMins + ':00')
console.log("current mins and count in decrement :", currentMins, currentCount)
}
})
$('.increment').click(function(){
if(currentMins<100){
currentMins+=1
currentCount += 60
$('#mins').html(currentMins)
$('.clock').html(currentMins + ':00')
console.log("current mins and count in increment :", currentMins, currentCount)
}
})
$('.clock').click(function(){
console.log("current currentCount in the starting clock div :", currentCount)
//interval setting
const interval = window.setInterval(function(){
if(currentCount == 0){
pause=true
$('.clock').html('Buon appetito!')
} else {
console.log("current currentCount in the else clause in clock div :", currentCount)
pause = false
currentCount --
let minuites = Math.floor(currentCount / 60)
let seconds = currentCount - minuites * 60
$('.clock').html(minuites + ':' + ('0' + seconds).slice(-2))
}
$('.pause').click(function(){
pause = true;
clearInterval(interval)
})
}, 1000)
$('select').on('change', function(){
pause = true;
clearInterval(interval)
})
})
})//end jquery
You can do that with a flag variable:
let started = false
and a conditional return statement:
if (started && !pause) {
return;
} else {
started = true;
}
All it does is when the clock is clicked, it checks to see if started is true. If it is, then the timer has already been enabled, so it just returns out of the function (unless it's paused). If the value of started is false, then the timer begins and the flag variable is set to true.
See this working example:
let currentMins = 10
let currentCount = 10 * 60
let pause = true
let started = false
$(document).ready(function() {
// --- SET TIME --- //
$('select').on('change', function() {
const timePair = {
pappardelle: 7,
penne: 10,
farfalle: 11,
bucatini: 8,
angelhair: 4,
gnocchi: 1,
orecchiette: 10,
justboiledeggs: 11
}
const selected = this.value
for (let keys in timePair) {
let toPrint = ''
if (selected.split(' ').join('').toLowerCase() == keys) {
toPrint = timePair[keys]
$('#mins').html(toPrint)
$('.clock').html(toPrint + ':00')
currentMins = toPrint
currentCount = timePair[keys] * 60
console.log('current counts on set: ', currentCount)
}
}
if (selected.indexOf('Seamless') != -1) {
window.open('http://seamless.com', '_blank')
}
})
// --- UPDATE CLOCK --- //
//basic increment and decrement setting
$('.decrement').click(function() {
if ((currentMins) > 1) {
currentMins -= 1
currentCount -= 60
$('#mins').html(currentMins)
$('.clock').html(currentMins + ':00')
console.log("current mins and count in decrement :", currentMins, currentCount)
}
})
$('.increment').click(function() {
if (currentMins < 100) {
currentMins += 1
currentCount += 60
$('#mins').html(currentMins)
$('.clock').html(currentMins + ':00')
console.log("current mins and count in increment :", currentMins, currentCount)
}
})
$('.clock').click(function() {
if (started && !pause) {
return;
} else {
started = true;
}
console.log("current currentCount in the starting clock div :", currentCount)
//interval setting
const interval = window.setInterval(function() {
if (currentCount == 0) {
pause = true
$('.clock').html('Buon appetito!')
} else {
console.log("current currentCount in the else clause in clock div :", currentCount)
pause = false
currentCount--
let minuites = Math.floor(currentCount / 60)
let seconds = currentCount - minuites * 60
$('.clock').html(minuites + ':' + ('0' + seconds).slice(-2))
}
$('.pause').click(function() {
pause = true;
clearInterval(interval)
})
}, 1000)
$('select').on('change', function() {
pause = true;
clearInterval(interval)
})
})
}) //end jquery
body {
margin: 50px;
font-family: 'Cormorant Garamond', serif;
color: tomato;
}
main {
justify-content: center;
}
h1 {
font-size: 40px;
text-align: center;
}
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: [col1-start] 130px [col2-start] 130px [col3-start] 140px [col3-end];
grid-template-rows: [row1-start] 120px [row2-start] 120px [row2-end];
background-color: #fff;
color: tomato;
justify-content: center;
}
.box {
color: tomato;
padding: 30px;
font-size: 150%;
border: 1px solid tomato;
}
.food {
grid-column: col1-start / col3-start;
grid-row: row1-start;
}
.clock {
grid-column: col3-start;
grid-row: row1-start / row2-end;
display: flex;
justify-content: center;
align-items: center;
}
.clock:hover {
color: #ffd700;
font-size: 25px;
cursor: pointer;
}
.settimer {
grid-column: col1-start;
grid-row: row2-start;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
align-content: stretch;
}
.settimer div {
margin: 5px;
}
#mins {
align-items: center;
font-size: 20px;
}
.icon {
font-size: 15px;
}
.icon:hover {
color: #ffd700;
cursor: pointer;
font-size: 18px;
}
.pause {
grid-column: col2-start;
grid-row: row2-start;
font-size: 20px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
align-content: stretch;
}
.pause:hover {
color: #ffd700;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="pomodoro.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Cormorant+Garamond:400,700" rel="stylesheet">
<script src="pomodorooo.js"></script>
<title>Pomodoro Clock</title>
</head>
<body>
<main>
<h1>Pomodoro clock</h1>
<div class="grid">
<div class="box food">Set the timer for
<select id="pasta">
<option id="0">I meant, pasta</option>
<option id="1">Pappardelle</option>
<option id="2">Penne</option>
<option id="3">Farfalle</option>
<option id="4">Bucatini</option>
<option id="5">Angel Hair</option>
<option id="6">Gnocchi</option>
<option id="7">Orecchiette</option>
<option id="8">Just boiled eggs</option>
<option id="9">Take me to Seamless already</option>
</select>
<!-- deleted form -->
</div>
<!-- a click box that has various food options, default set for each food -->
<div class="box clock">Start</div>
<!-- a blank circle. will be filled red-->
<div class="box settimer">
<div class="decrement icon"><i class="fas fa-caret-left"></i></div>
<div id="mins">Ready</div>
<!-- deleted span -->
<div class="increment icon"><i class="fas fa-caret-right"></i></div>
</div>
<!-- timer set. increment and decrement enabled -->
<div class="box pause">Pause</div>
<!-- break set. increment and decrement enabled -->
</div>
</main>
<br /><br /><br /><br /><br /><br />
</body>
</html>