Puro CSS compressione / espansione div


91

Ho un div comprimibile CSS puro che si basa sul codice di qualcun altro che utilizza la :targetpsuedoclass. Quello che sto cercando di impostare è una pagina con più di 12 domande e quando fai clic sul pulsante + il div di risposta si espande al di sotto. Non riesco a capire come creare più elementi div compressi in questa pagina senza scrivere un sacco di CSS extra. Qualcuno ha suggerimenti su come scrivere questo in modo che il mio codice CSS sia ridotto al minimo? (cioè, quindi non devo inserire un gruppo di selettori unici per ciascuna delle 12+ domande).

Non posso usare Javascript poiché sta succedendo su un sito wordpress.com che non consente JS.

Ecco il mio 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
A chiunque veda questo non usando wordpress posso per favore dire PER FAVORE, NON FARLO. È un hack e rompe la funzionalità posteriore di una pagina che è super fastidiosa.
gbtimmon

Risposte:


104

A seconda dei browser / dispositivi che stai cercando di supportare o di ciò che sei disposto a sopportare per i browser non conformi, potresti voler controllare i tag <summary>e <detail>. Sono esattamente per questo scopo. Non è richiesto alcun CSS poiché la compressione e la visualizzazione fanno parte della definizione / formattazione dei tag.

Ho fatto un esempio qui :

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

Il supporto del browser varia. Prova in webkit per ottenere i migliori risultati. Altri browser potrebbero mostrare automaticamente tutte le soluzioni. Puoi forse fare il fallback al metodo nascondi / mostra descritto sopra.


2
Il bug 591737 è il bug che tiene traccia del supporto in Firefox.
ShreevatsaR

9
È quasi la metà del 2016 e il supporto per questo è inesistente. Sicuramente non utilizzare questa soluzione.
Dwayne Charrington

3
Il supporto di @DigitalSea che è 'inesistente' non è corretto e 'sicuramente non usare questa soluzione' sono parole forti per uno standard che è stato stabile per diversi anni e ha avuto un polyfill disponibile dal 2010 mathiasbynens.be/notes/html5-details- jquery . Qual è la base della tua argomentazione? È probabile che MS edge implementerà presto questi tag Firefox ha implementato tag di riepilogo / dettaglio (ma attualmente lo ha dietro una bandiera) Webkit lo supporta come predefinito da Chrome 12 così come Safari su OS X e iOS browser derivati ​​da Blink - chrome mobile / desktop, opera lo supporta come impostazione predefinita
Thurstan

1
@Thurstan Nessun supporto in; IE8, IE9, IE10, IE11, Edge 13, nessun supporto in Firefox fino ad agosto 2016. Quindi, a meno che tu non abbia il lusso di rinunciare completamente al supporto di IE e attualmente Edge e Firefox, sì, non ben supportati. Il polyfill fa essenzialmente ciò che puoi già fare con Javascript (senza jQuery) e in modo abbastanza efficiente. Un polyfill per questa funzione facile da implementare è eccessivo. La soluzione che hai collegato utilizza jQuery che non è necessario. Non sarei sorpreso se un giorno lo vedessimo rimosso dalle specifiche.
Dwayne Charrington

4
Sto sviluppando solo per browser moderni e questa tecnica ha funzionato perfettamente per il mio caso d'uso e non richiedeva un tocco di CSS!
Josh Habdas

39

Utilizzando <summary>e<details>

L'utilizzo degli elementi <summary>e <details>è il più semplice, ma vedi il supporto del browser poiché l'attuale IE non lo supporta. Puoi polyfill però (la maggior parte sono basati su jQuery). Tieni presente che il browser non supportato mostrerà semplicemente la versione espansa ovviamente, quindi potrebbe essere accettabile in alcuni casi.

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

Vedi anche come applicare uno stile <details>all'elemento (HTML5 Doctor) (un po 'complicato).

CSS3 puro

Il :targetselettore ha un supporto browser piuttosto buono e può essere utilizzato per creare un singolo elemento comprimibile all'interno del 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>


1
<summary>e <details>ancora non funzionano in tutti i principali browser.
Neurotrasmettitore

4
@TranslucentCloud Questo è quello che ho detto. ;)
Wernight

E anche questo è stato detto dall'autore dell'altra risposta.
Neurotrasmettitore

1
C'è comunque da aggiungere un'animazione di transizione a questo?
azizj1

1
Per la versione animata in cui il testo scorre verso il basso e si dissolve utilizzando la transizione CSS, vedere questo post sul blog
sketchyTech

25

La risposta di @ gbtimmon è fantastica, ma decisamente troppo complicata. Ho semplificato il suo codice il più possibile.

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


3
Lavorare con CSS3 a volte è così gratificante :-)
mrmut

Questo non funziona se utilizzato più di una volta sulla stessa pagina: fare clic su nascondi / mostra influisce su tutti i div. Qualcuno sa come modificarlo in modo che funzioni se usato più di una volta?
phhu

Aggiornamento: il CSS di @Wernight risponde solo sotto ("Pure CSS3", CSS simile a questo, ma usando le classi). funziona con più div sulla stessa pagina.
phhu

1
@phhu sì, non funzionerà se riutilizzi gli stessi ID. Funzionerà se si vuole introdurre altra serie di ID ( hide2, show2, answer2per esempio). O classi, non importa.
Neurotrasmettitore

22

Hai solo bisogno di iterare gli ancoraggi nei due collegamenti.

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

Vedi questo jsfiddle http://jsfiddle.net/eJX8z/

Ho anche aggiunto un po 'di margine alla chiamata delle FAQ per migliorare il formato.


Grazie! Ci avevo provato, ma per qualche motivo non avrebbe funzionato per me. Devo aver avuto un insetto che non ho mai preso.
dmarvs

18

O una versione semplicissima con quasi nessun 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/


A proposito, ho dimenticato di dirlo: l'obiettivo non funziona in IE8 o versioni precedenti, sorpresa sorpresa! E css PIE non aiuterà neanche con questo, quindi potresti voler guardare un'opzione jQuery se la compatibilità del browser ti interessa.
Ionko Gueorguiev

Grazie, è molto più pulito. Circa un terzo del nostro potenziale pubblico di destinazione sarà su IE8. Stavo pensando di aggiungere solo alcuni CSS condizionali che aprissero tutti i div al caricamento.
dmarvs

Penso che un'interfaccia a schede potrebbe essere la soluzione giusta per te. Ne ho fatto uno tempo fa, puoi scaricarlo / verificarlo qui: ionko.com/index.php/work/simple-and-forrect-tabs .
Ionko Gueorguiev
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.