1

I have this accordion what works fine without javascript :

code :

.accordion ul li {
  border: 1px solid grey;
}

.accordion input[type=checkbox] {
  display: none;
}

.accordion label {
  margin: 0px;
  display: block;
  cursor: pointer;
  padding: 10px;
  transition: all .2s ease-out;
  -webkit-transition: all .2s ease-out;
  -moz-transition: all .2s ease-out;
}

.accordion .content {
  overflow: hidden;
  -webkit-transition: all 0.3s ease-out;
  -moz-transition: all 0.3s ease-out;
}

.accordion ul li .content {
  height: 0px;
}

.accordion [type=checkbox]:checked~label~.content {
  height: 250px;
  /*height: 100%*/
}
<div class="accordion">
  <ul>
    <li>
      <input type="checkbox" id="acc1" />
      <label for="acc1">
            <span style="color: green;">
          click to collapse/expand
           </span>
          </label>
      <div id="content" class="content">
        <div><a href="#">Item 1</a></div>
        <div><a href="#">Item 2</a></div>
        <div><a href="#">Item 3</a></div>
        <div><a href="#">Item 4</a></div>
        <div><a href="#">Item 5</a></div>
        <div><a href="#">Item 6</a></div>
      </div>
    </li>
    <li>
      <input type="checkbox" id="acc2" />
      <label for="acc2">
            <span style="color: green;">
          click to collapse/expand
           </span>
          </label>
      <div id="content" class="content">
        <div><a href="#">Item 1</a></div>
        <div><a href="#">Item 2</a></div>
        <div><a href="#">Item 3</a></div>
        <div><a href="#">Item 4</a></div>
        <div><a href="#">Item 5</a></div>
        <div><a href="#">Item 6</a></div>
        <div><a href="#">Item 7</a></div>
        <div><a href="#">Item 8</a></div>
        <div><a href="#">Item 9</a></div>
        <div><a href="#">Item 10</a></div>
        <div><a href="#">Item 11</a></div>
        <div><a href="#">Item 12</a></div>
        <div><a href="#">Item 13</a></div>
        <div><a href="#">Item 14</a></div>
        <div><a href="#">Item 15</a></div>
        <div><a href="#">Item 16</a></div>
        <div><a href="#">Item 17</a></div>
      </div>
    </li>
  </ul>
</div>

Plunker

My problem is with the last css class :

.accordion [type=checkbox]:checked~label~.content {
      height: 250px;
      /*height: 100%*/
    }

When the 'height' attribute is set to '250px' everything works fine, BUT since the height is static there's more space at the bottom of first accordion than there should be.

But when the 'height' attribute is set to '100%' now the space problem is solved, every accordion's height encapsulates its content perfectly, so no unnecessary space, BUT the animation is gone.

Can someone help me fix this (without javascript of course) ?

Pete
  • 57,112
  • 28
  • 117
  • 166
Wolf359
  • 2,620
  • 4
  • 42
  • 62
  • What do you want it to be 100% of? – Pete Oct 06 '17 at 09:40
  • You effectively want it to transition to an “auto” height here - as high as the content demands, right? That is not really possible using CSS alone - see the duplicate. – CBroe Oct 06 '17 at 09:42

1 Answers1

2

Use max-height instead of height:

.accordion ul li {
  border: 1px solid grey;
}

.accordion input[type=checkbox] {
  display: none;
}

.accordion label {
  margin: 0px;
  display: block;
  cursor: pointer;
  padding: 10px;
  transition: all .2s ease-out;
  -webkit-transition: all .2s ease-out;
  -moz-transition: all .2s ease-out;
}

.accordion .content {
  overflow: hidden;
  -webkit-transition: all 0.3s ease-out;
  -moz-transition: all 0.3s ease-out;
}

.accordion ul li .content {
  max-height: 0px;
}

