Pourquoi la sélection par ID n'est pas recommandée en CSS?

Dans CSSLint (csslint.net), ils ne recommandent pas d'utiliser un id pour sélectionner des éléments. Je fais confiance à css Lint car il est écrit par des gens intelligents qui connaissent CSS très bien et en profondeur. Mais je veux savoir quelles sont les raisons de cela? Pourquoi la sélection avec un id n'est-elle pas une bonne chose?

21
demandé sur Paul Sweatte 2011-11-10 22:35:48

5 réponses

CSSLint donne un guide pour expliquer pourquoi ils font leurs recommandations:

Les ID ne doivent pas être utilisés dans les sélecteurs car ces règles sont trop étroitement associées au code HTML et n'ont aucune possibilité de réutilisation. Il est préférable d'utiliser des classes dans les sélecteurs, puis d'appliquer une classe à un élément de la page. De plus, les Id ont un impact sur votre spécificité et peuvent conduire à des guerres de spécificité.

(lien)

Fondamentalement, si vous structurez votre code pour utiliser plutôt des classes que les identifiants, votre code peut être plus général et réutilisable, ce qui est généralement une bonne chose. En outre, la spécificité est une chose difficile à comprendre, et peut causer des bugs difficiles à trouver, donc si vous omettez les sélecteurs D'ID, vous êtes moins susceptible d'avoir des règles contradictoires résolues de manière inattendue.

24
répondu lonesomeday 2011-11-10 18:38:04

Je suis en désaccord avec l'idée de Ne jamais utiliser des ID pour sélectionner des éléments, mais je comprends le raisonnement.

Souvent, les développeurs utiliseront un sélecteur de spécificité très élevé lorsque la forme générale suffira:

#foo #bar #baz .something a {
    text-decoration: underline;
}

Est probablement mieux écrit comme

.something a {
     text-decoration: underline;
}

En outre, les styles d'écriture comme:

#foo-1,
#foo-2,
#foo-3,
#foo-4 {
    color: #F00;
}

Sont mieux écrits comme:

.foo {
    color: #F00;
}

Où je diffère de CSSLint implique des identifiants structurels qui sont réutilisés.

J'ai souvent marquer les pages avec cette structure:

<div id="page">
    <div id="page-inner">
        <header id="header">
            <div id="header-inner"></div>
        </header>
        <nav id="nav">
            <div id="nav-inner"></div>
        </nav>
        <div id="wrapper">
            <div id="wrapper-inner">
                <div id="content">
                    <div id="content-inner">
                        <article></article>
                        ...
                    </div>
                </div>
                <div id="sidebar">
                    <div id="sidebar-inner">
                        <div class="module"></div>
                        ...
                    </div>
                </div>
            </div>
        </div>
        <footer id="footer">
            <div id="footer-inner"></div>
        </footer>
    </div>
</div>

Et parce que je sais que cette structure est cohérente, cela ne me dérange pas d'utiliser #page, #header, #nav, #wrapper, #content, #sidebar, et #footer dans mon css pour balayer les styles spécifiques à la région. Ces styles sont étroitement couplés à cette structure particulière, ce qui les rend moins réutilisables ; parce que je réutilise la structure, ils sont réutilisables. La chose importante à retenir est que l'utilisation d'un ID dans un sélecteur est très spécifique, et doit être utilisé avec parcimonie.


, quelques mots sur spécificité:

D'une manière générale, il faut utiliser le sélecteur de spécificité le plus bas possible qui effectue la sélection correcte:

Si vous ciblez tous les <a> éléments, alors il est logique d'utiliser a.
Si vous ciblez tous les éléments <a> dans <div class="foo">, Il est logique d'utiliser .foo a.
Si vous ciblez tous les éléments <a> dans <div id="bar">, Il est logique d'utiliser #bar a. cependant , Vous pourriez utiliser un sélecteur de spécificité inférieur. [id="bar"] a a la même spécificité que .foo a, ce qui signifie que vous pouvez toujours cibler des éléments spécifiques par ID sans créer de sélecteurs avec une spécificité inutilement élevée.

