With a pure css accordion with checkbox, can you open and close all open tabs?

Viewed 445

Code is from here --> https://codepen.io/raubaca/pen/PZzpVe

I have looked at the other answers to questions similar to this. Nothing actually answers this question sufficiently. Or else they're about slightly convergent issues, or use jquery etc, or for css in a different format.

When using the checkbox method to make a pure css accordion where you can have multiple tabs open at one time, is it possible to close all the tabs at once? And also open all the tabs at once? I'm assuming I can do something like input:unchecked ~ .tab-content {...} But there's no input:unchecked in the css specs.

@charset "UTF-8";
body {
  color: #2c3e50;
  background: #ecf0f1;
  padding: 0 1em 1em;
}

h1 {
  margin: 0;
  line-height: 2;
  text-align: center;
}

h2 {
  margin: 0 0 0.5em;
  font-weight: normal;
}

input {
  position: absolute;
  opacity: 0;
  z-index: -1;
}

.row {
  display: flex;
}
.row .col {
  flex: 1;
}
.row .col:last-child {
  margin-left: 1em;
}

/* Accordion styles */
.tabs {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 4px -2px rgba(0, 0, 0, 0.5);
}

.tab {
  width: 100%;
  color: white;
  overflow: hidden;
}
.tab-label {
  display: flex;
  justify-content: space-between;
  padding: 1em;
  background: #2c3e50;
  font-weight: bold;
  cursor: pointer;
  /* Icon */
}
.tab-label:hover {
  background: #1a252f;
}
.tab-label::after {
  content: "❯";
  width: 1em;
  height: 1em;
  text-align: center;
  transition: all 0.35s;
}
.tab-content {
  max-height: 0;
  padding: 0 1em;
  color: #2c3e50;
  background: white;
  transition: all 0.35s;
}
.tab-close, .tab-open {
  display: flex;
  justify-content: flex-end;
  padding: 1em;
  font-size: 0.75em;
  background: #2c3e50;
  cursor: pointer;
}
.tab-close:hover {
  background: #1a252f;
}

input:checked + .tab-label {
  background: #1a252f;
}
input:checked + .tab-label::after {
  transform: rotate(90deg);
}
input:checked ~ .tab-content {
  max-height: 100vh;
  padding: 1em;
}
        <!-- <h1>Pure CSS Accordion <sup>2.0</sup></h1> -->
        <div class="row">
          <div class="col">
            <h2>Open <b>multiple</b></h2>
            <div class="tabs">
                <div class="tab">
                    <input type="checkbox" id="chck0" name="chk">
                    <label for="chck0" class="tab-open">Open All &times;</label>
                  </div>
              <div class="tab">
                <input type="checkbox" id="chck1"  name="chk">
                <label class="tab-label" for="chck1">Item 1</label>
                <div class="tab-content">
                  Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ipsum, reiciendis!
                </div>
              </div>
              <div class="tab">
                <input type="checkbox" id="chck2"  name="chk">
                <label class="tab-label" for="chck2">Item 2</label>
                <div class="tab-content">
                  Lorem ipsum dolor sit amet consectetur adipisicing elit. A, in!
                </div>
              </div>
              <div class="tab">
                <input type="checkbox" id="chck3" name="chk">
                <label for="chck3" class="tab-close">Close All &times;</label>
              </div>
            </div>
          </div>

1 Answers

The best you can do with css only is open all - you wouldn't be able to close all (just return them to their original state). First, you would need to move the toggle checkbox outside the tab so it is on the same level as the accordion tabs, then you can use the three styles at the end of the below snippet

If you need a close all, you would have to use js to uncheck the checkboxes that have been checked to open them - css can't do this

@charset "UTF-8";
body {
  color: #2c3e50;
  background: #ecf0f1;
  padding: 0 1em 1em;
}

h1 {
  margin: 0;
  line-height: 2;
  text-align: center;
}

h2 {
  margin: 0 0 0.5em;
  font-weight: normal;
}

input {
  position: absolute;
  opacity: 0;
  z-index: -1;
}

.row {
  display: flex;
}

.row .col {
  flex: 1;
}

.row .col:last-child {
  margin-left: 1em;
}


/* Accordion styles */

.tabs {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 4px -2px rgba(0, 0, 0, 0.5);
}

.tab {
  width: 100%;
  color: white;
  overflow: hidden;
}

.tab-label {
  display: flex;
  justify-content: space-between;
  padding: 1em;
  background: #2c3e50;
  font-weight: bold;
  cursor: pointer;
  /* Icon */
}

.tab-label:hover {
  background: #1a252f;
}

.tab-label::after {
  content: "❯";
  width: 1em;
  height: 1em;
  text-align: center;
  transition: all 0.35s;
}

.tab-content {
  max-height: 0;
  padding: 0 1em;
  color: #2c3e50;
  background: white;
  transition: all 0.35s;
}

