I'm trying to create an accordion,it is almost fine but what i cant acheive that everytime when i reload the page the first accordion should be open by default.
second is that im using ajax,after ajax what do i need that the same accordion that i click before the ajax accordion also stay open
Now the first accordion is open what i wanna acheive that when i click the second or any other accordion it should close.
const acc_btns = document.querySelectorAll(".accordion-header");
const acc_contents = document.querySelectorAll(".accordion-body");
acc_btns.forEach((btn) => {
btn.addEventListener("click", (e) => {
acc_contents.forEach((acc) => {
if (
e.target.nextElementSibling !== acc &&
acc.classList.contains("active")
) {
acc.classList.remove("active");
acc_btns.forEach((btn) => btn.classList.remove("active"));
}
});
const panel = btn.nextElementSibling;
panel.classList.toggle("active");
btn.classList.toggle("active");
});
});
window.onclick = (e) => {
if (!e.target.matches(".accordion-header")) {
acc_btns.forEach((btn) => btn.classList.remove("active"));
acc_contents.forEach((acc) => acc.classList.remove("active"));
}
};
.accordion {
width: 450px;
margin: 0 auto;
overflow: hidden;
border-radius: 4px;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
.accordion-header {
display: flex;
justify-content: space-between;
padding: 0.75rem 1rem;
width: 100%;
background: #1f8dd6;
border: none;
outline: none;
border-bottom: 1px solid #54a0ff;
color: #f3f3f3;
cursor: pointer;
}
.accordion-header.active {
background-color: #1070b1;
}
.accordion-header.active i {
transform: rotate(180deg);
transition: all 0.3s ease-in-out;
}
.accordion-body {
padding: 0 1rem;
background-color: #f3f3f3;
max-height: 0;
overflow: hidden;
transition: all 0.3s ease-in-out;
}
.accordion-body.active {
max-height: 10rem;
padding: 1rem;
}
.accordion-body.open {
max-height: 10rem;
padding: 1rem;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />
<div class="accordion">
<div class="accordion-item">
<button class="accordion-header">
<strong>Accordion 1</strong><i class="fas fa-angle-down"></i>
</button>
<div class="accordion-body open">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis atque, voluptates minima quod quisquam et quasi debitis officia non illo harum iure eos reprehenderit quaerat, veritatis asperiores facilis qui neque.
</div>
</div>
<div class="accordion-item">
<button class="accordion-header">
<strong>Accordion 2</strong><i class="fas fa-angle-down"></i>
</button>
<div class="accordion-body">
Dignissimos perspiciatis amet, qui soluta aliquid, ipsa ea alias quidem officiis vel, inventore quod labore aspernatur exercitationem fugit explicabo rerum dolores quo unde assumenda reprehenderit vero temporibus? Magni, nesciunt vero?
</div>
</div>
<div class="accordion-item">
<button class="accordion-header">
<strong>Accordion 3</strong><i class="fas fa-angle-down"></i>
</button>
<div class="accordion-body">
Amet fuga ipsum velit, quae illo doloremque? Id quidem harum placeat porro ipsam, animi voluptatem vel mollitia, quae rerum suscipit modi at consequatur ipsum vitae cum aspernatur itaque non quam?
</div>
</div>
<div class="accordion-item">
<button class="accordion-header">
<strong>Accordion 4</strong><i class="fas fa-angle-down"></i>
</button>
<div class="accordion-body">
Nihil consectetur ipsum nobis eligendi facilis sed corrupti, ab fugit ducimus dolorem rem nulla excepturi impedit sint ea, eveniet provident quos repudiandae a quas reiciendis aut, incidunt corporis? Laboriosam, labore.
</div>
</div>
</div>
Somehow i ll be able to figure it out.
const accordionItemHeaders = document.querySelectorAll(".accordion-item-header");
accordionItemHeaders.forEach(accordionItemHeader => {
accordionItemHeader.addEventListener("click", event => {
// Uncomment in case you only want to allow for the display of only one collapsed item at a time!
const currentlyActiveAccordionItemHeader = document.querySelector(".accordion-item-header.active");
if(currentlyActiveAccordionItemHeader && currentlyActiveAccordionItemHeader!==accordionItemHeader) {
currentlyActiveAccordionItemHeader.classList.toggle("active");
currentlyActiveAccordionItemHeader.nextElementSibling.style.maxHeight = 0;
}
accordionItemHeader.classList.toggle("active");
const accordionItemBody = accordionItemHeader.nextElementSibling;
if(accordionItemHeader.classList.contains("active")) {
accordionItemBody.style.maxHeight = accordionItemBody.scrollHeight + "px";
}
else {
accordionItemBody.style.maxHeight = 0;
}
});
});
accordionItemHeaders[0].click();
#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: #34495e;
color: #fff;
}
h1 {
text-align: center;
margin: 2rem 0;
font-size: 2.5rem;
}
.accordion {
width: 90%;
max-width: 1000px;
margin: 2rem auto;
}
.accordion-item {
background-color: #fff;
color: #111;
margin: 1rem 0;
border-radius: 0.5rem;
box-shadow: 0 2px 5px 0 rgba(0,0,0,0.25);
}
.accordion-item-header {
padding: 0.5rem 3rem 0.5rem 1rem;
min-height: 3.5rem;
line-height: 1.25rem;
font-weight: bold;
display: flex;
align-items: center;
position: relative;
cursor: pointer;
}
.accordion-item-header::after {
content: "\002B";
font-size: 2rem;
position: absolute;
right: 1rem;
}
.accordion-item-header.active::after {
content: "\2212";
}
.accordion-item-body {
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.accordion-item-body-content {
padding: 1rem;
line-height: 1.5rem;
border-top: 1px solid;
border-image: linear-gradient(to right, transparent, #34495e, transparent) 1;
}
#media(max-width:767px) {
html {
font-size: 14px;
}
}
<h1>FAQ</h1>
<div class="accordion">
<div class="accordion-item">
<div class="accordion-item-header">
What is Web Development?
</div>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
Web Development broadly refers to the tasks associated with developing functional websites and applications for the Internet. The web development process includes web design, web content development, client-side/server-side scripting and network security configuration, among other tasks.
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-item-header">
What is HTML?
</div>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
HTML, aka HyperText Markup Language, is the dominant markup language for creating websites and anything that can be viewed in a web browser.
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-item-header">
What are some basic technical skills of a Front-End developer?
</div>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
<ul style="padding-left: 1rem;">
<li>HTML, CSS, JavaScript</li>
<li>Frameworks (CSS and JavaScript frameworks)</li>
<li>Responsive Design</li>
<li>Version Control/Git</li>
<li>Testing/Debugging</li>
<li>Browser Developer Tools</li>
<li>Web Performance</li>
<li>SEO (Search Engine Optimization)</li>
<!-- <li>CSS Preprocessing</li> -->
<li>Command Line</li>
<li>CMS (Content Management System)</li>
</ul>
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-item-header">
What is HTTP?
</div>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
HTTP, aka HyperText Transfer Protocol, is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands.
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-item-header">
What is CORS?
</div>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
CORS, aka Cross-Origin Resource Sharing, is a mechanism that enables many resources (e.g. images, stylesheets, scripts, fonts) on a web page to be requested from another domain outside the domain from which the resource originated.
</div>
</div>
</div>
</div>
Related
First of all, sorry for my bad English, hope you understand me.
Second, I started programing yesterday, wathed lots of tutorials and didn't found anything, probably I am just dumb.
Just begun a new html project, I started with a colored bar for the top of the website, then linked an image to the main html project, something like Home navigation bar image idk.
Now the problem is, I want to overlap the already linked to main html to colored bar (https://i.stack.imgur.com/iVqm3.png)
Bluebar CSS code:
.upperblue {
width: 100%;
background-color: rgb(71, 103, 245);
height: 100px;
position: relative;
}
Image HTML and CSS
<p id="homeimage">
<a href="/index.html">
<img `src="https://lh3.googleusercontent.com/EiXgCES3j3b98a6ADBoU37yzcAO1shECNmOzbCZn2HYcUBPW4xiFmCHsXCy-A`mWGTn5ySEU3U-Rpq2H_NrXjjuSg-Qrr3m74XSVF0y9VD6ayXRy2zYaTVqONCjlneaMfsb352Z0S=w2400" height="185"
width="426">
</a>
</p>
I made a example here, i import some fonts , a bunch of CSS selectors . Start studing , ctrl + shift + i on chrome was a good tool for you test it all !!!
<!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">
<title>Document</title>
<!-- IMPORTING GOOGLE MATERIAL FONT ICONS (https://fonts.google.com/icons) -->
<!--
How to use it :
Place the .material-symbols-outlined class in some element that have text (div,span,p,li,table,footer,header,etc..)
I think that it only dont work like inputs, textarea elements
Found some icon : [eg: https://fonts.google.com/icons?icon.query=menu]
Click and copy the example that show right in the page .
example :
<span class="material-symbols-outlined">menu</span>
-->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD#48,400,0,0" />
<!-- IMPORTING POPPINS FONT FROM GOOGLE FONTS (https://fonts.google.com/) -->
<!--
How to use it :
On the google page , well on the up-right side on the page have an button : 'View selected families'
(Its a icon actually, you will not see the text XD)
Click there and you will see how to use each font
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght#0,300;0,400;0,500;1,300;1,400;1,500&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
text-decoration: none;
list-style: none;
outline: none;
font-family: 'system-ui', 'sans-serif';
font-weight: 300;
transition: .3s linear 0s all;
}
h1 , h2 ,h3 , h4, h5 {
font-weight: 500;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.8rem;
}
h3 {
font-size: 1.6rem;
}
h4 {
font-size: 1.4rem;
}
h5 {
font-size: 1.2rem;
}
h6 {
font-size: 1.1rem;
}
body {
margin: 0;
}
main {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
/* NOTE THAT HERE WE USE 2REM IN THE SIZE OF ASIDE ICONS , BECAUSE IS THEIR SIZE ON .header-icon ;D */
main > header {
flex: 0 0 50px;
display: grid;
grid-template-columns: 2rem auto 2rem;
justify-items: center;
align-items: center;
background: linear-gradient(45deg, #e7e7e7, #b9b9b9);
border-bottom: 1px solid #b5b5b5;
}
main > header > div:nth-child(1) {
margin: 0;
}
main > header > div:nth-child(2) {
margin: 0;
}
main > header > div:nth-child(3) {
margin: 0;
}
main > section {
flex: 1 0 auto;
padding: 10px;
background: #f1f1f1;
}
main > section > div:nth-child(1) {
width: 100%;
height: 100%;
border-radius: 10px;
padding: 10px;
background: white;
}
main > section > div:nth-child(1) > p {
margin-top: 10px;
}
main > footer {
flex: 0 0 10vmin;
display: grid;
grid-template-columns: auto auto auto;
justify-items: center;
border-top: 1px solid #ffffff82;
background: #e7e7e7;
}
main > footer > div:nth-child(1) {
margin: 0;
}
main > footer > div:nth-child(2) {
margin: 0;
}
main > footer > div:nth-child(3) {
margin: 0;
}
/* SEE THAT , WE CAN TURN OUR ICON BIGGER SETTING A FONT-SIZE PROPERTY !! ALSO OTHER OPTIONS*/
.header-icon {
font-size: 2rem;
}
/* ALSO NOTE THE CSS SELECTORS IM USING ...*/
a.normal {
color: black;
text-shadow: 0px 0px 1px black;
transition: .1s linear 0s text-shadow;
}
a.normal:hover {
text-shadow: 0px 0px 2px black;
}
a.button {
display: block;
border-radius: 6px;
color: white;
font-weight: 500;
text-align: center;
text-shadow: 1px 1px grey;
border: 1px solid gray;
background: #c1c1c1;
padding: 4px 14px;
transform: translate(0px, 0px);
transition: .1s linear 0s all;
}
a.button:hover {
transform: translate(1px, -1px);
box-shadow: 0px 0px 3px -1px #00000069;
}
button.sucess {
border-radius: 6px;
background: green;
color: white;
padding: 2px 10px;
border: 0;
}
</style>
</head>
<body>
<main>
<header>
<!-- Using google materials icons font with a custom class !! the default class need to be here !!-->
<div><span class="header-icon material-symbols-outlined">menu</span></div>
<div><h3>LOGO</h3></div>
<div><span class="header-icon material-symbols-outlined">toggle_on</span></div>
</header>
<section>
<div>
<h5>Main content</h5>
<p>
Lorem ipsum dolor sit amet. Est internos galisum ut adipisci voluptas qui ipsum quisquam aut dicta assumenda ut iste velit sit quia quasi id sequi fugiat. Et autem veniam eum alias optio et quas tenetur aut aperiam dolorem est soluta laboriosam non cupiditate officiis qui neque consequatur. Est ipsam numquam sit nobis iure quo assumenda quidem ut voluptatem accusamus rem consequatur nesciunt eum deserunt accusamus ad eaque explicabo. Hic quam facilis et dolorum galisum ut dolorum aliquid ad dolorem sapiente in aspernatur nemo sed veritatis maxime non dolorem quisquam.
A nemo voluptas a repellat iste ut harum dolor aut neque dolorum nam voluptatibus amet quo repellat autem et quasi nemo. Vel temporibus adipisci nam nesciunt quidem aut voluptas placeat in accusantium sunt ut laborum illum a esse quia aut doloribus molestiae. Ut sint nemo non odit autem ea optio repudiandae et sequi nostrum.
Aut culpa cumque qui repellendus earum aut dolores labore et velit ullam eum ratione culpa ut nemo repellat in dolorum eius. Et cupiditate maxime eos officiis animi eos architecto quam aut ipsa inventore. Ad quos sint ex cumque quis eum officiis harum qui culpa soluta eos optio omnis ut voluptatem accusamus aut ratione fugit. Et inventore vero ab eligendi debitis sit tempore dicta nam voluptatem nostrum.
</p>
Link
Link
<button class="sucess">Button</button>
<textarea name="" id="" cols="30" rows="10"></textarea>
<input type="checkbox" name="" id="myCheckbox"><label for="myCheckbox"></label>
<input type="date" name="" id="">
<input type="file" name="" id="">
<input type="number" name="" id="">
<input type="password" name="" id="">
<input type="search" name="" id="">
<input type="radio" name="" id="">
</div>
</section>
<footer>
<div>FOOTER 1</div>
<div>FOOTER 2</div>
<div>FOOTER 3</div>
</footer>
</main>
</body>
<script>
let modalLinks = document.querySelectorAll('a[data-modal]');
modalLinks.forEach(link =>
link.addEventListener('click', function() {
openModal(link)
})
);
function openModal(e) {
const el = e.closest('.card');
const modal = el.querySelector('[modal]');
modal.setAttribute('modal', 'active');
}
function closeModal(e) {
const modal = e.closest('[modal]');
modal.setAttribute('modal', '');
}
</script>
</html>
CSS SELECTORS // HTML TUTORIAL
I suspect the issue is with the line const active = document.querySelector(".accordion.active"); in JS code below. It doesn't seem to be retrieving that element. Could you please help me debug it? Or should I use something else instead of querySelector? It is also found that this.classList.add("active"); is not adding the "active class" to the accordion element when it is clicked.
document.addEventListener("DOMContentLoaded", function(event) {
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
const active = document.querySelector(".accordion.active");
console.log(active);
if (active) {
active.classList.remove('active'); // remove active class from accordions
}
this.classList.add("active"); // add it to this one
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
});
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 1.5rem;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active,
.accordion:hover {
background-color: #ccc;
}
.panel {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
background: red;
}
.active+.panel {
display: block;
}
<div class="row">
<button class="accordion"><div class="question"><?php echo $label; ?></div></button>
<div class="panel">
<p class="answer">
<?php echo $answer; ?>
</p>
</br>
</div>
</div>
<div class="row">
<button class="accordion"><div class="question"><?php echo $label; ?></div></button>
<div class="panel">
<p class="answer">
<?php echo $answer; ?>
</p>
</br>
</div>
</div>
You probably should re-think your approach since in your case, you will not even be in need of JavaScript - for the basics! If you need a custom accordion, then you can use JavaScript, and I try to explain to you how.
What you need is a clean HTML with <details> and <summary>. See this example:
<details class="accordion">
<summary>Question 1</summary>
<strong>Answer:</strong> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus molestias ex, rem ducimus quibusdam nihil aliquam corporis id sint aperiam dolores, accusantium culpa adipisci similique doloremque eius reiciendis. Veniam, perferendis.
</details>
<details class="accordion">
<summary>Question 2</summary>
<strong>Answer:</strong> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laborum doloribus tenetur tempore esse consectetur incidunt, distinctio eaque suscipit error fugit tempora, quas accusantium recusandae autem voluptatibus qui quasi molestiae odit.
</details>
With CSS you can style it the way you want it. If you want to remove the arrows, you can try it with details > summary { list-style: none; }. Also, you can use any other characters. In this example, we use the signs + (plus) and when the accordion is already opened, it should be - (minus.):
details > summary {
list-style-type: '+ ';
}
details[open] > summary {
list-style-type: "- ";
}
details > summary::-webkit-details-marker {
display: none;
}
summary {
background-color: #ccc;
}
<details class="accordion">
<summary>Question 1</summary>
<strong>Answer:</strong> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus molestias ex, rem ducimus quibusdam nihil aliquam corporis id sint aperiam dolores, accusantium culpa adipisci similique doloremque eius reiciendis. Veniam, perferendis.
</details>
<details class="accordion">
<summary>Question 2</summary>
<strong>Answer:</strong> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laborum doloribus tenetur tempore esse consectetur incidunt, distinctio eaque suscipit error fugit tempora, quas accusantium recusandae autem voluptatibus qui quasi molestiae odit.
</details>
As you can see, all open questions remain open. If you want only the active question to stay open, you may use JavaScript.
document.querySelectorAll('details').forEach((accordion) => {
accordion.addEventListener('click', (e) => {
document.querySelectorAll('details').forEach((event) => {
if (accordion !== event) {
event.removeAttribute('open');
}
});
});
});
details > summary {
list-style-type: '+ ';
}
details[open] > summary {
list-style-type: "- ";
}
details > summary::-webkit-details-marker {
display: none;
}
summary {
background-color: #ccc;
}
<details class="accordion">
<summary>Question 1</summary>
<strong>Answer:</strong> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus molestias ex, rem ducimus quibusdam nihil aliquam corporis id sint aperiam dolores, accusantium culpa adipisci similique doloremque eius reiciendis. Veniam, perferendis.
</details>
<details class="accordion">
<summary>Question 2</summary>
<strong>Answer:</strong> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laborum doloribus tenetur tempore esse consectetur incidunt, distinctio eaque suscipit error fugit tempora, quas accusantium recusandae autem voluptatibus qui quasi molestiae odit.
</details>
You don't need to manipulate the display of the active element, your CSS already does that. Also you should not both add and toggle the active class on this - that is equivalent to removing it.
I've also added an if statement to check if the clicked element is already active so that collapsing it again works.
document.addEventListener("DOMContentLoaded", function(event) {
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
const active = document.querySelector(".accordion.active");
console.log(active);
if (active) {
active.classList.remove('active'); // remove active class from accordions
}
if (active !== this) {
this.classList.toggle("active");
}
});
}
});
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 1.5rem;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active,
.accordion:hover {
background-color: #ccc;
}
.panel {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
background: red;
}
.active+.panel {
display: block;
}
<div class="row">
<button class="accordion"><div class="question">Label1</div></button>
<div class="panel">
<p class="answer">
Answer goes here
</p>
</div>
</div>
<div class="row">
<button class="accordion"><div class="question">Label2</div></button>
<div class="panel">
<p class="answer">
Second answer
</p>
</div>
</div>
//
this.classList.add("active"); is not adding the "active class" to the accordion element when it is clicked.
//
It is adding. But immediately the class is toggled, so it is removed. That toogle class line is commented.
I have added the css for green color to active accordion, which you can see after moving the cursor off the accordion element.
document.addEventListener("DOMContentLoaded", function(event) {
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
const active = document.querySelector(".accordion.active");
console.log(active);
if (active) {
active.classList.remove('active'); // remove active class from accordions
// this is if other heading is clicked
}
// this.classList.toggle("active"); // not needed
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
this.classList.remove("active"); // remove it to this one
panel.style.display = "none";
} else {
this.classList.add("active"); // add it to this one
panel.style.display = "block";
}
});
}
});
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 1.5rem;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.accordion.active{
background:green;
}
.active,
.accordion:hover {
background-color: #ccc;
}
.panel {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
background: red;
}
.active+.panel {
display: block;
}
<div class="row">
<button class="accordion"><div class="question">Accordion Label 1</div></button>
<div class="panel">
<p class="answer">
Accordion Answer 1
</p>
</br>
</div>
</div>
<div class="row">
<button class="accordion"><div class="question">Accordion Label 2</div></button>
<div class="panel">
<p class="answer">
Accordion Answer 1
</p>
</br>
</div>
</div>
I always prefer delegation.
I am wrapping the accordion in a DIV and delegate the clicks from there
No need to show / hide the panes since the CSS .active+.panel { display: block; } does that for us
document.addEventListener("DOMContentLoaded", function(event) { // when page has loaded
const acc = document.getElementById("accodionContainer"); // the container
const buttons = acc.querySelectorAll(".accordion"); // the buttons in the container
acc.addEventListener("click", e => { // any click in the container
const currentButton = e.target.closest(".accordion"); // you have stuff inside the relevant element, make sure we use the .accordion element
if (!currentButton) return // something not a (in a ) button was clicked
// toggle clicked button, remove active from the rest
buttons.forEach(acc => acc.classList[acc === currentButton ? "toggle" : "remove"]("active"));
});
});
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 1.5rem;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active,
.accordion:hover {
background-color: #ccc;
}
.panel {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
.active+.panel {
display: block;
}
.accordion.active span::after {
content: "➖";
}
.accordion span::after {
content: "➕";
}
<div id="accodionContainer">
<div class="row">
<button class="accordion"><span></span> Question 1</button>
<div class="panel">
<p class="answer">
Answer 1
</p>
</div>
</div>
<div class="row">
<button class="accordion"><span></span> Question 2</button>
<div class="panel">
<p class="answer">
Answer 2
</p>
</div>
</div>
</div>
The below answer is not related to the question, but it is good to have the html hierarchy.
const accordionToggles = document.querySelectorAll('.accordion-toggle');
const accordionItems = document.querySelectorAll('.accordion-item');
const flush = true; // set to true,if only one accordion bodyto be open. set false, to open multiple accordion-body
accordionToggles.forEach((toggleBtn) => {
toggleBtn.addEventListener('click', (event) => {
const accordionItem = event.target.closest(".accordion-item");
if (!flush) {
accordionItem.classList.toggle('active');
return;
}
if (accordionItem.classList.contains('active')) {
accordionItem.classList.toggle('active');
return;
}
accordionItems.forEach((item) => {
item.classList.remove('active');
})
accordionItem.classList.add('active');
})
});
.accordion {}
.accordion-item {
border: 1px solid gray;
}
.accordion-item+.accordion-item {
border-top: none;
}
.accordion-header {}
.accordion-toggle {
width: 100%;
border: none;
height: 30px;
border-bottom: 1px solid black;
text-align: left;
position: relative;
}
.accordion-toggle:after {
position: absolute;
top: 5px;
right: 5px;
font-size: 18px;
}
.accordion-body {
padding: 10px;
display: none;
}
.accordion-item.active .accordion-body {
display: block;
}
.accordion-item .accordion-toggle:after {
content: "+"
}
.accordion-item.active .accordion-toggle:after {
content: "-"
}
<div class="accordion">
<div class="accordion-item">
<div class="accordion-header">
<button class="accordion-toggle">Title 1</button>
</div>
<div class="accordion-body">
Accordion Content 1
</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<button class="accordion-toggle">Title 2</button>
</div>
<div class="accordion-body">
Accordion Content 2
</div>
</div>
</div>
I'm basically trying to implement a popup that blurs the background and makes it so that the user can't touch the buttons and other components in the background.
You can disable the whole div by using css.
#div-id{
pointer-events: none;
}
This will disable all the elements inside the div.
If you want the blur effect you can add opacity: 0.2; to the div css.
You can add this class on your main element container to blur the whole background
.blured {
filter: blur(2px);
-webkit-filter: blur(2px);
}
And add pointer-events: none; on your modal or popup
By using css backdrop-filter property and pointer-events you can achieve what u need .. see example below
* {
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 1rem;
}
body {
margin: 0;
padding: 0;
}
.disabled{
pointer-events: none;
color : grey;
}
.modal {
position: fixed;
inset: 0;
isolation: isolate;
background-color: rgba(19, 128, 119, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.popup {
position: absolute;
z-index: 1;
width: 400px;
background-color: black;
color: white;
padding: 1rem;
}
.blur{
position: absolute;
inset: 0;
z-index: -1;
backdrop-filter: blur(0.2rem);
}
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid dolorum illo, non incidunt earum natus neque architecto a autem maxime voluptatibus tempora minima, provident expedita quidem cumque ab. Error, tenetur?
</div>
<div class="modal">
<div class="blur"></div>
<div class="popup">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi quam architecto minima nihil aliquid quis unde
illo mollitia iure. Quia.
<br /> <br /> <br />
<a href="#" class="disabled">
I am a disabled link !
</a>
</div>
</div>
References : pointer-events and backdrop-filter.
Note: Also remember using pointer events doesn't means you can't use keyboard to focus.. To prevent keyboard tab focus you might need to use tabindex attribute on the link
body{
position:relative;
///rest of your style
}
.backdrop {//create a div inside body // <div class".backdrop"></div>
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 1;
backdrop-filter: blur(5px);
}
.backdrop:enabled { //here we have disable all pevnts
pointer-events: none;
}
This is just a theory based question. I am fairly new to programming and was wondering why this happens within HTML.
I'm making an HTML based resume where when I have a mouse pointer hover over my ul it will activate a function such as this.
$("li#about").hover(function(){
$("#content1").toggle();
});
The Issue While hovering over my selector when my #content was no longer hidden, my margins between my header and ul box would cause jittering within the page.
I went from:
<header>
<h1>Ryan Anderson</h1>
<h3>Developer</h3>
</header>
<body>
<div class="clearfix">
<div class="column">
<ul>
<li id="about"> <span>About Me</span> </li>
<li id='education'> <span>Education</span></li>
<li id='info'> <span>Experience</span></li>
<li id='ref'> <span>References</span></li>
</ul>
<div class="clr"></div>
</div>
to:
<header>
<h1>Ryan Anderson</h1>
<h3>Developer</h3>
<body>
<div class="clearfix">
<div class="column">
<ul>
<li id="about"> <span>About Me</span> </li>
<li id='education'> <span>Education</span></li>
<li id='info'> <span>Experience</span></li>
<li id='ref'> <span>References</span></li>
</ul>
<div class="clr"></div>
</div>
</header>
My questions:
What was the reason for the sporadic jittering and how did wrapping my ul within the header tag prevent this from occurring?
Is my solution proper etiquette? If not, what would you recommend?
If you have any good recommendations for coding etiquette please post links in comments.
sing-song Being new, I know my code must look like poo. Regardless I added a fiddle for you.
Thanks for the read! I apologize in advance for the ugly code. I posted a JSFiddle as well, figured it would help any other newbies to conceptualize what i'm asking. This fiddle is without correction Just change the closing header tag to where I specified above to see the results.
My Fiddle: https://jsfiddle.net/dgibbins1/cwn6ws02/4/
header{
background: #5a4c1c;
border-radius:10px;
opacity:0.85;
padding:1px 0;
}
h1{
margin: 0 0;
color: white;
padding-left:10px;
}
h3{
color:#dad6c7;
padding-left: 31px;
}
body{
background:#dad6c7;
}
ul{
list-style-type:none;
padding: 0px 15px;
margin: 50px 0;
}
span{
color:white;
}
li{
font-family:Helvetica;
}
div.column{
border-style:solid;
border-color:rgba(56,43,3,1);
}
#content1, #content2,#content3,#content4{
opacity:1;
display: none;
padding: 3px auto;
}
.clear-fix{
}
.column li{
padding:4px 0 4px 0;
margin-top:30px;
margin-bottom:30px;
font-family:'Oswald', sans-serif;
text-align: center;
font-size: 20px;
overflow: hidden;
}
.clr{
clear:both;
font-size:0;
}
.column{
float:left;
background-size: 220px 220px;
background:#5a4c1c;
padding: 5px 2px;
margin: 10px 10px 0 0;
opacity:0.5;
width: 15%;
border-radius:20px;
}
.column li:hover{
background: black;
border-radius:20px;
}
.content{
color:#5a4c1c;
font-weight: bold;
font-family: helvetica;
width:85%;
}
.footer{
text-align: center;
background:#5a4c1c;
color: white;
padding: 10px 0;
opacity: 0.5;
margin-top: 30%;
border-radius:10px;
}
<!DOCTYPE html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link href="/normalize.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet">
<title> Resume: Ryan Anderson</title>
</head>
<header>
<h1>Ryan Anderson</h1>
<h3>Developer</h3>
</header>
<body>
<div class="clearfix">
<div class="column">
<ul>
<li id="about"> <span>About Me</span> </li>
<li id='education'> <span>Education</span></li>
<li id='info'> <span>Experience</span></li>
<li id='ref'> <span>References</span></li>
</ul>
<div class="clr"></div>
</div>
<div id="content1" class="content show-description">
<p>About me <br />
<small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi non quis exercitationem culpa nesciunt nihil aut nostrum explicabo reprehenderit optio amet ab temporibus asperiores quasi cupiditate. Voluptatum ducimus voluptates voluptas?</small>
</p>
</div>
<div id="content2" class="content" >
<p>Education <br />
<small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi non quis exercitationem culpa nesciunt nihil aut nostrum explicabo reprehenderit optio amet ab temporibus asperiores quasi cupiditate. Voluptatum ducimus voluptates voluptas?</small>
</p>
</div>
<div id="content3" class="content">
<p>Experience <br />
<small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi non quis exercitationem culpa nesciunt nihil aut nostrum explicabo reprehenderit optio amet ab temporibus asperiores quasi cupiditate. Voluptatum ducimus voluptates voluptas?</small>
</p>
</div>
<div id="content4" class="content">
<p>References <br />
Paul Garven (co-worker): (780)-828-1111<br />
Paul CWC (owner of CWWC): (416)- 721-1111<br />
Someone at Bitmaker: (416-967-11-11
</p>
</div>
</div>
<div class="footer">
<p>Contact <br/>
<small>mobile: (647)-333-8723 <br/>
e-mail: hotmail#gmail.com</small>
</p>
</div>
<script>
$("li#about").hover(function(){
$("#content1").toggle();
});
$("li#education").hover(function() {
$("#content2").toggle();
});
$("li#info").hover(function() {
$("#content3").toggle();
});
$("li#ref").hover(function() {
$("#content4").toggle();
});
</script>
</body>
You have an error in your CSS.
#content1, #content2,#content3,#content4{
opacity:1;
display: none;
padding: 3px auto; <--
}
padding doesn't take the value auto.
Switch it to padding-top:3px; padding-bottom:3px; and the jittering will stop.
Link: Working proof
you have some issues with your markup
some of your nesting is applied incorrectly.
in fact i am not even sure i found all the errors
some of your css is incorrect as well
$("li#about").hover(function() {
$("#content1").toggle();
});
$("li#education").hover(function() {
$("#content2").toggle();
});
$("li#info").hover(function() {
$("#content3").toggle();
});
$("li#ref").hover(function() {
$("#content4").toggle();})
header {
background: #5a4c1c;
border-radius: 10px;
opacity: 0.85;
padding: 1px 0;
}
.minheight {
min-height: 200px;
}
h1 {
margin: 0 0;
color: white;
padding-left: 10px;
}
h3 {
color: #dad6c7;
padding-left: 31px;
}
body {
background: #dad6c7;
}
ul {
list-style-type: none;
padding: 0px 15px;
margin: 50px 0;
}
span {
color: white;
}
li {
font-family: Helvetica;
}
div.column {
border-style: solid;
border-color: rgba(56, 43, 3, 1);
}
#content1,
#content2,
#content3,
#content4 {
opacity: 1;
display: none;
padding: 3px auto;
}
.clear-fix {
}
.column li {
padding: 4px 0 4px 0;
margin-top: 30px;
margin-bottom: 30px;
font-family: 'Oswald', sans-serif;
text-align: center;
font-size: 20px;
overflow: hidden;
}
.clr {
clear: both;
font-size: 0;
}
.column {
float: left;
background-size: 220px 220px;
background: #5a4c1c;
padding: 5px 2px;
margin: 10px 10px 10px 0;
opacity: 0.5;
width: 20%;
min-width:134px;
border-radius: 20px;
}
.column li:hover{
background: black;
border-radius: 20px;
}
.content {
color: #5a4c1c;
font-weight: bold;
font-family: helvetica;
width: 85%;
}
.footer {
text-align: center;
background: #5a4c1c;
color: white;
padding: 10px 0;
opacity: 0.5;
margin-top: 30%;
border-radius: 10px;
clear:both;
}
<link href="//normalize-css.googlecode.com/svn/trunk/normalize.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<h1>Ryan Anderson</h1>
<h3>Developer</h3>
<div class="clearfix">
<div class="column">
<ul>
<li id="about"> <span>About Me</span>
</li>
<li id='education'> <span>Education</span>
</li>
<li id='info'> <span>Experience</span>
</li>
<li id='ref'> <span>References</span>
</li>
</ul>
<div class="clr"></div>
</div>
<div id="content1" class="content show-description">
<p>About me
<br />
<small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi non quis exercitationem culpa nesciunt nihil aut nostrum explicabo reprehenderit optio amet ab temporibus asperiores quasi cupiditate. Voluptatum ducimus voluptates voluptas?</small>
</p>
</div>
<div id="content2" class="content">
<p>Education
<br />
<small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi non quis exercitationem culpa nesciunt nihil aut nostrum explicabo reprehenderit optio amet ab temporibus asperiores quasi cupiditate. Voluptatum ducimus voluptates voluptas?</small>
</p>
</div>
<div id="content3" class="content">
<p>Experience
<br />
<small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi non quis exercitationem culpa nesciunt nihil aut nostrum explicabo reprehenderit optio amet ab temporibus asperiores quasi cupiditate. Voluptatum ducimus voluptates voluptas?</small>
</p>
</div>
<div id="content4" class="content">
<p>References
<br />Paul Garven (co-worker): (780)-828-1111
<br />Paul CWC (owner of CWWC): (416)- 721-1111
<br />Someone at Bitmaker: (416-967-11-11
</p>
</div>
</div>
<div class="footer">
<p>Contact
<br/>
<small>mobile: (647)-333-8723 <br/>
e-mail: hotmail#gmail.com</small>
</p>
</div>
</body>
I have some content in my post. But I want to hide it until I click to a link in this post. I have yet to build this site, but I will say my idea.
The first Heading
The second Heading
The third Heading
The fourth Heading
/* The content following are hidden Until I clicked to a link above. /
/ Content is available wrapped in a div tag, do not loaded from another site. */
Content 1 will be show only click to "1. The first Heading"
Content 2 will be show only click to "2. The second Heading"
Content 3 will be show only click to "3. The third Heading"
Content 4 will be show only click to "4. The fourth Heading"
Can use CSS or Ajax / jQuery to create the effect?
You could do it using the following jquery code:
$(document).ready(function(){
$("#hide").click(function(){
$("p").hide();
});
$("#show").click(function(){
$("p").show();
});
});
Here is the complete demo how you can hide and show the element by click event.
I have made a pure css accordion that achieves the same functionality.Checkout the following link at codepen
HTML:
<div class="container">
<ul>
<li>What is java Programming Language?
<div class="acc-content" id="first">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nemo harum vel aliquid. Quaerat soluta sed aperiam temporibus ipsum obcaecati porro commodi error unde reprehenderit ipsa, dolore id, totam dolores, quae.
</p>
</div></li>
<li>How is javascript different from java?
<div class="acc-content" id="second">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nemo harum vel aliquid. Quaerat soluta sed aperiam temporibus ipsum obcaecati porro commodi error unde reprehenderit ipsa, dolore id, totam dolores, quae
</p>
</div></li>
<li>Other front end technologies
<div class="acc-content" id="third">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nemo harum vel aliquid. Quaerat soluta sed aperiam temporibus ipsum obcaecati porro commodi error unde reprehenderit ipsa, dolore id, totam dolores, quae
</p>
</div></li>
</ul>
</div>
CSS:
*{
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body{
padding-top: 50px;
font : 1em cursive;
background-image: url(http://www.mrwallpaper.com/wallpapers/fantasy-winter-scenery-1920x1200.jpg);
background-size: cover;
color: #fff;
overflow-x: hidden;
}
.container{
position: relative;
width: 100%;
max-width: 500px;
margin: auto;
padding: 5px;
}
ul{
margin: 0;
padding: 0;
list-style: none;
}
.acc-header{
display: block;
cursor: pointer;
padding: 10px 20px;
background-color: #000;
opacity: 0.7;
text-transform: uppercase;
text-decoration: none;
text-align: center;
color: #fff;
border-radius: 2px;
margin-bottom: 10px 0 0 10px;
}
.acc-content p{
margin: 10px;
}
.acc-content{
background-color: #222;
opacity: 0.7;
height: 0px;
overflow: hidden;
-webkit-transition: height 0.4s ease;
-moz-transition: height 0.4s ease;
-ms-transition: height 0.4s ease;
-o-transition: height 0.4s ease;
transition: height 0.4s ease;
}
.acc-content:target{
height: 170px;
}
With jQuery it can be pretty easy. By default you hide .content divs with CSS and display the corresponding one on heading click. Consider bellow example.
var $content = $('.content');
$('h2').click(function() {
$content.removeClass('show')
.filter('.content-' + $(this).data('content'))
.addClass('show');
});
.content {
display: none;
padding: 5px;
background: #EEE;
}
.content.show {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2 data-content="1">Heading #1</h2>
<h2 data-content="2">Heading #2</h2>
<h2 data-content="3">Heading #3</h2>
<div class="content content-1">Content #1</div>
<div class="content content-2">Content #2</div>
<div class="content content-3">Content #3</div>
If I understand well, I would recommend to load from ajax the content on first click and then hide it instead of deleting the toggled panel and retrieve it again from AJAX each time (so that there is no wait on each click and less requests).
So here's a way of doing it:
$('.header').click(function()
{
var clickedHeader= $(this);
if (clickedHeader.next().is('.toggle:visible'))
{
clickedHeader.next().slideDown(800);
}
else if (clickedHeader.next().is('.toggle:hidden'))
{
clickedHeader.next().slideUp(800);
}
else
{
$.get(url, data, function(data)
{
// First do some treatment if needed...
clickedHeader.after('<div class="toggle" style="display:none;">'+data+'</div>');
clickedHeader.next().slideDown(800);
});
}
});
This will work if you have HTML like this for ex.
<div class="header">First header</div>
<div class="header">Second header</div>
<div class="header">Third header</div>
<div class="header">Fourth header</div>
and after each header you would toggle a div that has class '.toggle'.
Hope it helps.