Je ne recommande généralement pas d'utiliser des sélecteurs [id="XXXX"] pour sélectionner l'attribut [id], car il est verbeux et peut causer de la confusion. Je ne recommande d'utiliser [data-id="XXXX"] sélecteurs pour la sélection basée sur personnalisé [data-*] attributs pour relier plus étroitement les styles à l'état actuel des nœuds DOM.

24
répondu zzzzBov 2014-01-28 18:02:50

Tout d'Abord:

CSS Lint, comme JS lint est une opinion déguisée en validation, pas une autorité.

J'y suis depuis cinq ans. J'ai travaillé sur de très grands sites de vente au détail, dans des agences interactives, en tant qu'entrepreneur solo, et je suis actuellement dans une entreprise SaaS.

L'idée que les identifiants sont sans équivoque mauvais, IMO n'est qu'une idée à laquelle vous pourriez arriver si votre CSS-fu quand il s'agit de traiter avec des équipes n'était pas génial pour commencer.

Bon, flexible CSS, IMO, suit les meilleures pratiques générales suivantes:

  • Toujours aller du général au particulier. La famille de polices et la taille de police la plus courante pour le corps du texte général, par exemple, ne devraient jamais être déclarées qu'à un seul endroit. Lorsque vous passez à des sélecteurs qui impliquent plus généralement l'utilisation de classes, vous commencerez à remplacer la taille de la police. Quand vient le temps d'appliquer une famille de polices principalement inutilisée à un sous-ensemble très spécifique de HTML, c'est alors qu'il est logique d'utiliser un ID sur un conteneur pour frappez les éléments obtenant la variation du corps du texte.

  • Plus une propriété est généralement appliquée, plus il devrait être facile de remplacer et vous ne devriez jamais vous inquiéter d'écraser vos propriétés les plus générales par accident. Ceci par exemple, body#some_id div, est un sélecteur incroyablement mauvais à utiliser pour cette raison. Au niveau 2nd-ish (il y a 3...ish) où vous traitez généralement plus de paquets d'éléments couramment réutilisés liés à des conteneurs classés, cela devrait être un peu plus difficile d'écraser ces propriétés par accident. "Par accident" arrive plus souvent, IMO, quand vous avez des tas de sélecteurs de plusieurs classes partout. Dans le dernier niveau, vous ne devriez pas traiter d'éléments réutilisables mais de remplacements pour des sections très spécifiques d'un document. L'utilisation d'un ID dans ces circonstances est une pratique idéale, pas mauvaise, mais les ID sont mieux utilisés avec parcimonie et uniquement pour les propriétés spécifiques des éléments dans le conteneur d'élément que l'ID fait besoin de changer.

  • Plus un sélecteur est spécifique, plus il devrait être difficile de le casser par accident. Par spécifique, Je ne veux pas seulement dire des identifiants sur l'élément. Je veux dire un élément de conteneur ID qui se trouve près de l'élément que vous ciblez réellement. Cependant, le dépassement intentionnel devrait toujours impliquer un effort minimal, ce qui signifie que les identifiants vous aident plutôt que de vous gêner (voir l'exemple ci-dessous). Si jamais vous vous trouvez dans une position de " manquer D'identifiants, de classes, et tags " je recommande la violence (au moins la violence imaginaire). Mais sérieusement, quelqu'un mérite d'être frappé.

  • Évitez les longues listes de sélecteurs: Vous devriez commencer à avoir l'impression de "mal faire" chaque fois que vous utilisez régulièrement 4+ valeurs de sélecteurs pour une déclaration. Je ne compterais pas > comme une balise / valeur lors du décompte car l'utilisation de cela à bon escient est une excellente pratique pour la maintenabilité et la performance.

  • Évitez Les Courses Aux Armements Spécifiques: Vous connais le gars. La recrue "ne plaisante pas avec mes affaires" qui a décidé que la meilleure façon de couvrir ses fesses était d'utiliser chaque étiquette, sélecteur et ID qu'il pouvait commencer par le corps. N'engage pas ce mec ou ne lui donne pas de fessée jusqu'à ce qu'il s'arrête. Mais même sur des équipes plus tournées vers l'avenir, les courses aux armements peuvent toujours commencer assez innocemment si vous n'ajoutez pas (avec parcimonie) plus de poids aux sélecteurs dans des endroits où cela a du sens.

L'approche minimaliste en particulier, est énorme. Plus vous comptez sur le placement HTML pour évitez d'avoir besoin de CSS en premier lieu, mieux c'est. Le meilleur travail que vous avez fait à distribuer les styles les plus généraux à l'échelle mondiale, moins vous avez à vous soucier dans des contextes plus spécifiques. Plus les remplacements de propriété hautement spécifiques sont ciblés et concis, plus ils sont faciles à gérer à long terme. Et c'est là que la politique générale de non-identification est stupide IMO.

Quoi de plus pratique et simple à remplacer?

Ceci:

body .main-content .side-bar .sub-nav > ul > li > button

Ou cette?

#sub-nav button

Si vous travaillez généralement en solo ou que vous ne faites que de petits projets pour gagner votre vie en faisant du développement web tout en gagnant votre argent réel lors de conférences, le Supérieur peut vous sembler idiot et peu probable, mais lorsque vous travaillez avec une équipe et que vous suivez une politique de classe uniquement, et que vous venez de vous brûler pour ne pas utiliser une spécificité assez élevée récemment, il serait très facile de commencer à ajouter de plus en plus de classes et de tags à vos affaires (juste pour éviter les problèmes sur un court délai-vous le changerez plus tard bien sûr), ce qui entraîne un désordre alambiqué imprévisible et gargantuesque dans vos fichiers CSS.

Donc: essayez de ne jamais utiliser plus d'un ID et uniquement pour les propriétés locales d'un conteneur qui ne contient pas d'autres conteneurs. Essayez de ne jamais utiliser plus d'une ou deux classes. Évitez les classes et les ID qui ciblent les éléments à partir d'on-high (Les conteneurs qu'ils représentent sont de nombreux nœuds ancêtres ci-dessus). Plus de 3-4 tags est probablement trop dans la plupart cas jusqu'à ce qu'il soit temps pour un peu d'entretien ou de formation/Fessée des recrues. Et suivez la règle boyscout. Zap ces importants et évidemment des sélecteurs trop spécifiques que vous allez quand il est sûr de.

