纯CSS折叠/展开div

123
我有一个纯CSS的可折叠div,基于别人使用的:target伪类的代码。我正在尝试设置一个包含12个以上问题的页面,当您单击“+”按钮时,答案div会展开。我无法弄清如何在此页面上创建多个可折叠div元素,而不编写大量额外的CSS。有人有建议吗?如何编写此代码以使我的CSS代码最小化?(即,我不必为每个12+问题输入大量唯一选择器)。
由于这将放在不允许JS的wordpress.com网站上,因此我无法使用Javascript。
这是我的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;
}

6
若有看到此信息且未使用WordPress的人,请允许我说一句,请不要这样做。这是一种破解方法,会损坏页面的后台功能,非常令人恼火。 - gbtimmon
@gabtimmon,如果我们不打算使用WordPress,为什么这是一个黑客攻击呢? - mountainclimber11
5个回答

150

根据您要支持的浏览器/设备,或者您对于不兼容浏览器可以接受的程度,您可能需要查看<summary><detail>标签。它们正是为此而设计的。无需任何CSS,因为折叠和显示均包含在标签的定义/格式中。

这里我提供了一个示例链接:

<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>

浏览器支持程度不同,如果要获得最佳效果,请在webkit中尝试。其他浏览器可能默认显示所有解决方案。您可以尝试使用上面描述的隐藏/显示方法。


2
Bug 591737是跟踪Firefox支持的错误。 - ShreevatsaR
11
现在已经快到2016年中期了,对此的支持已经不存在了。绝对不要使用这种解决方案。 - Dwayne Charrington
3
您的论点基于以下事实:自2010年以来,已经有一个polyfill可用,使得HTML5 details/summary标签对于开发人员来说是一种稳定的标准。此外,大多数现代浏览器都已支持这些标签,包括Webkit(Chrome和Safari)、Firefox和Blink派生的浏览器(Chrome移动版/桌面版、Opera)。同时,MS Edge也很可能很快就会支持这些标签。因此,将其称为“不存在支持”或者“绝对不要使用此解决方案”是不正确的强烈言辞。 - Thurstan
1
@Thurstan 不支持IE8,IE9,IE10,IE11,Edge 13,在2016年8月之前Firefox也不支持。所以除非你有放弃完全支持IE和当前的Edge和Firefox的奢侈,否则它的支持并不好。Polyfill基本上做的是你已经可以用Javascript(没有jQuery)相当高效地完成的事情。为这个简单易实现的功能编写Polyfill是过度的。你提供的解决方案使用了不必要的jQuery。我不会感到惊讶,如果有一天我们看到这个从规范中删除。 - Dwayne Charrington
8
我只为现代浏览器开发,这种技术完美地解决了我的问题,并且不需要使用一点CSS! - vhs
显示剩余2条评论

65

使用<summary><details>

使用<summary><details>元素是最简单的方法,但请注意浏览器支持,因为当前IE不支持它。不过你可以使用polyfill(大部分基于jQuery)。请注意,不支持的浏览器将只显示展开的版本,所以在某些情况下这可能是可以接受的。

/* 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>

请参阅如何样式化<details>元素(HTML5 Doctor)(有点棘手)。

纯CSS3

:target选择器的浏览器支持相当好,可用于在框架内制作一个单个可折叠的元素。

.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>


1
<summary><details>在所有主流浏览器中仍然无法正常工作。 - Neurotransmitter
5
@TranslucentCloud,这就是我说的。 ;) - Wernight
同时,这也是另一个答案作者所说的。 - Neurotransmitter
3
有没有办法为这个添加过渡动画? - azizj
1
有关使用CSS过渡动画使文本向下滑动并淡入的动画版本,请参阅此博客文章 - sketchyTech

34

@gbtimmon的答案很好,但是实在太复杂了。我已经尽可能地简化了他的代码。

#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>


1
当在同一个页面上使用超过一次时,这将无法工作:单击隐藏/显示会影响所有div。有人知道如何修改它,使其在多次使用时可以正常工作吗? - phhu
更新:@Wernight的CSS-only答案(“Pure CSS3”,类似于此的CSS,但使用类)可以在同一页上使用多个div。 - phhu
1
@phhu 是的,如果您重复使用相同的ID,它将无法工作。如果您引入其他一组ID(例如hide2show2answer2),它将起作用。或者使用类也可以,这并不重要。 - Neurotransmitter
如果能多解释一下,比如~的作用是什么,那就更棒了。 - not2savvy
~ 是一种“通用兄弟选择器”,它允许您选择同级别的兄弟元素。 - Neurotransmitter

23
你只需要迭代这两个链接中的锚点即可。
<a href="#hide2" class="hide" id="hide2">+</a>
<a href="#show2" class="show" id="show2">-</a>

请查看这个 jsfiddle http://jsfiddle.net/eJX8z/

我还为常见问题解答添加了一些边距,以改善格式。


谢谢!我尝试过了,但出于某种原因它对我不起作用。可能是我从未发现的一个错误。 - dmarvs

19

或者一个几乎没有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/


顺便提一下,:target 在 IE8 或更早版本中无法正常工作,惊喜吧!并且 CSS PIE 也不能解决这个问题,所以如果你关心浏览器兼容性的话,可能需要考虑使用 jQuery 选项。 - Ionko Gueorguiev
谢谢,这样干净多了。我们潜在目标受众中大约三分之一将使用IE8浏览器。我想添加一些有条件的CSS,仅在加载时打开所有div。 - dmarvs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接