Réduire / développer le div pur CSS

92

J'ai un div réductible CSS pur qui est basé sur le code de quelqu'un d'autre qui utilise le :targetpsuedoclass. Ce que j'essaie de configurer est une page avec plus de 12 questions, et lorsque vous cliquez sur le bouton +, la réponse div se développe en dessous. Je ne peux pas comprendre comment créer plusieurs éléments div qui se réduisent sur cette page sans écrire une tonne de CSS supplémentaire. Quelqu'un a-t-il des suggestions sur la façon d'écrire ceci afin que mon code CSS soit minimisé? (c'est-à-dire, donc je n'ai pas à entrer un tas de sélecteurs uniques pour chacune des 12+ questions).

Je ne peux pas utiliser Javascript car cela se passe sur un site wordpress.com qui n'autorise pas JS.

Voici mon 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;
}
dmarvs
la source
6
À quiconque ne voit pas cela en utilisant wordpress puis-je s'il vous plaît dire s'il vous plaît ne faites pas ça. C'est un hack et cela casse la fonctionnalité arrière d'une page qui est super ennuyeuse.
gbtimmon

Réponses:

106

En fonction des navigateurs / appareils que vous souhaitez prendre en charge, ou de ce que vous êtes prêt à accepter pour les navigateurs non conformes, vous pouvez consulter les balises <summary>et <detail>. Ils sont exactement dans ce but. Aucun css n'est requis du tout car la réduction et l'affichage font partie de la définition / mise en forme des balises.

J'ai fait un exemple ici :

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

La prise en charge du navigateur varie. Essayez en webkit pour de meilleurs résultats. D'autres navigateurs peuvent afficher par défaut toutes les solutions. Vous pouvez peut-être revenir à la méthode hide / show décrite ci-dessus.

Thurstan
la source
2
Le bogue 591737 est le bogue qui suit le support dans Firefox.
ShreevatsaR
9
Nous sommes presque mi 2016 et le support pour cela est inexistant. N'utilisez certainement pas cette solution.
Dwayne Charrington
3
Le support @DigitalSea étant `` inexistant '' est incorrect et `` n'utilisez certainement pas cette solution '' sont des mots forts pour un standard qui est stable depuis plusieurs années et qui dispose d'un polyfill depuis 2010 mathiasbynens.be/notes/html5-details- jquery . Quelle est la base de votre argumentation? MS edge est susceptible d'implémenter ces balises bientôt Firefox a implémenté des balises de résumé / détail (mais les a actuellement derrière un drapeau) Webkit le prend en charge par défaut depuis Chrome 12, tout comme safari sur les navigateurs dérivés d'OS X et iOS Blink - chrome mobile / desktop, opéra le soutenir par défaut
Thurstan
1
@Thurstan Pas de support dans; IE8, IE9, IE10, IE11, Edge 13, pas de support dans Firefox jusqu'en août 2016. Donc, à moins que vous n'ayez le luxe de renoncer entièrement au support d'IE et actuellement Edge et Firefox, oui, pas bien supporté. Le polyfill fait essentiellement ce que vous pouvez déjà faire avec Javascript (sans jQuery) et assez efficacement. Un polyfill pour cette fonctionnalité facile à implémenter vous-même est exagéré. La solution que vous avez liée utilise jQuery, ce qui n'est pas nécessaire. Je ne serais pas surpris si nous voyons cela retiré de la spécification un jour de toute façon.
Dwayne Charrington
4
Je développe uniquement pour les navigateurs modernes et cette technique a parfaitement fonctionné pour mon cas d'utilisation et ne nécessitait pas un coup de langue de CSS!
Josh Habdas
39

Utilisation <summary>et<details>

L'utilisation d' éléments <summary>et <details>est la plus simple, mais voyez la prise en charge du navigateur car l'actuel IE ne le prend pas en charge. Vous pouvez cependant polyfill (la plupart sont basés sur jQuery). Notez que le navigateur non pris en charge affichera simplement la version étendue bien sûr, ce qui peut être acceptable dans certains cas.

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

Voir aussi comment styliser l' <details>élément (HTML5 Doctor) (un peu délicat).

CSS3 pur

Le :targetsélecteur a une très bonne prise en charge du navigateur , et il peut être utilisé pour créer un seul élément pliable dans le cadre.

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

Wernight
la source
1
<summary>et <details>ne fonctionne toujours pas dans tous les principaux navigateurs.
Neurotransmetteur
4
@TranslucentCloud C'est ce que j'ai dit. ;)
Wernight
Et cela a également été dit par l'auteur de l'autre réponse.
Neurotransmetteur
1
Est-il possible d'ajouter une animation de transition à cela?
azizj1
1
Pour la version animée où les diapositives de texte vers le bas et se fane en utilisant la transition CSS, voir ce blogpost
sketchyTech
25

La réponse de @ gbtimmon est excellente, mais beaucoup trop compliquée. J'ai simplifié son code autant que possible.

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

Neurotransmetteur
la source
3
Travailler avec CSS3 est parfois si gratifiant :-)
mrmut
Cela ne fonctionne pas lorsqu'il est utilisé plus d'une fois sur la même page: cliquer sur masquer / afficher affecte toutes les divs. Quelqu'un sait-il comment le modifier pour qu'il fonctionne lorsqu'il est utilisé plus d'une fois?
phhu
Mise à jour: le CSS de @Wernight ne répond que ci-dessous ("Pure CSS3", CSS similaire à celui-ci, mais utilisant des classes). fonctionne avec plusieurs div sur la même page.
phhu
1
@phhu oui, cela ne fonctionnera pas si vous réutilisez les mêmes identifiants. Il fonctionnera si vous introduirez autre ensemble d'ID ( hide2, show2, answer2par exemple). Ou des cours, peu importe.
Neurotransmetteur le
22

Il vous suffit d'itérer les ancres dans les deux liens.

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

Voir ce jsfiddle http://jsfiddle.net/eJX8z/

J'ai également ajouté une marge à l'appel de FAQ pour améliorer le format.

gbtimmon
la source
Merci! J'avais essayé cela, mais pour une raison quelconque, cela ne fonctionnait pas pour moi. Doit avoir eu un bug que je n'ai jamais attrapé.
dmarvs
18

Ou une version super simple avec à peine aucun 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/

Ionko Gueorguiev
la source
D'ailleurs j'ai oublié de mentionner que: la cible ne fonctionne pas dans IE8 ou plus ancien, surprise surprise! Et css PIE n'aidera pas non plus avec cela, vous voudrez peut-être regarder une option jQuery si la compatibilité du navigateur vous intéresse.
Ionko Gueorguiev
Merci, c'est beaucoup plus propre. Environ un tiers de notre public cible potentiel sera sur IE8. Je pensais simplement ajouter du CSS conditionnel qui ouvrirait simplement toutes les divs en charge.
dmarvs
Je pense qu'une interface à onglets pourrait être la bonne solution pour vous. J'en ai fait un il y a quelque temps, vous pouvez le télécharger / le vérifier ici: ionko.com/index.php/work/simple-and-flexible-tabs .
Ionko Gueorguiev