Accordion Component With Only CSS [No Javascript]
Tags: css, ui, design, html
Published: 2023-09-19 07:37:53

Hi Web Dev's, 👋 We all know how much good web dev is that's why we are doing this. When it comes to web design it's a very important skill you must have. Creating component using core technologies improves your core skills.
Today in this tutorial I'll sharing **_how I created a simple accordion component with Neomorphism design using only Html and CSS._**


Without wasting time, Let's start -

If you are not familiar with what is accordion then checkout this - [MUI Accordion Component](https://mui.com/material-ui/react-accordion/).

For creating the accordion component we need the basic skeleton first our **HTML**


```
<!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="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
  

  <title>Document</title>
</head>
<body>
  <main class="container">
  <div class="accordion">
    <div class="accordion__head">
    <p class="accordion__title">
      Hey there, I am a accordion title      
    </p>
    <div class="accordion__opener"> 
        <input type="checkbox" id="accordion-opener-input" checked>
      <label for="accordion-opener-input">
          <i class="fa-solid fa-caret-up"></i>
          </label>
    </div>
    </div>
     <div class="accordion__description">
      <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. </p>
    </div>
    </div>
    
  </div>
  </main>
  <script src="https://kit.fontawesome.com/31571152d6.js" crossorigin="anonymous"></script>
</body>
</html>
```

_We'll not go in details of html structure. Here I used the good old trick to check for the open and close state like we do for switch. I have used the input type checkbox to toggle between open and closed states._

Now let's come to the heart of the web. **The CSS Style.**

```
*{
  margin:0;
  padding:0;
}
*,*::before,*::after{
  box-sizing:border-box;
}
img {
  max-width:100%;
  display:block;
}

:root{
  --clr-primary: #d9d9d9;
  --clr-secondary:#fafafa;
  --clr-clear:#ffffff;
  --clr-grey: #6d6d6d;
  --clr-dark:#1e1e1e;
  --ff-base:'Inter', sans-serif;
  
  --fw-regular: 400;
  
  --fs-200:0.875rem;
  --fs-300:1rem;
  --fs-400:1.125rem;
  --fs-500:1.375rem;
  --fs-600:1.75rem;
  --fs-700:3.25rem;
    
}
html{
  color-scheme: light dark;
}
body{
  font-family:var(--ff-base);
  font-size: var(--fs-300);
  line-height:1.5;
  font-weight: var(--fw-regular);
  height:100vh;
  
}
main {
  display:flex;
  justify-content:center;
  align-items:flex-start;
  height:80%;
  padding-top:4rem;
}
.accordion{
  font-size:inherit;
  padding: 1.2em 2em;
  border-radius:.5em;
  max-width:30rem;
  width:100%;
  box-shadow:  10px 10px 30px #000000,
             -10px -10px 30px #1f1f1f;
  transition: box-shadow .5s ease;
}
.accordion:hover{
  box-shadow:  10px 10px 20px #000000,
             -10px -10px 20px #1f1f1f;
}
.accordion__head{
  display:flex;
  justify-content:space-between;
}
.accordion__title{
  display:inline-block;
}
.accordion__opener{
  display:inline;
  margin-left:.5rem;
  
}
.accordion__opener input{
  display:none;
}
.accordion__opener label{
  cursor:pointer;
}
.accordion__opener label i {
/*   transform: rotate(90deg); */
  display:inline-block;
  transition: transform .4s ease;
  
}
.accordion__description{
  overflow:hidden;
  margin-top:0;
  display:grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .5s, margin-top .5s; 
  color: var(--clr-grey);

}
.accordion__description p {
  overflow: hidden;
}
.accordion__opener input:checked + label i{
  transform: rotate(180deg);
}
.accordion__head:has(.accordion__opener input:checked) + :is(.accordion__description){
  margin-top: 10px;
  grid-template-rows: 1fr;
}

@media (prefers-color-scheme: light){
  body{
    background: #e0e0e0;
  }
  .accordion{
    background: #e0e0e0;
box-shadow:  20px 20px 60px #bebebe,
             -20px -20px 60px #ffffff;
  }
  .accordion:hover{
    background: #e0e0e0;
    box-shadow:  20px 20px 30px #bebebe,
             -20px -20px 30px #ffffff;
  }
}
```

Here I have used the basic Css normalization for removing default styling of few things. Also declared few variables for reusing properties and making our life easier.😆

**Now what's different here?** _In most of the tutorial for creating the css only accordion, you'll find out that they we mentioning the **max-width** property. Which is not good sometime when you don't know how much height your content can have. 
In this I have used the **css grid trick**. With **css grid-template-row**, I am manipulating the height and achieving the same functionality without mentioning **max-width** on the description. You can use **max-width** trick as well if your use case requires that._

Also I have used the **BEM Naming convention for Css ** which is a standard for writing the Css classes.

For generating the Neomorphism styles I have used a Neomorphism style generator. Link is in the resources section.

Checkout the Codepen here - [CSS Only Accordion Component](https://codepen.io/Navdeep-Mishra-the-solid/pen/eYbpXgb)


**_Useful Resources:_** 

_BEM Convention_ - [Checkout](https://getbem.com/naming/) 
_Neomorphism Generator_ - [Checkout](https://neumorphism.io/#e0e0e0)


Feel free to discuss more about the article in the comments below😎
_Thanks for reading. 
Please like and share._
**Follow for more post on #webdev**