.tab-close,
.tab-open {
  display: flex;
  justify-content: flex-end;
  padding: 1em;
  font-size: 0.75em;
  background: #2c3e50;
  cursor: pointer;
}

.tab-close:hover {
  background: #1a252f;
}

input:checked+.tab-label {
  background: #1a252f;
}

input:checked+.tab-label::after {
  transform: rotate(90deg);
}

input:checked~.tab-content {
  max-height: 100vh;
  padding: 1em;
}

#chck0+label:before {
  content: 'Open All';
  color: #ffffff;
}

#chck0:checked+label:before {
  content: 'Return to previous state';
}

#chck0:checked~.tab .tab-content {
  max-height: 100vh;
  padding: 1em;
}
<!-- <h1>Pure CSS Accordion <sup>2.0</sup></h1> -->
<div class="row">
  <div class="col">
    <h2>Open <b>multiple</b></h2>
    <div class="tabs">
      <input type="checkbox" id="chck0" name="chk">
      <label for="chck0" class="tab-open"> &times;</label>
      <div class="tab">
        <input type="checkbox" id="chck1" name="chk">
        <label class="tab-label" for="chck1">Item 1</label>
        <div class="tab-content">
          Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ipsum, reiciendis!
        </div>
      </div>
      <div class="tab">
        <input type="checkbox" id="chck2" name="chk">
        <label class="tab-label" for="chck2">Item 2</label>
        <div class="tab-content">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. A, in!
        </div>
      </div>
    </div>
  </div>

Actually, you could extend this to use radio buttons as your toggles and then you can have a close all too:

@charset "UTF-8";
body {
  color: #2c3e50;
  background: #ecf0f1;
  padding: 0 1em 1em;
}

h1 {
  margin: 0;
  line-height: 2;
  text-align: center;
}

h2 {
  margin: 0 0 0.5em;
  font-weight: normal;
}

input {
  position: absolute;
  opacity: 0;
  z-index: -1;
}

.row {
  display: flex;
}

.row .col {
  flex: 1;
}

.row .col:last-child {
  margin-left: 1em;
}


/* Accordion styles */

.tabs {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 4px -2px rgba(0, 0, 0, 0.5);
}

.tab {
  width: 100%;
  color: white;
  overflow: hidden;
}

.tab-label {
  display: flex;
  justify-content: space-between;
  padding: 1em;
  background: #2c3e50;
  font-weight: bold;
  cursor: pointer;
  /* Icon */
}

.tab-label:hover {
  background: #1a252f;
}

.tab-label::after {
  content: "❯";
  width: 1em;
  height: 1em;
  text-align: center;
  transition: all 0.35s;
}

.tab-content {
  max-height: 0;
  padding: 0 1em;
  color: #2c3e50;
  background: white;
  transition: all 0.35s;
}

.tab-close,
.tab-open {
  display: flex;
  justify-content: flex-end;
  padding: 1em;
  font-size: 0.75em;
  background: #2c3e50;
  cursor: pointer;
}

.tab-close:hover {
  background: #1a252f;
}

input:checked+.tab-label {
  background: #1a252f;
}

input:checked+.tab-label::after {
  transform: rotate(90deg);
}

input:checked~.tab-content {
  max-height: 100vh;
  padding: 1em;
}

.toggle-label {
  color: #000000;
}

#open-all:checked~.tab .tab-content {
  max-height: 100vh;
  padding: 1em;
}

#open-all:checked~#open-all-label,
#close-all:checked~#close-all-label,
#reset-all:checked~#reset-all-label {
  display: none;
}

#close-all:checked~.tab .tab-content {
  max-height: 0;
  padding: 0;
}
<!-- <h1>Pure CSS Accordion <sup>2.0</sup></h1> -->
<div class="row">
  <div class="col">
    <h2>Open <b>multiple</b></h2>
    <div class="tabs">
      <input type="radio" id="reset-all" name="toggle" checked>
      <input type="radio" id="open-all" name="toggle">
      <input type="radio" id="close-all" name="toggle">
      <label for="reset-all" class="toggle-label" id="reset-all-label">Reset &times;</label>
      <label for="open-all" class="toggle-label" id="open-all-label">Open All &times;</label>
      <label for="close-all" class="toggle-label" id="close-all-label">Close All &times;</label>
      <div class="tab">
        <input type="checkbox" id="chck1" name="chk">
        <label class="tab-label" for="chck1">Item 1</label>
        <div class="tab-content">
          Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ipsum, reiciendis!
        </div>
      </div>
      <div class="tab">
        <input type="checkbox" id="chck2" name="chk">
        <label class="tab-label" for="chck2">Item 2</label>
        <div class="tab-content">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. A, in!
        </div>
      </div>
    </div>
  </div>

Related