Pure CSS collapse/expand div

CssCollapsable

Css Problem Overview


I have a pure CSS collapsable div which is based on someone else's code who uses the :target psuedoclass. What I am trying to set up is a page with 12+ questions, and when you click on the + button the answer div expands beneath. I cannot figure out how to make multiple collapsing div elements on this page without writing a ton of extra CSS. Anyone have suggestions on how to write this so my CSS code is minimized? (i.e., so i dont have to input a bunch of unique selectors for each of the 12+ questions).

I cannot use Javascript since this is going on a wordpress.com site which does not allow JS.

Here is my jfiddle: <http://jsfiddle.net/dmarvs/94ukA/4/>

<div class="FAQ">
    <a href="#hide1" class="hide" id="hide1">+</a>
    <a href="#show1" class="show" id="show1">-</a>
    <div class="question"> Question Question Question Question Question Question Question Question Question Question Question? </div>
        <div class="list">
            <p>Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer </p>
        </div>
</div>

/* source: http://www.ehow.com/how_12214447_make-collapsing-lists-java.html */

.FAQ { 
    vertical-align: top; 
    height:auto !important; 
}
.list {
    display:none; 
    height:auto;
    margin:0;
    float: left;
}
.show {
    display: none; 
}
.hide:target + .show {
    display: inline; 
}
.hide:target {
    display: none; 
}
.hide:target ~ .list {
    display:inline; 
}

/*style the (+) and (-) */
.hide, .show {
	width: 30px;
	height: 30px;
	border-radius: 30px;
	font-size: 20px;
	color: #fff;
	text-shadow: 0 1px 0 #666;
	text-align: center;
	text-decoration: none;
	box-shadow: 1px 1px 2px #000;
	background: #cccbbb;
	opacity: .95;
	margin-right: 0;
	float: left;
	margin-bottom: 25px;
}

.hide:hover, .show:hover {
	color: #eee;
	text-shadow: 0 0 1px #666;
	text-decoration: none;
	box-shadow: 0 0 4px #222 inset;
	opacity: 1;
	margin-bottom: 25px;
}

.list p{
    height:auto;
    margin:0;
}
.question {
	float: left;
	height: auto;
	width: 90%;
	line-height: 20px;
	padding-left: 20px;
	margin-bottom: 25px;
	font-style: italic;
}

Css Solutions


Solution 1 - Css

Depending on what browsers/devices you are looking to support, or what you are prepared to put up with for non-compliant browsers you may want to check out the <summary> and <detail> tags. They are for exactly this purpose. No css is required at all as the collapsing and showing are part of the tags definition/formatting.

I've made an example here:

<details>
<summary>This is what you want to show before expanding</summary>
<p>This is where you put the details that are shown once expanded</p>
</details>

[Browser support varies.][1] Try in webkit for best results. Other browsers may default to showing all the solutions. You can perhaps fallback to the hide/show method described above.

[1]: http://caniuse.com/#feat=details "Can I Use"

Solution 2 - Css

Using <summary> and <details>

Using <summary> and <details> elements is the simplest but see browser support as current IE is not supporting it. You can polyfill though (most are jQuery-based). Do note that unsupported browser will simply show the expanded version of course, so that may be acceptable in some cases.

/* Optional styling */
summary::-webkit-details-marker {
  color: blue;
}
summary:focus {
  outline-style: none;
}

<details>
  <summary>Summary, caption, or legend for the content</summary>
  Content goes here.
</details>

See also how to style the <details> element (HTML5 Doctor) (little bit tricky).

Pure CSS3

The :target selector has a pretty good browser support, and it can be used to make a single collapsible element within the frame.

.details,
.show,
.hide:target {
  display: none;
}
.hide:target + .show,
.hide:target ~ .details {
  display: block;
}

<div>
  <a id="hide1" href="#hide1" class="hide">+ Summary goes here</a>
  <a id="show1" href="#show1" class="show">- Summary goes here</a>
  <div class="details">
    Content goes here.
  </div>
</div>
<div>
  <a id="hide2" href="#hide2" class="hide">+ Summary goes here</a>
  <a id="show2" href="#show2" class="show">- Summary goes here</a>
  <div class="details">
    Content goes here.
  </div>
</div>

Solution 3 - Css

@gbtimmon's answer is great, but way, way too complicated. I've simplified his code as much as I could.

#answer,
#show,
#hide:target {
    display: none; 
}

#hide:target + #show,
#hide:target ~ #answer {
    display: inherit; 
}

<a href="#hide" id="hide">Show</a>
<a href="#/" id="show">Hide</a>
<div id="answer"><p>Answer</p></div>

Solution 4 - Css

You just need to iterate the anchors in the two links.

<a href="#hide2" class="hide" id="hide2">+</a>
<a href="#show2" class="show" id="show2">-</a>

See this jsfiddle http://jsfiddle.net/eJX8z/

I also added some margin to the FAQ call to improve the format.

Solution 5 - Css

Or a super simple version with barely any css :)

<style>   
.faq ul li {
	display:block;
	float:left;
	padding:5px;
}

.faq ul li div {
	display:none;
}

.faq ul li div:target {
	display:block;
}


</style>


<div class="faq">
   <ul>
   <li><a href="#question1">Question 1</a>   
   <div id="question1">Answer 1 </div>
   </li>
   
   
   <li><a href="#question2">Question 2</a>
   <div id="question2">Answer 2 </div>
   </li>
   <li><a href="#question3">Question 3</a>
   <div id="question3">Answer 3 </div>
   </li>
   <li><a href="#question4">Question 4</a>
   <div id="question4">Answer 4 </div>
   </li>
   <li><a href="#question5">Question 5</a>
   <div id="question5">Answer 5 </div>
   </li>
   <li><a href="#question6">Question 6</a>
   <div id="question6">Answer 6 </div>
   </li>
   </ul>  
</div>

http://jsfiddle.net/ionko22/4sKD3/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondmarvsView Question on Stackoverflow
Solution 1 - CssThurstanView Answer on Stackoverflow
Solution 2 - CssWernightView Answer on Stackoverflow
Solution 3 - CssNeurotransmitterView Answer on Stackoverflow
Solution 4 - CssgbtimmonView Answer on Stackoverflow
Solution 5 - CssIonko GueorguievView Answer on Stackoverflow