CoderScissorhands
CoderScissorhands

Reputation: 495

Making a CSS accordion open by clicking on plus sign OR the label

I found a great CSS/html codepen that allows me to view text in an accordion fashion when clicking on text inside the label element of class question, but there's only one problem I have with it:

The problem:

I can't use the plus-signs of class plus to also toggle the accordion. Instead, in the current implementation the accordions only open and allow me to view the answer if I click on the text inside the label elements of class question.

As things stand now, if I click on the plus sign (of class .plus), nothing happens. Can someone help me to modify this code so that clicking on either the plus-sign of class plus or the question text itself inside of the label element toggles the answers' visibility?

This is the codepen: https://codepen.io/ihatecoding/pen/ryOpQd

This is the snippett:

@import url(http://fonts.googleapis.com/css?family=Open+Sans:300,800);

body {
  font-family: 'Open Sans';
  font-size: 1.5em;
  background: #eee;
}

.content {
  width: 80%;
  padding: 20px;
  margin: 0 auto;
  padding: 0 60px 0 0;
}

.centerplease {
  margin: 0 auto;
  max-width: 270px;
  font-size: 40px;
}

.question {
  position: relative;
  background: #8FBC8F;
  margin: 0;
  padding: 10px 10px 10px 50px;
  display: block;
  width:100%;
  cursor: pointer;
}

.answers {
  background: #999;
  padding: 0px 15px;
  margin: 5px 0;
  height: 0;
  overflow: hidden;
  z-index: -1;
  position: relative;
  opacity: 0;
  -webkit-transition: .7s ease;
  -moz-transition: .7s ease;
  -o-transition: .7s ease;
  transition: .7s ease;
}

.questions:checked ~ .answers{
  height: auto;
  opacity: 1;
  padding: 15px;
}

.plus {
  position: absolute;
  margin-left: 10px;
  z-index: 5;
  font-size: 2em;
  line-height: 100%;
  -webkit-user-select: none;    
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
  -webkit-transition: .3s ease;
  -moz-transition: .3s ease;
  -o-transition: .3s ease;
  transition: .3s ease;
}

.questions:checked ~ .plus {
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}

.questions {
  display: none;
}
<div class='centerplease'>
  FAQ accordion
</div>
<br>

<div class="content">
<div>
  <input type="checkbox" id="question1" name="q"  class="questions">
  <div class="plus">+</div>
  <label for="question1" class="question">
    This is the question that will be asked?
  </label>
  <div class="answers">
    What if the answer is really long and wraps the whole page and you never want to finish it but you have to because its the answer!
  </div>
</div>

<div>
  <input type="checkbox" id="question2" name="q" class="questions">
  <div class="plus">+</div>
  <label for="question2" class="question">
    Short?
  </label>
  <div class="answers">
    short!
  </div>
</div>
  
<div>
  <input type="checkbox" id="question3" name="q" class="questions">
  <div class="plus">+</div>
  <label for="question3" class="question">
    But what if the question is really long and wraps the whole page and you feel like you will never finish reading the question?
  </label>
  <div class="answers">
    This is the answer!
  </div>
</div>
</div>

Upvotes: 2

Views: 2010

Answers (3)

Michael Coker
Michael Coker

Reputation: 53709

I would move the plus sign into a pseudo element of the label, since it doesn't need to be in the markup and is just for display anyways.

@import url(http://fonts.googleapis.com/css?family=Open+Sans:300,800);

body {
  font-family: 'Open Sans';
  font-size: 1.5em;
  background: #eee;
}

.content {
  width: 80%;
  padding: 20px;
  margin: 0 auto;
  padding: 0 60px 0 0;
}

.centerplease {
  margin: 0 auto;
  max-width: 270px;
  font-size: 40px;
}

.question {
  position: relative;
  background: #8FBC8F;
  margin: 0;
  padding: 10px 10px 10px 50px;
  display: block;
  width:100%;
  cursor: pointer;
}

.answers {
  background: #999;
  padding: 0px 15px;
  margin: 5px 0;
  height: 0;
  overflow: hidden;
  z-index: -1;
  position: relative;
  opacity: 0;
  -webkit-transition: .7s ease;
  -moz-transition: .7s ease;
  -o-transition: .7s ease;
  transition: .7s ease;
}

.questions:checked ~ .answers{
  height: auto;
  opacity: 1;
  padding: 15px;
}

.question:before {
  position: absolute;
  margin-left: 10px;
  z-index: 5;
  font-size: 2em;
  line-height: 100%;
  content: '+';
  left: 0; top: 0;
  -webkit-user-select: none;    
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
  -webkit-transition: .3s ease;
  -moz-transition: .3s ease;
  -o-transition: .3s ease;
  transition: .3s ease;
}

.questions:checked ~ .question:before {
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}

.questions {
  display: none;
}
<div class='centerplease'>
  FAQ accordion
</div>
<br>

<div class="content">
<div>
  <input type="checkbox" id="question1" name="q"  class="questions">
  <label for="question1" class="question">
    This is the question that will be asked?
  </label>
  <div class="answers">
    What if the answer is really long and wraps the whole page and you never want to finish it but you have to because its the answer!
  </div>
</div>

<div>
  <input type="checkbox" id="question2" name="q" class="questions">
  <label for="question2" class="question">
    Short?
  </label>
  <div class="answers">
    short!
  </div>
</div>
  
<div>
  <input type="checkbox" id="question3" name="q" class="questions">
  <label for="question3" class="question">
    But what if the question is really long and wraps the whole page and you feel like you will never finish reading the question?
  </label>
  <div class="answers">
    This is the answer!
  </div>
</div>
</div>

Upvotes: 1

Dražen
Dražen

Reputation: 293

Just place 'plus' within label tag, and of course, fix the positioning.

  <label for="question1" class="question">
    <div class="plus">+</div>This is the question that will be asked?
  </label>

Upvotes: 0

Hunter Turner
Hunter Turner

Reputation: 6894

A simple fix for this would be to give your .plus class pointer-events: none;. This allows for the mouse to click through the plus icon, hitting the label behind it.

@import url(http://fonts.googleapis.com/css?family=Open+Sans:300,800);

body {
  font-family: 'Open Sans';
  font-size: 1.5em;
  background: #eee;
}

.content {
  width: 80%;
  padding: 20px;
  margin: 0 auto;
  padding: 0 60px 0 0;
}

.centerplease {
  margin: 0 auto;
  max-width: 270px;
  font-size: 40px;
}

.question {
  position: relative;
  background: #8FBC8F;
  margin: 0;
  padding: 10px 10px 10px 50px;
  display: block;
  width:100%;
  cursor: pointer;
}

.answers {
  background: #999;
  padding: 0px 15px;
  margin: 5px 0;
  height: 0;
  overflow: hidden;
  z-index: -1;
  position: relative;
  opacity: 0;
  -webkit-transition: .7s ease;
  -moz-transition: .7s ease;
  -o-transition: .7s ease;
  transition: .7s ease;
}

.questions:checked ~ .answers{
  height: auto;
  opacity: 1;
  padding: 15px;
}

.plus {
  position: absolute;
  margin-left: 10px;
  z-index: 5;
  font-size: 2em;
  line-height: 100%;
  -webkit-user-select: none;    
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
  -webkit-transition: .3s ease;
  -moz-transition: .3s ease;
  -o-transition: .3s ease;
  transition: .3s ease;
  pointer-events: none;
}

.questions:checked ~ .plus {
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}

.questions {
  display: none;
}
<div class='centerplease'>
  FAQ accordion
</div>
<br>

<div class="content">
<div>
  <input type="checkbox" id="question1" name="q"  class="questions">
  <div class="plus">+</div>
  <label for="question1" class="question">
    This is the question that will be asked?
  </label>
  <div class="answers">
    What if the answer is really long and wraps the whole page and you never want to finish it but you have to because its the answer!
  </div>
</div>

<div>
  <input type="checkbox" id="question2" name="q" class="questions">
  <div class="plus">+</div>
  <label for="question2" class="question">
    Short?
  </label>
  <div class="answers">
    short!
  </div>
</div>
  
<div>
  <input type="checkbox" id="question3" name="q" class="questions">
  <div class="plus">+</div>
  <label for="question3" class="question">
    But what if the question is really long and wraps the whole page and you feel like you will never finish reading the question?
  </label>
  <div class="answers">
    This is the answer!
  </div>
</div>
</div>

Upvotes: 4

Related Questions