2012-01-12 17 views
21

Ho una lista HTML in questo modo:CSS: Selezionare il primo fratello adiacente

<ul> 
    <li class="heading">Heading 1</li> 
    <li class="heading">Heading 2</li> 
    <li>Text Under Heading 2</li> 
</ul> 

Dal Titolo 1 non ha alcun testo sotto di essa, voglio nasconderlo con i CSS.

Se faccio questo,

li.heading + li.heading { display: none; } 

nasconde Rubrica 2 invece della rubrica 1.

Come faccio a nascondere la rubrica 1? C'è un modo per cercare i fratelli adiacenti e selezionare il primo?

+0

Utilizzare javascript! – greut

+3

@greut: Se non riesco a trovare un selettore CSS per farlo, userò Javascript. – Jeremy

+0

Jeremy, non capisco cosa intendi per "primo fratello adiacente". Non puoi semplicemente usare ': first-child'? – BoltClock

risposta

9

Non è possibile utilizzare CSS come attualmente definito e implementato. Richiederebbe un selettore che selezioni un elemento sulla base dei suoi fratelli dopo di esso. I selettori CSS possono selezionare un elemento sulla base di elementi precedenti o esterni, ma non sulla base di elementi successivi o interni.

L'effetto desiderato può essere ottenuto utilizzando JavaScript in modo piuttosto semplice e, a seconda dello scopo, è possibile decidere se rimuovere gli elementi dal display o rimuoverli completamente dall'albero del documento.

+11

Invece di ricorrere a JavaScript, sarebbe probabilmente più sensato cambiare la struttura HTML in modo che * possa * essere raggiunto con i CSS ... –

+0

Grazie per la risposta dettagliata. – Jeremy

+4

@ ŠimeVidas Voglio solo sottolineare che ci sono situazioni in cui non hai il controllo sull'HTML (ad esempio, leggendo HTML direttamente dal database - ugh ...) ma hai il controllo su JavaScript. Ma sono d'accordo che sarebbe meglio se possibile. –

3

ci sono alcuni modi per nascondere solo il "Intestazione 1" solo:

ul li:first-child {display:none;}

alternativa:

li.parent{ display: none; } 
li.parent + li.parent { display: list-item; } 

Inoltre, <li>Child of Heading 2</li> è non un bambino di <li class="parent">Heading 2</li>. È un fratello.

+0

Nessuna di queste soluzioni ha funzionato. Nel primo caso, potrei non voler nascondere il primo figlio se ci fosse un "Testo sotto intestazione 1". Il secondo caso non ha funzionato quando l'ho provato. Sembra che i CSS non supportino ciò che voglio fare. – Jeremy

0

La specifica CSS3 ufficiale attualmente non supporta nulla di simile, anche se mi rendo conto che sarebbe utile.

Vorrei provare a cercare alcune javascript o librerie/librerie javascript preinstallate per aggiungere selettori CSS. Anche se non ho mai incontrato nulla.

Se trovi qualcosa, per favore postalo qui.

Se non trovi nulla, potresti anche farlo manualmente o provare a trovare una soluzione completamente diversa.

Vorrei avere una risposta migliore per voi. Ci dispiace :(

20

E 'possibile indirizzare primo fratello con i CSS, con alcune limitazioni.

Per l'esempio in questione potrebbe essere fatto con qualcosa di simile

li.heading { display: none; }     /* apply to all elements */ 
li.heading + li.heading { display: list-item } /* override for all but first sibling */ 

Questo funziona, ma richiede che sia possibile impostare esplicitamente gli stili sui fratelli per sovrascrivere l'impostazione per il primo figlio.

0

provare a utilizzare JS per getElementsby Classname e se più di 1 allora usare i CSS:

ul li: first-child {display: none;}

0

so che questa domanda ha già una risposta marcata valida , ma forse altre persone vogliono usare la mia soluzione solo CSS:

Volevo avere un elenco di avvisi (in questo caso avvisi di bootstrap) in un contenitore e il loro bordo da comprimere. Ogni avviso ha un raggio di confine, che sembra piuttosto sciocco quando sono tutti in un contenitore. Quindi con margin-top: -1px ho fatto crollare i loro bordi. Come passo successivo ho dovuto modificare gli stili del primo, di ogni avviso intermedio e dell'ultimo avviso. E questo dovrebbe anche essere bello per un singolo avviso, due avvisi e n avvisi.

.alert { 
    border-top-left-radius: 4px; 
    border-top-right-radius: 4px; 
    border-bottom-left-radius: 0px; 
    border-bottom-right-radius: 0px; 
    margin: 0; 
} 

// set for the first alert that it should have a rounded top border 

.alert:last-child { 
    border-bottom-left-radius: 4px; 
    border-bottom-right-radius: 4px; 
} 

// set for the last alert that it should have a rounded bottom border 
// if there is only one alert this will also trigger it to have a rounded bottom border aswell 

.alert+.alert:last-child { 
    margin-top: -1px; 
    border-top-left-radius: 0; 
    border-top-right-radius: 0; 
} 

//for the last border of n alerts we set the top border to be collapsing and remove only the the top rounded borders 

.alert+.alert:not(:last-child) { 
    margin-top: -1px; 
    border-radius: 0; 
} 

// for each following alert in between we remove the top rounded borders and make their borders collapse 

E qui è un modello angolare per più avvisi.

<div id="alertscontainer"> 
    <div data-ng-repeat="alert in data.alerts" class="alert" data-ng-class="'alert-' + alert.class"> 
     {{alert.body}} 
    </div> 
</div> 
Problemi correlati