web-dev-qa-db-fra.com

Existe-t-il un moyen de spécifier un raccourci CSS pour "tous les éléments sauf le premier / dernier"?

Très souvent, il est naturel de devoir spécifier un style CSS pour tous les éléments sauf le premier (ou le dernier). Par exemple, lorsque vous stylisez des paragraphes, vous souhaitez ajouter une marge inférieure à chaque élément à l'exception du dernier (ou de même, une marge supérieure à chaque élément à l'exception du premier).

Y a-t-il un moyen de le faire qui est:

  • plus concis que de définir p {...} puis p:first-child {...}?
  • plus simple et intuitif que p:nth-child(-n+1)?

Si ce n'est pas le cas, connaissez-vous une tentative d'ajout?

46
julien_c

Pour tous les éléments p à l'exception du premier enfant, utilisez l'un ou l'autre (le second est mieux pris en charge):

p:not(:first-child)
p:first-child ~ p

Pour tous les éléments p sauf le dernier enfant:

p:not(:last-child)

Pour tous les éléments p sauf le premier et le dernier enfant:

p:not(:first-child):not(:last-child)

Comme d'habitude, :not() et :last-child De CSS3 ne sont pas pris en charge avant IE9 + et les versions relativement nouvelles des autres navigateurs. Vous n'irez pas très loin en termes de prise en charge du navigateur (IE8 et versions antérieures) à moins que vous n'ajoutiez des classes à vos premier et dernier enfants, en utilisant JavaScript ou autre.

N'oubliez pas que les marges verticales se réduisent entre les paragraphes entrants et leurs ancêtres , donc à moins que vous ne vouliez mettre à zéro les marges de l'élément conteneur pour ces paragraphes également, vous ne devriez pas avoir besoin de mettre à zéro les marges des premier et dernier p éléments en particulier. Voici un violon pour illustrer.

89
BoltClock

Si le support IE7-8 n'est pas nécessaire, vous pouvez utiliser le sélecteur :not() CSS .

Mais si vous devez prendre en charge IE7 +, ce qui peut toujours être le cas, vous pouvez utiliser une petite astuce qui vous mène généralement assez loin. Un fait moins connu est que le :first-child le sélecteur psuedo fonctionne réellement dans IE7 + (pas :last-child cependant) comme le sont certains autres sélecteurs css et cela rend possible l'ajout de marges verticales dans une disposition flottante horizontalement.

Imaginez ce html:

<ul>
    <li>Item #1</li>
    <li>Item #2</li>
    <li>Item #3</li>
    <li>Item #4</li>
</ul>

Et cela en tant que CSS:

/* General reset */
ul, li { list-type: none; margin: 0; padding: 0; }
/* Make horizontal */
ul > li { float: left; }

Alors maintenant, tous les éléments de la liste sont horizontalement côte à côte, et maintenant nous voulons ajouter une marge entre tous les éléments mais pas à droite ou à gauche, nous pouvons le faire en CSS:

/* General reset */
ul, li { list-type: none; margin: 0; padding: 0; }
/* Make horizontal */
ul > li { float: left; margin-left: 10px; }
ul > li:first-child { margin-left: 0; }

Cela couvre généralement 95% des cas où je veux quelque chose d'unique, puis le reste des les sélecteurs "oubliés" couvrent encore quelques pour cent , après cela, vous devez ajouter des classes qui ne sont généralement pas beaucoup de un goulot d'étranglement de toute façon dans le backend de la page.

3
sg3s

Eh bien, vous pourriez faire:

p:not(:first-child) {...}

Mais seuls les navigateurs les plus récents prennent en charge le :not psuedo-class.

A part ça, non. Votre meilleure option est de spécifier un style pour tous, puis de le remplacer pour le premier/dernier.

3

Je suggère d'utiliser first-of-type:

p:not(:first-of-type) { ... }

Prise en charge du navigateur ( caniuse )

2
David Morales