Mais respectez les règles de base plutôt que les "lois" CSS et assurez-vous d'évaluer ces idées à la lumière de l'expérience. Ne faites confiance à personne ou à un outil qui lance des instructions générales comme "Ne jamais utiliser D'ID" pour quelque chose avec autant de variables qu'un scénario de mise en page CSS peut avoir. C'est juste noob kool-aid en ce qui me concerne et les auteurs responsables devraient savoir mieux maintenant s'ils veulent prétendre être des experts en la matière.

14
répondu Erik Reppen 2012-10-04 14:51:17

Leur argument est mentionné par lonesomeday dans leur réponse, qu'il le couple étroitement au HTML et ne permet pas de le réutiliser.

Je pourrais faire un argument, qu'il y a des cas où vous ne voulez pas qu'un style soit utilisé par autre chose qu'un seul élément, donc le spécifier sur un sélecteur d'id aurait du sens.

Tout va descendre à la préférence personnelle. Ce n'est pas une règle dure et rapide à laquelle vous devez adhérer, cela semble être la pensée du CSS Équipe Lint, pas une règle qui provoque des erreurs ou quoi que ce soit.

4
répondu Doozer Blake 2011-11-10 18:42:44

Un gros problème survient lorsque vous gérez beaucoup de CSS ou de grands sites Web. Les ID par définition ne sont pas réutilisables. Mais vous entrez également dans des problèmes de spécificité. Vous entrez dans des conditions de course désagréables avec des styles lorsque vous commencez à changer de spécificité. Les id ont plus de spécificité que les classes, mais les styles en ligne ont plus que les ID. Styles en ligne ont plus de spécificité que les feuilles de style externes. En utilisant des classes, vous standardisez la façon dont les styles sont appliqués à vos éléments, ce qui rend les choses plus prévisibles. Cela tend à faciliter le développement, en particulier lorsque vous travaillez avec plusieurs personnes.

3
répondu hradac 2012-03-15 14:08:30