## Expanding Panels

##### Code Breakdown

###### Introduction

This project shows how to create "expanding" panel display areas. These panels can be used to hold anything such as comments, recipes, or images. In our case here, we are using the expanding panels to display images.

The complete source code for this project can be downloaded here.

###### the HTML

The HTML is pretty simple here. We have a main container <div>, which which will hold five sub-<div>'s. These sub-<div>'s, will hold our images. Each sub-<div> has a class of panel and initially, the first <div> will have an additional class of active.

This is essentially how we control which panel is "expanded". We'll use JavaScript to control which panel is active,Request textDocument/definition failed.with the first panel being the active panel, initially.

Here's the code:

- html
- <div class="container">
  - <div class="panel active" style="background-image: url('images/photo1.png')"><h3>Explore The World</h3>
  - <div class="panel" style="background-image: url('images/photo2.png')"><h3>Wild Forest</h3>
  - <div class="panel" style="background-image: url('images/photo3.png')"><h3>Sunny Beach</h3>
  - <div class="panel" style="background-image: url('images/photo4.png')"><h3>City Winter</h3>
  - <div class="panel" style="background-image: url('images/photo5.png')"><h3>Mountains Clouds</h3>
- </div>

Notice that we have set the background image for each panel, directly as an inline style. This eliminates the need to create an individual style for each div, which would then need to have the background image set in the CSS.

Also notice the active class on the first <div>. This determines which panel is "expanded" and we will manipulate this through our JavaScript.

And lastly, notice that each panel has an <h3> providing a title for it's image. Displaying this label is controlled through the CSS and will only be displayed on the active panel.

###### the CSS

The CSS is also pretty simple. We're going to set the main container to be a flex container, aligning everything centered. Each panel is going to have a flex width of 0.5, with the active panel having a flex width of 5. So the active panel will be 10 times wider than the inactive panels.

As stated previously, we're going to control which panel is active with JavaScript.

Here's the code:

- css
- .container {
  - display: flex;
  - justify-content: center;
  - align-items: center;
- }
- .panel {
  - background-size: auto 100%;
  - background-position: center;
  - background-repeat: no-repeat;
  - height: 80vh;
  - border: 1px solid #000;
  - border-radius: 50px;
  - color: #fff;
  - cursor: pointer;
  - flex: 0.5;
  - margin: 10px;
  - position: relative;
  - transition: flex 0.7s;
  - // most of this is simple styling, but notice how we set the background size to auto size 100% of the container, centered, and no-repeat.
  - // The default width is flex 0.5 and we set position relative so we can control the position of our "Title Label". We then set a transition for the Title when it displays.
- }
- .panel h3 {
  - position: absolute;
  - bottom: 20px;
  - left: 20px;
  - margin: 0;
  - font-size: 24px;
  - opacity: 0;
  - // this is the styling for the "Title Label" for each panel. Notice that is is positioned absolutely within it's parent container (panel)
  - // also notice an initial opacity of 0. This will be set to 1 on the active panel.
- }
- .panel.active {
  - flex: 5;
  - box-shadow: 0px 0px 15px #e0ca82;
  - // this defines our active panel. it sets the width to flex 5 and gives it a background highlight.
- }
- .panel.active h3 {
  - opacity: 1;
  - transition: 0.3s ease-in 0.4s;
  - // this "turns on" the title label for the active panel and gives it a smooth transition.
- }

And that should do us for the styling. All we need is the JavaScript for some functionality.

###### the JavaScript

The JavaScript is also very simple. We're going to use querySelectorAll to access all of our panel divs. Once we have the access, we will set up a click event to detect which panel was "clicked". And lastly, remove the active class from all of the panels, and reApply it to the panel that was selected.

We've already set the styling in our CSS, so all that the JavaScript needs to do is change which panel is the active panel.

Here is the code:

- Javascript
- const panels = document.querySelectorAll('.panel');
- // add click function to each panel
- panels.forEach((panel) => {
  - panel.addEventListener('click', () => {
    - removeActiveClasses(); // runs a function to remove the active class from all of the panels
    - panel.classList.add('active');// adds the active class to the currently selected panel
  - });
- });
- // loop through all of the panels and remove the active class
- function removeActiveClasses() {
  - panels.forEach((panel) => {
    - panel.classList.remove('active');
  - });
- }

And that's all that is needed. Once again, all that the JavaScript is doing is changing which panel is the "active" panel, based on which panel the user selected.

Back to Top