.accordion [type=checkbox]:checked~label~.content {
  max-height: 250px; /* has to be taller than tallest content */
}
<div class="accordion">
  <ul>
    <li>
      <input type="checkbox" id="acc1" />
      <label for="acc1">
            <span style="color: green;">
          click to collapse/expand
           </span>
          </label>
      <div id="content" class="content">
        <div><a href="#">Item 1</a></div>
        <div><a href="#">Item 2</a></div>
        <div><a href="#">Item 3</a></div>
        <div><a href="#">Item 4</a></div>
        <div><a href="#">Item 5</a></div>
        <div><a href="#">Item 6</a></div>
      </div>
    </li>
    <li>
      <input type="checkbox" id="acc2" />
      <label for="acc2">
            <span style="color: green;">
          click to collapse/expand
           </span>
          </label>
      <div id="content" class="content">
        <div><a href="#">Item 1</a></div>
        <div><a href="#">Item 2</a></div>
        <div><a href="#">Item 3</a></div>
        <div><a href="#">Item 4</a></div>
        <div><a href="#">Item 5</a></div>
        <div><a href="#">Item 6</a></div>
        <div><a href="#">Item 7</a></div>
        <div><a href="#">Item 8</a></div>
        <div><a href="#">Item 9</a></div>
        <div><a href="#">Item 10</a></div>
        <div><a href="#">Item 11</a></div>
        <div><a href="#">Item 12</a></div>
        <div><a href="#">Item 13</a></div>
        <div><a href="#">Item 14</a></div>
        <div><a href="#">Item 15</a></div>
        <div><a href="#">Item 16</a></div>
        <div><a href="#">Item 17</a></div>
      </div>
    </li>
  </ul>
</div>

Also, if you want one to close when another opens, you can change your checkbox to a radio

.accordion ul li {
  border: 1px solid grey;
}

.accordion input[type=radio] {
  display: none;
}

.accordion label {
  margin: 0px;
  display: block;
  cursor: pointer;
  padding: 10px;
  transition: all .2s ease-out;
  -webkit-transition: all .2s ease-out;
  -moz-transition: all .2s ease-out;
}

.accordion .content {
  overflow: hidden;
  -webkit-transition: all 0.3s ease-out;
  -moz-transition: all 0.3s ease-out;
}

.accordion ul li .content {
  max-height: 0px;
}

.accordion [type=radio]:checked~label~.content {
  max-height: 250px; /* has to be taller than tallest content */
}
<div class="accordion">
  <ul>
    <li>
      <input type="radio" name="accordion" id="acc1" />
      <label for="acc1">
            <span style="color: green;">
          click to collapse/expand
           </span>
          </label>
      <div id="content" class="content">
        <div><a href="#">Item 1</a></div>
        <div><a href="#">Item 2</a></div>
        <div><a href="#">Item 3</a></div>
        <div><a href="#">Item 4</a></div>
        <div><a href="#">Item 5</a></div>
        <div><a href="#">Item 6</a></div>
      </div>
    </li>
    <li>
      <input type="radio" name="accordion" id="acc2" />
      <label for="acc2">
            <span style="color: green;">
          click to collapse/expand
           </span>
          </label>
      <div id="content" class="content">
        <div><a href="#">Item 1</a></div>
        <div><a href="#">Item 2</a></div>
        <div><a href="#">Item 3</a></div>
        <div><a href="#">Item 4</a></div>
        <div><a href="#">Item 5</a></div>
        <div><a href="#">Item 6</a></div>
        <div><a href="#">Item 7</a></div>
        <div><a href="#">Item 8</a></div>
        <div><a href="#">Item 9</a></div>
        <div><a href="#">Item 10</a></div>
        <div><a href="#">Item 11</a></div>
        <div><a href="#">Item 12</a></div>
        <div><a href="#">Item 13</a></div>
        <div><a href="#">Item 14</a></div>
        <div><a href="#">Item 15</a></div>
        <div><a href="#">Item 16</a></div>
        <div><a href="#">Item 17</a></div>
      </div>
    </li>
  </ul>
</div>
Pete
  • 57,112
  • 28
  • 117
  • 166
  • 3
    You can even set `max-height` to be an arbitrarily large value. But the problem is that the animation duration is no longer proportional to the actual content height, which results in inconsistent animation times. – Niet the Dark Absol Oct 06 '17 at 09:43
  • 1
    @NiettheDarkAbsol that's the unfortunate side effect of pure css accordions – Pete Oct 06 '17 at 09:45