I'm trying to create a progress circle, and get the progress value based on HTML data (data-start and data progress), but there is an error.
The code works fine on one element, but the problem occurs when creating a loop for all elements.
Uncaught Type Error: Cannot read properties of undefined (reading 'start')"
let progressBar = document.getElementsByClassName(".circular-progress");
let valueContainer = document.getElementsByClassName(".value-container");
let progressValue = valueContainer.dataset.start;
let progressEndValue = valueContainer.dataset.progress;
var twoSum = function() {
for (var i = 0; i < progressValue.length; i++) {
for (var j = 0; j < progressEndValue.length; j++) {
let progress = setInterval(() => {
i++;
valueContainer.textContent = `${[i]}%`;
progressBar.style.background = `conic-gradient(
#4d5bf9 ${[i] * 3.6}deg,
#cadcff ${[i] * 3.6}deg
)`;
if (progressValue == progressEndValue) {
clearInterval(progress);
}
}, 30);
}
}
};
.skill .container {
display: grid;
align-items: center;
}
.skill-grid {
display: grid;
grid-template-columns: 190px 190px;
grid-template-rows: 190px 190px;
justify-content: center;
column-gap: 2.5rem;
row-gap: 100px;
margin-right: 2rem;
position: relative;
}
.skill-card {
background-color: var(--white);
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
flex: 1 1 6rem;
/* padding: 3rem 4rem; */
border-radius: 0.5rem;
transition: transform ease-in-out 0.3s;
}
.skill-card p {
font-size: 1rem;
font-weight: 600;
text-align: center;
padding-top: 10px;
}
.circular-progress {
position: relative;
height: 100px;
width: 100px;
border-radius: 50%;
display: grid;
place-items: center;
}
.circular-progress:before {
content: "";
position: absolute;
height: 90%;
width: 90%;
background-color: #ffffff;
border-radius: 50%;
}
.value-container {
position: relative;
font-family: var(--main-font);
font-size: 1.3rem;
color: var(--bs-primary);
font-weight: 600;
}
<section class="skill">
<div class="container">
<div class="skill-grid">
<div class="skill-card">
<div class="circular-progress">
<div class="value-container" data-start="0" data-progress="90">0</div>
</div>
<p>UI Design</p>
</div>
<div class="skill-card">
<div class="circular-progress">
<div class="value-container" data-start="0" data-progress="80">0</div>
</div>
<p>UI Design</p>
</div>
<div class="skill-card">
<div class="circular-progress">
<div class="value-container" data-start="0" data-progress="60">0%</div>
</div>
<p>UI Design</p>
</div>
<div class="skill-card">
<div class="circular-progress">
<div class="value-container" data-start="0" data-progress="50">0%</div>
</div>
<p>UI Design</p>
</div>
</div>
</div>
</section>
You can easily simplify your code:
Better use the querySelectorAll() (and it's single element counterpart querySelector() selection method, since it provides a more versatile css-like selector syntax.
As commented by #Peter B getElementsByClassName()
selects multiple elements (besides it's expect the raw class name without trailing "." dots)
thus, you need to loop through all elements and process each item.
// find all progress circles
let progressBars = document.querySelectorAll(".circular-progress");
progressBars.forEach((progressBar) => {
// select child value container
let valueContainer = progressBar.querySelector(".value-container");
let progressValue = valueContainer.dataset.start;
let progressEndValue = valueContainer.dataset.progress;
let i = 0;
// increment progress angles
let progress = setInterval(() => {
i++;
valueContainer.textContent = `${[i]}%`;
progressBar.style.background = `conic-gradient(
#4d5bf9 ${i * 3.6}deg,
#cadcff ${i * 3.6}deg
)`;
// stop animation
if (i >= progressEndValue) {
clearInterval(progress);
}
}, 10);
});
.skill .container {
display: grid;
align-items: center;
}
.skill-grid {
display: grid;
grid-template-columns: 190px 190px;
grid-template-rows: 190px 190px;
justify-content: center;
column-gap: 2.5rem;
row-gap: 100px;
margin-right: 2rem;
position: relative;
}
.skill-card {
background-color: var(--white);
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
flex: 1 1 6rem;
/* padding: 3rem 4rem; */
border-radius: 0.5rem;
transition: transform ease-in-out 0.3s;
}
.skill-card p {
font-size: 1rem;
font-weight: 600;
text-align: center;
padding-top: 10px;
}
.circular-progress {
position: relative;
height: 100px;
width: 100px;
border-radius: 50%;
display: grid;
place-items: center;
}
.circular-progress:before {
content: "";
position: absolute;
height: 90%;
width: 90%;
background-color: #ffffff;
border-radius: 50%;
}
.value-container {
position: relative;
font-family: var(--main-font);
font-size: 1.3rem;
color: var(--bs-primary);
font-weight: 600;
}
<section class="skill">
<div class="container">
<div class="skill-grid">
<div class="skill-card">
<div class="circular-progress">
<div class="value-container" data-start="0" data-progress="90">0</div>
</div>
<p>UI Design</p>
</div>
<div class="skill-card">
<div class="circular-progress">
<div class="value-container" data-start="0" data-progress="80">0</div>
</div>
<p>UI Design</p>
</div>
<div class="skill-card">
<div class="circular-progress">
<div class="value-container" data-start="0" data-progress="60">0%</div>
</div>
<p>UI Design</p>
</div>
<div class="skill-card">
<div class="circular-progress">
<div class="value-container" data-start="0" data-progress="50">0%</div>
</div>
<p>UI Design</p>
</div>
</div>
</div>
</section>
In the above example we're selecting the outer progress circle elements.
Since the text labels are just child elements, we can select them within the loop.
Related
When I drag one card with the red border, I wanted to only show the dragged element. So, I added the .invisible class to the original element, but everything is invisible now. Why?
Full code here: https://codepen.io/asamad9134/pen/WNKLpZb
const cards = document.querySelector('.cards');
cards.addEventListener('dragstart', (event) => {
const selectedCard = event.target;
selectedCard.classList.add('invisible');
});
cards.addEventListener('dragend', (event) => {
const selectedCard = event.target;
selectedCard.classList.remove('invisible');
});
.cards {
display: flex;
width: 100vw;
justify-content: space-around;
}
.card {
font-family: Arabic;
border-radius: 10%;
;
font-size: 4em;
text-align: center;
width: 200px;
height: 130px;
background-color: white;
border: 10px solid rgb(255, 85, 0);
}
.card:hover {
cursor: grab;
transform: scale(1.2);
transition: 0.3s;
}
.empty-divs {
display: flex;
justify-content: space-around;
width: 100vw;
}
.empty-div {
display: flex;
flex-direction: column;
align-items: center;
}
.blank-card {
width: 200px;
height: 130px;
background-color: #f4f4f4;
border-radius: 10%;
text-align: center;
border: 10px solid grey;
}
.invisible {
display: none;
}
<section class="cards">
<p class="card card-idle" id="أَرْنَب" draggable=true>أَرْنَب</p>
<p class="card card-idle" draggable=true>كِتَاب</p>
<p class="card card-idle" draggable=true>كُرَة</p>
</section>
<section class="empty-divs">
<div class="empty-div">
<img id="rabbit" src="http://source.unsplash.com/random/200x200" alt="rabbit" />
<p class="blank-card"></p>
</div>
<div class="empty-div">
<img id="rabbit" src="http://source.unsplash.com/random/200x200" alt="rabbit" />
<p class="blank-card"></p>
</div>
<div class="empty-div">
<img id="rabbit" src="http://source.unsplash.com/random/200x200" alt="rabbit" />
<p class="blank-card"></p>
</div>
</section>
EDIT, I set the opacity: 0; instead but this has a strange lag affect.
display: none; removes the tag and its effects for all intents and purposes, but the tag remains visible in the source code. Try using opacity: 0.4; so that it's visibility is changed and not completely removed from the structure. You could then set that opacity to 0 if you wanted it to be completely invisibile, but not be removed.
Here's an approach to make it so that only the current element that is being dragged displays. Note that I also used visibility: hidden to hide the cards instead of opacity: 0.
// create a nodelist of all of the cards
const cards = document.querySelectorAll('.card');
// add a an event listener for each card in the nodelist
cards.forEach(card => {
card.addEventListener('dragstart', (event) => {
const selectedCard = event.target;
// create an array of the cards that are not selected so you can
// "hide" only the not selected cards
const notSelectedCards = Array.from(cards).filter(card => card !== selectedCard)
selectedCard.classList.add('card-dragging');
notSelectedCards.forEach(card => card.classList.add('invisible'));
// remove the "invisible" class (and do whatever other
// cleanup on dragend that you want)
selectedCard.addEventListener('dragend', (event) => {
selectedCard.classList.remove('card-dragging');
notSelectedCards.forEach(card => card.classList.remove('invisible'));
}, { once: true});
})
})
* {
box-sizing: border-box;
}
.cards {
display:flex;
justify-content: space-around;
}
.card {
font-family: Arabic;
border-radius: 10%;
font-size: 4em;
text-align:center;
width: 200px;
height: 130px;
background-color: white;
border: 10px solid rgb(255, 85, 0);
}
.card:hover{
cursor: grab;
transform: scale(1.2);
transition: 0.3s;
}
.empty-divs{
display: flex;
justify-content: space-around;
}
.empty-div {
display: flex;
flex-direction: column;
align-items: center;
}
.blank-card {
width: 200px;
height: 130px;
background-color: #f4f4f4;
border-radius: 10%;
text-align:center;
border: 10px solid grey;
}
.invisible {
visibility: hidden;
}
.card-dragging {
opacity: .2;
}
<section class="cards">
<p class="card card-idle" id="أَرْنَب" draggable=true>أَرْنَب</p>
<p class="card card-idle" draggable=true>كِتَاب</p>
<p class="card card-idle" draggable=true>كُرَة</p>
</section>
<section class="empty-divs">
<div class="empty-div">
<img src="http://source.unsplash.com/random/200x200" alt="random" />
<p class="blank-card"></p>
</div>
<div class="empty-div">
<img src="http://source.unsplash.com/random/200x200" alt="random" />
<p class="blank-card"></p>
</div>
<div class="empty-div">
<img src="http://source.unsplash.com/random/200x200" alt="random" />
<p class="blank-card"></p>
</div>
</section>
newbie here...
I am working on some simple project where I am trying to simulate bank app.
Thing is that when I click on send money button, I want to take value from input value, and then subtract this value from my whole account balance.
Really simple, but after first transaction I get value which I want, but after second time I get innerText displaying "Nan" instead of some number value.
Here it is javascript file, if you can see from this why I get error.
Also here it is html and css if you don't understand what I am talking about.
////////////////// TOTAL MONEY FROM CARDS ///////////////////////
const totalMoney = document.querySelector(`.totalMoney`);
const allcards = document.querySelectorAll(`.cards`);
let totalMoneyAccount = 0;
allcards.forEach((kartica) => {
let novacNaKartici = kartica.querySelector(`.novacNaKartici`).innerText;
novacNaKartici = parseInt(novacNaKartici);
totalMoneyAccount += novacNaKartici;
totalMoney.innerText = ` ${replika2} $`;
});
//////////////////////////// TRANSFER MONEY TO SOMEONE /////////////////////////////
const reciver = document.querySelector(`input[name='recivier']`);
let amount = document.querySelector(`input[name='amount']`);
const sendMoneyBtn = document.querySelector(`.sendBtn`);
const transakcijeParent = document.querySelector(`.transakcije`);
sendMoneyBtn.addEventListener(`click`, () => {
amount = parseInt(amount.value);
totalMoneyAccount = totalMoneyAccount - amount;
updateProfile(totalMoneyAccount);
});
function updateProfile(totalMoneyAccount) {
totalMoney.innerHTML = totalMoneyAccount;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD#20..48,100..700,0..1,-50..200"
/>
<link rel="stylesheet" href="style.css" />
<title>Bank app</title>
</head>
<body>
<div class="container">
<div class="profile">
<div class="header">
<span class="material-symbols-outlined"> notifications </span>
<span class="material-symbols-outlined"> search </span>
</div>
<div class="person">
<img src="/img/cost1.jpg" alt="" />
<p>Random user</p>
<span class="totalMoney" style="font-size: 20px;"></span>
</div>
<div class="menu">
<div class="account flex">
<span class="material-symbols-outlined"> manage_accounts </span>
<p>Accounts</p>
</div>
<div class="transactions flex">
<span class="material-symbols-outlined"> receipt_long </span>
<p>Transactions</p>
</div>
<div class="bonus flex">
<span class="material-symbols-outlined"> star </span>
<p>Bonus</p>
</div>
<div class="invest flex">
<span class="material-symbols-outlined"> trending_up </span>
<p>Investments</p>
</div>
<div class="logOut flex">
<span class="material-symbols-outlined"> logout </span>
<p>Log Out</p>
</div>
</div>
</div>
<div class="main">
<div class="left">
<div class="naslov">
<p>Cards</p>
<span class="material-symbols-outlined">
add_circle
</span>
</div>
<div class="allCards">
<div class="cards changeJustify">
<div class="singleCard">
<img src="/img/visa.png" alt="" class="changeImg"/>
</div>
<div class="opis">
<p style="color: grey; font-size:20px">VISA</p>
<p style="color: black; font-size:16px" class="balance1 changeBalance">Balance:</p>
</div>
<div class="balance">
<span class="material-symbols-outlined changeSpan dots">
more_vert
</span>
<span style="font-size: 22px; color:grey(59, 59, 59);" class="novacNaKartici">2500$</span>
</div>
</div>
<div class="cards changeJustify">
<div class="singleCard ">
<img src="/img/american.jpg" alt="" class="changeImg"/>
</div>
<div class="opis ">
<p style="color: grey; font-size:20px">VISA</p>
<p style="color: grey; font-size:16px" class="balance1 changeBalance">Balance:</p>
</div>
<div class="balance ">
<span class="material-symbols-outlined changeSpan dots" >
more_vert
</span>
<span style="font-size: 22px; color:black;" class="novacNaKartici">3500$</span>
</div>
</div>
</div>
<p style="font-size: 30px;
color: grey;
font-weight: bold;">Transactions</p>
<div class="transakcije">
</div>
</div>
</div>
<div class="right">
<p style="font-size: 30px;
color: grey;
font-weight: bold;">Transfer money</p>
<div class="transfer">
<label for="recivier">Transfer to</label>
<input type="text" placeholder="antonio3101" name="recivier">
<label for="amount">Amount</label>
<input type="number" placeholder="$300..." name="amount">
<button class="sendBtn">Send</button>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
body {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: sans-serif;
}
.container {
width: 100vw;
height: 100vh;
display: flex;
background-color: #f1f2f6;
}
.profile {
height: 100vh;
width: 20%;
background-color: #1d1c57;
display: flex;
flex-direction: column;
color: white;
}
.profile .header {
display: flex;
padding: 30px;
align-items: center;
justify-content: space-between;
color: #7979a6;
}
.profile .header span {
font-size: 26px;
}
.profile .header span:hover {
color: white;
}
.profile .person {
margin-top: 40px;
display: flex;
flex-direction: column;
align-items: center;
}
.profile .person img {
width: 150px;
height: 150px;
border-radius: 50%;
}
.profile .person p {
font-size: 26px;
color: #c6c5d8;
}
.profile .menu {
margin-top: 100px;
padding: 20px;
background-color: #262467;
border-radius: 30px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
height: 100%;
position: relative;
font-size: 22px;
color: #7c7eaa;
}
.profile .flex {
margin-left: 20px;
display: flex;
align-items: center;
gap: 20px;
}
.profile .flex:hover {
margin-left: 40px;
color: white;
transition: ease-in-out;
}
.logOut {
position: absolute;
bottom: 50px;
}
/*-------------------------- KARTICE ----------------------------------------- */
.main .naslov {
color: grey;
font-size: 30px;
font-weight: bold;
}
.naslov {
display: flex;
align-items: center;
justify-content: space-between;
}
.naslov span {
font-size: 32px;
}
.naslov span:hover {
color: black;
}
.main .left {
display: flex;
flex-direction: column;
margin-left: 30px;
}
.main .left .cards {
background-color: #ffffff;
padding: 20px;
display: flex;
padding: 20px;
border-radius: 20px;
}
.cards {
margin-top: 10px;
}
.cards .singleCard {
display: flex;
width: 100%;
}
.allCards {
display: flex;
flex-direction: column;
}
.cards .singleCard img {
width: 250px;
padding-right: 10px;
}
.cards .opis p {
margin: 0;
padding: 0;
margin-left: 10px;
}
.cards .opis {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.cards .balance {
margin-left: 30px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
/*------------------------------- CHANGE CARD -------------------------------- */
.changeImg {
height: 50px;
object-fit: cover;
}
.changeSpan {
display: none;
}
.changeJustify {
display: flex;
align-items: center;
}
.changeBalance {
display: none;
}
/*-------------------------- TRANSAKCIJE ----------------------------------------- */
.transakcije {
background-color: white;
display: flex;
flex-direction: column;
padding: 10px;
}
.single-transaction {
display: flex;
margin-left: 10px;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid grey;
}
.single-transaction img {
height: 60px;
width: 60px;
border-radius: 50%;
object-fit: cover;
}
.single-transaction .destination {
font-size: 16px;
color: rgb(73, 73, 73);
font-weight: bold;
}
.single-transaction .amount {
color: rgb(30, 149, 30);
font-weight: bold;
font-size: 16px;
}
.single-transaction:last-child {
border-bottom: 0;
}
/*-------------------------- RIGHT SECTIONS ----------------------------------------- */
/*-------------------------- TRANSFER MONEY ----------------------------------------- */
.right {
display: flex;
flex-direction: column;
margin-left: 100px;
}
.right .transfer {
background-color: #1d1c57;
padding: 50px 20px;
border-radius: 10px;
margin-left: 10px;
margin-right: 20px;
}
.right .transfer input {
height: 30px;
font: 24px;
margin-left: 10px;
}
.right .transfer label {
margin-left: 20px;
color: white;
}
.right .transfer button {
padding: 10px 15px;
color: black;
background-color: white;
border-radius: 5px;
border: 0;
margin-left: 20px;
margin-right: 20px;
}
You are overwriting your amount variable (which points to an input element) with the value inputted into said input.
Hence, after the first click you no longer have a reference to the input element: your code tries to read the value property of the integer amount of the last transaction. This results in the following evaluation: parseInt(amount.value) -> parseInt(undefined) -> NaN.
Change this code:
sendMoneyBtn.addEventListener(`click`, () => {
amount = parseInt(amount.value);
totalMoneyAccount = totalMoneyAccount - amount;
updateProfile(totalMoneyAccount);
});
to something like this:
sendMoneyBtn.addEventListener(`click`, () => {
const amountValue = parseInt(amount.value);
totalMoneyAccount = totalMoneyAccount - amountValue;
updateProfile(totalMoneyAccount);
});
Credit to #JohnnyMopp for noticing it first.
I have an accordion list and my task was to implement a smooth tabs open/close function for dynamic content without a set height.
The forEach method works perfectly.
The smooth open/close function (setHeight in JS snippet)also works fine, but only for the first tab.
In other tabs this function does not work and the opening does not happen as we would like it to.
I've already racked my brains.
How can I combine the forEach method and the "setHeight" function so that nothing breaks?
const accItems = document.querySelectorAll('.accordion__item');
accItems.forEach((item) => {
const icon = item.querySelector('.accordion__icon');
const content = item.querySelector('.accordion__content');
item.addEventListener('click', () => {
if (item.classList.contains('open')) {
item.classList.remove('open');
icon.classList.remove('open');
content.classList.remove('open');
} else {
const accOpen = document.querySelectorAll('.open');
accOpen.forEach((open) => {
open.classList.remove('open');
});
item.classList.add('open');
icon.classList.add('open');
content.classList.add('open');
}
if (content.clientHeight) {
content.style.height = 0;
} else {
let accText = item.querySelector('.acc-text');
content.style.height = accText.clientHeight + "px";
}
});
});
body {
margin: 0;
padding: 0;
box-sizing: border-box;
color: #1f1f1f;
background: #f2f2f2; }
html {
font-size: 62.5%; }
h5 {
margin: 0; }
p {
margin: 0; }
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: auto;
max-width: 140rem; }
.section-accordion {
display: flex;
align-items: center;
max-width: 134rem;
margin: auto; }
.accordion-image {
width: 630px;
height: 450px;
background: url("https://eternel.maitreart.com/wp-content/uploads/2021/07/creat-home-1.jpg");
background-repeat: no-repeat;
background-size: cover; }
.accordion {
width: 63rem;
height: auto;
margin-left: 8rem; }
.accordion__item {
border-top: 1px solid #a8a6a4;
overflow: hidden;
transition: height .5s;
padding-bottom: 1rem; }
.accordion__item:last-child {
border-bottom: 1px solid #a8a6a4; }
.accordion__item--header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2rem 1rem 1rem 1rem;
cursor: pointer; }
.accordion__item.open {
width: 100%; }
.accordion__title {
font-family: 'Lora';
font-size: 2.4rem;
line-height: 1.2;
font-weight: 400;
text-transform: uppercase; }
.accordion__icon {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 2rem;
height: 2rem;
transition: transform .5s ease; }
.accordion__icon span:first-child {
transform: rotate(90deg) translateX(1px);
width: 1.4rem;
height: .1rem;
background: currentColor; }
.accordion__icon span {
display: block;
width: 1.4rem;
height: .1rem;
background: currentColor;
cursor: pointer; }
.accordion__icon.open {
transform: rotate(45deg); }
.accordion__content {
font-family: 'Roboto', sans-serif;
font-size: 1.6rem;
line-height: 1.62;
font-weight: 400;
padding: 0 1rem 0 1rem;
height: 0;
transition: height .5s;
overflow: hidden; }
.accordion__content.open {
margin-bottom: 1.2rem;
height: 100%; }
<div class="container">
<section class="section-accordion">
<div class="accordion-image"></div>
<div class="accordion">
<div class="accordion__item open">
<div class="accordion__item--header">
<h5 class="accordion__title">Visual direction</h5>
<div class="accordion__icon open">
<span></span>
<span></span>
</div>
</div>
<div class="accordion__content open">
<p class="acc-text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course.
Assistance travelling so especially do prosperous appearance mr no celebrated.
Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__item--header">
<h5 class="accordion__title">Event production</h5>
<div class="accordion__icon">
<span class="accordion__icon--first"></span>
<span class="accordion__icon--second"></span>
</div>
</div>
<div class="accordion__content">
<p class="acc-text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course.
Assistance travelling so especially do prosperous appearance mr no celebrated.
Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__item--header">
<h5 class="accordion__title">Brand creation</h5>
<div class="accordion__icon">
<span class="accordion__icon--first"></span>
<span class="accordion__icon--second"></span>
</div>
</div>
<div class="accordion__content">
<p class="acc-text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course.
Assistance travelling so especially do prosperous appearance mr no celebrated.
Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__item--header">
<h5 class="accordion__title">Design concept</h5>
<div class="accordion__icon">
<span class="accordion__icon--first"></span>
<span class="accordion__icon--second"></span>
</div>
</div>
<div class="accordion__content">
<p class="acc-text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course.
Assistance travelling so especially do prosperous appearance mr no celebrated.
Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
</div>
</div>
It does not seem that you need setHeight which is the one that messes the display
Here is a delegated version
const accordionItems = document.querySelectorAll(".accordion__item");
document.querySelector('.accordion').addEventListener('click', (e) => {
const item = e.target.closest(".accordion__item");
if (!item) return
accordionItems.forEach(acItem => {
if (acItem !== item) {
acItem.classList.remove('open');
acItem.querySelector('.accordion__icon').classList.remove('open');
acItem.querySelector('.accordion__content').classList.remove('open');
}
});
const icon = item.querySelector('.accordion__icon');
const content = item.querySelector('.accordion__content');
item.classList.toggle("open")
const isOpen = item.classList.contains("open");
icon.classList.toggle("open", isOpen);
content.classList.toggle('open', isOpen);
});
body {
margin: 0;
padding: 0;
box-sizing: border-box;
color: #1f1f1f;
background: #f2f2f2;
}
html {
font-size: 62.5%;
}
h5 {
margin: 0;
}
p {
margin: 0;
}
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: auto;
max-width: 140rem;
}
.section-accordion {
display: flex;
align-items: center;
max-width: 134rem;
margin: auto;
}
.accordion-image {
width: 630px;
height: 450px;
background: url("https://eternel.maitreart.com/wp-content/uploads/2021/07/creat-home-1.jpg");
background-repeat: no-repeat;
background-size: cover;
}
.accordion {
width: 63rem;
height: auto;
margin-left: 8rem;
}
.accordion__item {
border-top: 1px solid #a8a6a4;
overflow: hidden;
transition: height .5s;
padding-bottom: 1rem;
}
.accordion__item:last-child {
border-bottom: 1px solid #a8a6a4;
}
.accordion__item--header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2rem 1rem 1rem 1rem;
cursor: pointer;
}
.accordion__item.open {
width: 100%;
}
.accordion__title {
font-family: 'Lora';
font-size: 2.4rem;
line-height: 1.2;
font-weight: 400;
text-transform: uppercase;
}
.accordion__icon {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 2rem;
height: 2rem;
transition: transform .5s ease;
}
.accordion__icon span:first-child {
transform: rotate(90deg) translateX(1px);
width: 1.4rem;
height: .1rem;
background: currentColor;
}
.accordion__icon span {
display: block;
width: 1.4rem;
height: .1rem;
background: currentColor;
cursor: pointer;
}
.accordion__icon.open {
transform: rotate(45deg);
}
.accordion__content {
font-family: 'Roboto', sans-serif;
font-size: 1.6rem;
line-height: 1.62;
font-weight: 400;
padding: 0 1rem 0 1rem;
height: 0;
transition: height .5s;
overflow: hidden;
}
.accordion__content.open {
margin-bottom: 1.2rem;
height: 100%;
}
<div class="container">
<section class="section-accordion">
<div class="accordion-image"></div>
<div class="accordion">
<div class="accordion__item open">
<div class="accordion__item--header">
<h5 class="accordion__title">Visual direction</h5>
<div class="accordion__icon open">
<span></span>
<span></span>
</div>
</div>
<div class="accordion__content open" id="content__wrapper">
<p class="acc-text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__item--header">
<h5 class="accordion__title">Event production</h5>
<div class="accordion__icon">
<span class="accordion__icon--first"></span>
<span class="accordion__icon--second"></span>
</div>
</div>
<div class="accordion__content" id="content__wrapper">
<p class="acc-text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__item--header">
<h5 class="accordion__title">Brand creation</h5>
<div class="accordion__icon">
<span class="accordion__icon--first"></span>
<span class="accordion__icon--second"></span>
</div>
</div>
<div class="accordion__content" id="content__wrapper">
<p class="acc-text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__item--header">
<h5 class="accordion__title">Design concept</h5>
<div class="accordion__icon">
<span class="accordion__icon--first"></span>
<span class="accordion__icon--second"></span>
</div>
</div>
<div class="accordion__content" id="content__wrapper">
<p class="acc-text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course. Assistance travelling so especially do prosperous appearance mr no celebrated. Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
</div>
</div>
</section>
</div>
cleaned up js to make it more readable:
const accItems = document.querySelectorAll('.accordion__item');
function handleItemClick(e, i) {
if (e) e.preventDefault();
const actives = document.getElementsByClassName("open");
while (actives.length)
actives[0].classList.remove('open');
accItems[i].classList.add("open");
}
accItems.forEach((item, i) =>
item.addEventListener("click", (e) => handleItemClick(e, i))
);
Handling height with just css:
I made icon and content children of .open
.accordion {
width: 63rem;
height: auto;
margin-left: 8rem; }
.accordion__item {
border-top: 1px solid #a8a6a4;
overflow: hidden;
transition: height .5s;
padding-bottom: 1rem; }
.accordion__item:last-child {
border-bottom: 1px solid #a8a6a4; }
.accordion__item--header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2rem 1rem 1rem 1rem;
cursor: pointer; }
.open .accordion__item {
width: 100%; }
.accordion__title {
font-family: 'Lora';
font-size: 2.4rem;
line-height: 1.2;
font-weight: 400;
text-transform: uppercase; }
.accordion__icon {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 2rem;
height: 0;
transition: transform .5s ease; }
.accordion__icon span:first-child {
transform: rotate(90deg) translateX(1px);
width: 1.4rem;
height: .1rem;
background: currentColor; }
.accordion__icon span {
display: block;
width: 1.4rem;
height: .1rem;
background: currentColor;
cursor: pointer; }
open .accordion__icon {
transform: rotate(45deg);
height: 2rem; }
.accordion__content {
font-family: 'Roboto', sans-serif;
font-size: 1.6rem;
line-height: 1.62;
font-weight: 400;
padding: 0 1rem 0 1rem;
height: 0;
transition: height .5s;
overflow: hidden; }
.open .accordion__content {
margin-bottom: 1.2rem;
height: 100%; }
the attached code allows you to click on a div to bring it into "focus" like a modal dialogue box, which is what I wanted it to do. However, I don't want to have to click on the div a second time to "dismiss" it, instead I want to click anywhere outside of the div.
I'm completely stumped at this point, and can't seem to find any good resources for it. Any help would be greatly appreciated!
$('[id^=TestDiv]').click(function(e) {
$('#TestDiv' + this.id.match(/\d+$/)[0]).toggleClass('fullscreen');
$('#overlay').toggle();
});
body {
height: 100vh;
width: 100vh;
}
#Container {
margin: auto;
padding: 0;
display: grid;
background-color: black;
width: 100%;
height: 100%;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas:
"myDiv1 myDiv2"
"myDiv3 myDiv4";
}
div.fullscreen {
position: absolute;
z-index: 9999;
width: 50%;
height: 50%;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
#TestDiv1 {
background: red;
grid-area: myDiv1;
}
#TestDiv2 {
background: green;
grid-area: myDiv2;
}
#TestDiv3 {
background: blue;
grid-area: myDiv3;
}
#TestDiv4 {
background: yellow;
grid-area: myDiv4;
}
div[id^='TestDiv'] {
display: flex;
justify-content: flex-end;
flex-direction: column;
}
span.text {
float: left;
margin-bottom: 2%;
margin-left: 2%;
font-size: 0.5em;
}
span.integer {
float: right;
margin-bottom: 2%;
margin-right: 4%;
font-size: 0.55em;
font-weight: bold;
}
#overlay {
position: fixed;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 2;
}
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<body>
<div id="Container">
<div id="TestDiv1" class="top">
<div>
<span class="text">text content </span>
<span class="integer">1</span>
</div>
</div>
<div id="TestDiv2" class="top">
<div>
<span class="text">text content </span>
<span class="integer">2</span>
</div>
</div>
<div id="TestDiv3" class="bottom">
<div>
<span class="text">text content </span>
<span class="integer">3</span>
</div>
</div>
<div id="TestDiv4" class="bottom">
<div>
<span class="text">text content </span>
<span class="integer">4</span>
</div>
</div>
</div>
<div id="overlay"></div>
</body>
</html>
You are using toggle class, the problem is that just use addClass, do the below code, it will work:
$('[id^=TestDiv]').click(function(e) {
$('#TestDiv' + this.id.match(/\d+$/)[0]).addClass('fullscreen');
$('#overlay').css("display","block");
});
$('#overlay').click(function () {
$('[id^=TestDiv]').removeClass('fullscreen');
$('#overlay').css("display","none");
});
$('[id^=TestDiv]').click(function(e) {
$('#TestDiv' + this.id.match(/\d+$/)[0]).addClass('fullscreen');
$('#overlay').css("display","block");
});
$('#overlay').click(function () {
$('[id^=TestDiv]').removeClass('fullscreen');
$('#overlay').css("display","none");
});
body {
height: 100vh;
width: 100vh;
}
#Container {
margin: auto;
padding: 0;
display: grid;
background-color: black;
width: 100%;
height: 100%;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas:
"myDiv1 myDiv2"
"myDiv3 myDiv4";
}
div.fullscreen {
position: absolute;
z-index: 9999;
width: 50%;
height: 50%;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
#TestDiv1 {
background: red;
grid-area: myDiv1;
}
#TestDiv2 {
background: green;
grid-area: myDiv2;
}
#TestDiv3 {
background: blue;
grid-area: myDiv3;
}
#TestDiv4 {
background: yellow;
grid-area: myDiv4;
}
div[id^='TestDiv'] {
display: flex;
justify-content: flex-end;
flex-direction: column;
}
span.text {
float: left;
margin-bottom: 2%;
margin-left: 2%;
font-size: 0.5em;
}
span.integer {
float: right;
margin-bottom: 2%;
margin-right: 4%;
font-size: 0.55em;
font-weight: bold;
}
#overlay {
position: fixed;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 2;
}
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<body>
<div id="Container">
<div id="TestDiv1" class="top">
<div>
<span class="text">text content </span>
<span class="integer">1</span>
</div>
</div>
<div id="TestDiv2" class="top">
<div>
<span class="text">text content </span>
<span class="integer">2</span>
</div>
</div>
<div id="TestDiv3" class="bottom">
<div>
<span class="text">text content </span>
<span class="integer">3</span>
</div>
</div>
<div id="TestDiv4" class="bottom">
<div>
<span class="text">text content </span>
<span class="integer">4</span>
</div>
</div>
</div>
<div id="overlay"></div>
</body>
</html>
I want to justify one word divided into three rows with CSS and possibly jQuery.
It is in a fluid layout and the word should fill 100% of the parent div.
This is what I want to achieve:
Thanks!
You can do something like this:
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #111;
}
.flex {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
width: 836px;
max-width: 100%;
height: 478px;
margin: 0 auto;
background: #fff;
}
.flex > span {
width: 33.33%;
font-size: 6em;
font-weight: bold;
font-family: sans-serif;
text-align: center;
}
.flex > span:nth-child(8) {
visibility: hidden;
}
<div class="flex">
<span>S</span>
<span>T</span>
<span>R</span>
<span>E</span>
<span>N</span>
<span>G</span>
<span>T</span>
<span>hidden</span>
<span>H</span>
</div>
Got a solution for you:
let word = "Settnrgh";
let list = word.split('');
let firstword = list[0] + list[1] + list[2];
let secondword = list[3] + list[4];
let thirdword = list[5] + list[6] + list[7];
$(".left").text(firstword);
$(".center").text(secondword);
$(".right").text(thirdword)
.parent {
display: grid;
grid-template-columns: auto auto auto auto;
width: 300px;
height: 200px;
background-color: white;
margin: 15px auto;
text-align: center;
}
.parent .text-div {
writing-mode: vertical-rl;
text-orientation: upright;
padding: 0;
margin: 0;
font-size: 80px;
font-weight: bold;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="left text-div">
</div>
<div class="center text-div">
</div>
<div class="right text-div">
</div>
<div></div>
</div>
</div>