2010-08-31 3 views
2

Je travaille avec une pièce existante de code CSS qui ressemble à ceci (extrait d'un corps beaucoup plus grand de code):Comment simplifier le code CSS

.apl_widget_fourLevel { 
margin:0 auto 1em; 
overflow:hidden; 
/* zoom:1 */ /* IE Sheet */ 
} 

/* a panel container */ 
.apl_widget_fourLevel .apl_widget_level { 
    float:left; 
    position:relative; 
    overflow:hidden; 
    text-align:center; 
    width:102px; 
    height:150px; 
    margin:0 1px 0 0; 
} 

/* extra height for widgets with the supplementary data beneath the panels */ 
/* reset width for selected mini panels */ 
.apl_widget_fourLevel.apl_widget_client1 .apl_widget_level { 
    height:auto; 
} 

/* extra height for widgets with the supplementary data beneath the panels */ 
/* reset width for selected mini panels */ 
.apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level { 
    height:auto; 
    width:90px; 
} 

/* reset width for selected mini panels */ 
.apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level.apl_widget_levelSelected { 
    width:102px; 
} 

    /* the gray label in the panel 
     enforce for mini display */ 
    .apl_widget_fourLevel .apl_widget_level .apl_widget_label, 
    .apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level.apl_widget_levelSelected .apl_widget_label { 
     position:absolute; 
     top:20px; 
     left:0; 
     width:100%; 
     margin:0; 
     color:#555; 
     font-weight:normal; 
     text-transform:uppercase; 
     font-size:100%; 
     line-height:1.0em; 
     z-index:1; 
    } 

    /* offset for mini labels */ 
    .apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level .apl_widget_label { 
     margin-top:20px; 
     font-size:85%; 
    } 

    /* label cascade reset for IE6, sigh */ 
    .apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level.apl_widget_levelSelected .apl_widget_label { 
     margin-top:0; 
     font-size:100%; 
    } 

    /* the value displayed in the panel */ 
    .apl_widget_fourLevel .apl_widget_level .apl_widget_value, 
    .apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level.apl_widget_levelSelected .apl_widget_value { 
     position:absolute; 
     top:45px; 
     left:0; 
     width:100%; 
     margin:0; 
     color:#fff; 
     font-weight:bold; 
     font-size:28px; 
     line-height:1.0em; 
     z-index:1; 
    } 

    /* offset for mini value */ 
    .apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level .apl_widget_value { 
     margin-top:15px; 
     font-size:24px; 
    } 

    .apl_widget_fourLevel.apl_widget_client1 .apl_widget_level .apl_widget_value { 
     margin-top:3px; 
     font-size:20px; 
     font-weight:normal; 
     opacity:0; 
     -moz-opacity:0; 
     -webkit-opacity:0; 
     filter: alpha(opacity=0); 
    } 

    /* value cascade reset for IE6, sigh */ 
    .apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level.apl_widget_levelSelected .apl_widget_value { 
     margin-top:0; 
     font-size:28px; 
    } 

    /* range values smaller */ 
    .apl_widget_fourLevel.apl_widget_fourLevelRange .apl_widget_level .apl_widget_value { 
     margin-top:7px; 
     font-size:15px; 
    } 

    .apl_widget_fourLevel .apl_widget_value a { 
     color:#fff; 
    } 

    /* supplemental value beneath the panel */ 
    .apl_widget_fourLevel .apl_widget_level .apl_widget_valueScore { 
     position:absolute; 
     bottom:0px; 
     left:0; 
     width:100%; 
     color:#0072ad; 
     font-weight:bold; 
     font-size:28px; 
     z-index:1; 
    } 

    .apl_widget_fourLevel .apl_widget_level .apl_widget_valueScore a { 
     color:#0072ad; 
    } 

    /* low values will be lighter color */ 
    .apl_widget_fourLevel .apl_widget_level.apl_widget_levelLow .apl_widget_valueScore, 
    .apl_widget_fourLevel .apl_widget_level.apl_widget_levelLow .apl_widget_valueScore a { 
     color:#30a2dd; 
    } 

    /* the image container element */ 
    .apl_widget_fourLevel .apl_widget_level .apl_widget_panel { 
     overflow:hidden; 
     width:100%; 
     height:135px; 
     position:relative; 
    } 

     /* the panel image itself */ 
     .apl_widget_fourLevel .apl_widget_level .apl_widget_panel img { 
      position:absolute; 
      top:0; 
      left:-5px; 
      margin-top:-150px; 
     } 

     /* Individual Level image offsets */ 
     .apl_widget_fourLevel .apl_widget_level.apl_widget_level1 .apl_widget_panel img { 
      left:-5px; 
     } 

     .apl_widget_fourLevel .apl_widget_level.apl_widget_level2 .apl_widget_panel img { 
      left:-105px; 
     } 

     .apl_widget_fourLevel .apl_widget_level.apl_widget_level3 .apl_widget_panel img { 
      left:-205px; 
     } 

     .apl_widget_fourLevel .apl_widget_level.apl_widget_level4 .apl_widget_panel img { 
      left:-305px; 
     } 

     /* mini panel offsets */ 
     .apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level .apl_widget_panel img { 
      margin-top:-300px; 
      margin-left:-6px; 
     } 

     /* reset image offset via margin for highlighted/selected style */ 
     .apl_widget_fourLevel .apl_widget_level.apl_widget_levelSelected .apl_widget_panel img { 
      margin:0; 
     } 

Mon grand problème est la complexité: tous les La règle a 3-5 sélecteurs, rendant très difficile de déterminer quelle règle s'applique. Il y a 25 règles pour styliser quatre boutons avec du texte. Ça ne peut pas être si dur! Un peu d'arrière-plan: ce CSS met en forme un widget qui affiche quatre images bitmap, dont l'une est sélectionnée, à partir d'un seul bitmap utilisant des sprites CSS. Les images non sélectionnées proviennent d'une ligne du grand bitmap et l'image dans l'état sélectionné provient d'une autre ligne. L'image sélectionnée est placée dans une boîte plus large et plus grande que les boîtes d'images non sélectionnées.

Alors y a-t-il un programme qui simplifiera cela à quelque chose de gérable cognitivement? Existe-t-il un outil permettant d'identifier les valeurs inutiles car remplacées par des sélecteurs plus spécifiques? Existe-t-il des bonnes pratiques pour gérer CSS, de sorte que vous n'obteniez pas de chemins inutilement sélectifs?


Mise à jour: 2010-08-31 12:25

Je regardé dans less comme une façon de conceptualiser le code CSS. Et parce que mon code n'est pas en moins, j'ai recherché css2less. Voici un extrait de ce css2less produit sur le code en question:

.apl_widget_fourLevel { 
    margin:0 auto 1em; 
    overflow:hidden; 

    .apl_widget_level.apl_widget_level1 { 
     .apl_widget_panel { 
      img { 
       left:-5px; 
      } 
     } 
    } 
    .apl_widget_level.apl_widget_level2 { 
     .apl_widget_panel { 
      img { 
       left:-105px; 
      } 
     } 
    } 
    .apl_widget_level.apl_widget_level3 { 
     .apl_widget_panel { 
      img { 
       left:-205px; 
      } 
     } 
    } 
    .apl_widget_level.apl_widget_level4 { 
     .apl_widget_panel { 
      img { 
       left:-305px; 
      } 
     } 
    } 
    .... 
} 

Alors, voici la chose: apl_widget_levelX sont en fait uniques. Je pense qu'un bon outil pourrait générer ceci:

img#apl_widget_level1 { left:-5px; } 
img#apl_widget_level2 { left:-105px; } 
img#apl_widget_level3 { left:-205px; } 
img#apl_widget_level4 { left:-305px; } 

.apl_widget_fourLevel { 
    margin:0 auto 1em; 
    overflow:hidden; 
    .... 
} 

Commentaires similaires pour les éléments sélectionnés/non sélectionnés. J'aime les endroits où les réponses vont, mais je cherche des outils pour faciliter ma vie. Le code CSS complet dans ce fichier est de 2500 lignes et la suite entière de 11000 lignes.


Mise à jour: 2010-09-01 09:50

C'est ce que je me suis tourné dans la main:

ul.apl_widget_content { 
    width: 492px; 
    height: 140px; 
    position: relative; 
} 
ul.apl_widget_content li { 
    background: url(/home/hbrown/tmp/widget_fourlevel_1.png) no-repeat; 
    list-style: none; 
    display: inline; 
    position: absolute; 
    text-align:center; 
    text-transform:uppercase; 
} 

#apl_widget_level1 { 
    left:5px; top: 0px; 
    background-position: -13px -300px; 
    width: 86px; height: 133px; 
} 
#apl_widget_level2 { 
    left:105px; top: 0px; 
    background-position: -113px -300px; 
    width: 86px; height: 133px; 
} 
#apl_widget_level3 { 
    left:205px; top: 0px; 
    background-position: -213px -300px; 
    width: 86px; height: 133px; 
} 
#apl_widget_level4 { 
    left:305px; top: 0px; 
    background-position: -313px -300px; 
    width: 86px; height: 133px; 
} 
#apl_widget_level1s { 
    left:5px; top: 0px; 
    background-position: -5px 0px; 
    width:102px; height: 133px; 
} 
#apl_widget_level2s { 
    left:105px; top: 0px; 
    background-position: -105px 0px; 
    width:102px; height: 133px; 
} 
#apl_widget_level3s { 
    left:205px; top: 0px; 
    background-position: -205px 0px; 
    width:102px; height: 133px; 
} 
#apl_widget_level4s { 
    left:305px; top: 0px; 
    background-position: -305px 0px; 
    width:102px; height: 133px; 
} 
div.apl_widget_label { 
    padding-top: 35px; 
    font-size: 85%; 
    font-weight:normal; 
    top: 20px; 
    line-height:1em; 
} 
.selected .apl_widget_label { 
    padding-top: 15px; 
} 
div.apl_widget_value { 
    font-size:24px; 
    margin-top:10px; 
} 
.selected div.apl_widget_value { 
    margin-top:15px; 
} 
.apl_widget_value a { 
    text-decoration:none; 
    color:#FFF; 
} 

Auparavant 175 lignes. Maintenant 75 lignes. La majeure partie du code (40 lignes) fait le spriting CSS.


Mise à jour 2010-09-01 11:30

HTML ressemble maintenant à:

<ul class="apl_widget_content"> 
    <li id="apl_widget_level1"> 
     <div class="apl_widget_label">Level </div> 
     <div class="apl_widget_value"><a href="#">1</a></div> 
    </li> 
    <li id="apl_widget_level2"> 
     <div class="apl_widget_label">Level</div> 
     <div class="apl_widget_value"><a href="#">2</a></div> 
    </li> 
    <li id="apl_widget_level3s" class="selected"> 
     <div class="apl_widget_label">Level</div> 
     <div class="apl_widget_value"><a href="#">3</a></div> 
    </li> 
    <li id="apl_widget_level4"> 
     <div class="apl_widget_label">Level</div> 
     <div class="apl_widget_value"><a href="#">4</a></div> 
    </li> 
</ul> 

HTML regardé comme précédemment:

<div class="apl_widget_strand_fourLevel apl_widget_fourLevelMini"> 
    <div class="apl_widget_content"> 
     <div class="apl_widget_level apl_widget_level1 "> 
      <div class="apl_widget_label">Level</div> 
      <div class="apl_widget_value"><a href="#">1</a></div> 
      <div class="apl_widget_panel"> 
       <img alt="" src="widget_fourlevel_1.png"> 
      </div> 
     </div> 
     <div class="apl_widget_level apl_widget_level2 "> 
      <div class="apl_widget_label">Level</div> 
      <div class="apl_widget_value"><a href="#">2</a></div> 
      <div class="apl_widget_panel"> 
       <img alt="" src="widget_fourlevel_1.png"> 
      </div> 
     </div> 
     <div class="apl_widget_level apl_widget_level3 apl_widget_levelSelected"> 
      <div class="apl_widget_label">Level</div> 
      <div class="apl_widget_value"><a href="#">3</a></div> 
      <div class="apl_widget_panel"> 
       <img alt="" src="widget_fourlevel_1.png"> 
      </div> 
     </div> 
     <div class="apl_widget_level apl_widget_level4 "> 
      <div class="apl_widget_label">Level</div> 
      <div class="apl_widget_value"><a href="#">4</a></div> 
      <div class="apl_widget_panel"> 
       <img alt="" src="widget_fourlevel_1.png"> 
      </div> 
     </div> 
    </div>      
</div> 
+0

Pourriez-vous montrer du HTML? Il est plus facile d'optimiser les CSS en fonction de l'apparence du HTML, et peut-être que le fait de modifier le code HTML peut conduire à des CSS plus optimisées. – RoToRa

+0

Et avez-vous besoin de soutenir IE6? Il peut y avoir d'autres optimisations possibles en utilisant des choses que IE6 ne supporte pas. – RoToRa

+0

@RoToRa: ajout de HTML. Oui, le support IE6 est requis. Testé dans Firefox, ahem. – hughdbrown

Répondre

1

Basé sur le HTML affiché le je vous suggère les modifications suivantes:

Les classes internes apl_widget_label et apl_widget_value ne sont pas nécessaires et peuvent simplement remplacés par des éléments uniques (qui est unique dans le li). Cela peut rendre les sélecteurs légèrement plus longs, mais beaucoup mieux structurés et plus lisibles. De plus, le div autour du lien est inutile car le lien peut être stylisé directement.

<ul class="apl_widget_content"> 
    <li id="apl_widget_level1"> 
     <div>Level </div><a href="#">1</a> 
    </li> 
    ... 

avec

.apl_widget_content li div { 
    padding-top: 35px; 
    font-size: 85%; 
    font-weight:normal; 
    top: 20px; 
    line-height:1em; 
} 
.apl_widget_content li.selected div { 
    padding-top: 15px; 
} 
.apl_widget_content li a { 
    font-size:24px; 
    margin-top:10px; 
    text-decoration:none; 
    color:#FFF; 
    display: block; 
} 
.apl_widget_content li.selected a { 
    margin-top:15px; 
} 

Vous pouvez également déplacer les top, width et height propriétés dans les règles de niveau aux ul.apl_widget_content li(.selected) règles:

ul.apl_widget_content li { 
    ... 
    top: 0px; 
    width: 86px; 
    height: 133px; 
} 

ul.apl_widget_content li.selected { 
    width:102px; 
} 

#apl_widget_level1 { 
    background-position: -13px -300px; 
} 

Ce serait génial si vous pouviez obtenir débarrasser des identifiants de "niveau sélectionné" (ceux se terminant par s), mais je ne peux pas penser à un moyen raisonnable qui s UPS IE6.

Je viens de voir que vous avez défini le li à display: inline tout en conservant les éléments de bloc à eux. Vous devrez faire attention à cela, car en dépit d'être CSS correct technique son rendu exact n'est pas vraiment défini. Vous pouvez considérer display: inline-block ou float: left à la place.

+0

Et j'aime ça. Je repars avec l'impression, cependant, qu'il n'y a pas de bons outils pour refactoriser ou rationaliser CSS. Passage à l'affichage: inline-block et float: left n'a pas changé l'apparence de FF. J'imagine que c'est ce que vous attendiez. – hughdbrown

+0

J'ai créé un bon CSS pour les navigateurs compatibles, mais j'avais le bogue "float double marge" et le bogue "parent réduit de float element" dans IE6. Fin de la fixation avec "display: inline;" qui, vous le rappelez, n'est pas précis CSS. – hughdbrown

+0

Je souhaite toujours qu'il y avait des outils pour cela. – hughdbrown

1

Si c'est juste pour quatre boutons , Je voudrais tirer la page dans un navigateur moderne et utiliser une boîte à outils de développement (Firebug dans Firefox, Dragonfly dans Opera, le WebKit développer dans Safari/Chrome) pour inspecter les boutons en question et voir quels sont les styles efficaces sur chacun.

0

Vous voudrez peut-être aller sur this article Je lis pas trop longtemps, il a un très bon aperçu des avantages et inconvénients de l'organisation de votre CSS. Je voudrais aussi jeter un oeil au bas de l'article, il a des liens vers d'autres informations. Du point de vue des choses, les styles de votre widget ont semblé aller un peu trop loin avec le classitis, mais au moins c'est documenté, je ne peux pas compter le nombre de fois que j'ai vu des classes css non documentées.

0

Je pense que vous devez changer le nom de vos classes, je vois que vous utilisez ".apl_widget_label" pour presque tout et stylisant l'élément en fonction des sélecteurs.

par exemple:

/* the gray label in the panel 
    enforce for mini display */ 
    .apl_widget_fourLevel .apl_widget_level .apl_widget_label, 
    .apl_widget_fourLevel.apl_widget_fourLevelMini .apl_widget_level.apl_widget_levelSelected .apl_widget_label { 

Pourquoi ne pas créer une autre classe appelée "mini-écran", puis votre élément serait comme:

<div class=".apl_widget_label mini-display">..</div> 

et votre code CSS serait:

.mini-display{..} 

si vous ne l'aimez pas ... j'ai vu des gens qui créent les classes comme ça

<div class="left margin-auto big red ...">..</div> 

où chaque classe change quelque chose de spécifique sur l'élément (c'est-à-dire left => float: left;). Et ils ont comme une bibliothèque de classes qu'ils utilisent toujours.

3

Ce qui suit sont juste des commentaires; Il est difficile de donner des réponses définitives à des questions comme celle-ci, en particulier. lorsque la structure HTML n'est pas disponible.


La première chose qui m'a vraiment été les noms de classes longues . Quand vous avez tellement de répétitions dans le nom des classes, je pense que vous faites quelque chose de mal. Des noms comme

.apl_widget_fourLevel .apl_widget_level.apl_widget_level1 .apl_widget_panel img 

Vraiment devrait être raccourci à (quelque chose comme):

.apl_widget .fourlevel .panel img 

Surtout quand vos sélecteurs sont essentiellement 90% répétitif, comme

.apl_widget_level.apl_widget_level1 

Il y a juste aucun point pour cette ! En CSS, la cascade garantit l'héritage, donc ajouter un préfixe aussi tous vos noms de classe est juste nécessaire. Certes, si vous avez obtenu au point de indexation vos noms de classe, il est temps de les échanger pour id s, comme

#level1 

Il peut semble petit, mais il fait vraiment CSS plus maintenable si vous Il y a des sélecteurs qui sont compacts et moins répétitifs - au moins, vous ne passerez pas autant de temps à scruter les sélecteurs.


Si la structure HTML du widget est le même dans tout le code, vous pouvez réellement échanger sur certaines des classes pour les éléments.Il va bien sûr réduire la réutilisabilité du style, mais étant donné que les widgets ne partagent souvent pas la même structure et le même design que le reste de la page, il devrait être possible pour les styles de widget plus simples de lésiner sur les classes. Selectors comme (par exemple)

.profile img 

serait certainement mieux que de simplement donner cette img une classe - ses deux immédiatement évident ce que vous faites, et facile à entretenir en même temps.


autre chose que vous pouvez faire est de que du code pour les cas particuliers, comme ce cas

a { 
    color: white; 
    background: #666; 
    text-decoration: none; 
} 

a.special { 
    color: #B8E9FF; 
} 

a.brilliant { 
    color: #FFAFAF; 
} 

très simplifiée Aussi, supprimer les redoublements qui reste le même dans chaque cas. Encore une fois, utilisez la cascade à son plein potentiel.


3-5 sélecteurs max n'est pas inhabituel. 3-5 pour tous les l'un d'eux est, cependant. Les sélecteurs CSS devraient logiquement aller du simple au complexe, car plus de cas sont ajoutés. Ainsi, essayez de trouver la base du widget, définissez un défaut, et codez votre chemin.

L'extrait de code lui-même n'est pas trop mauvais sauf pour l'inclusion de noms de classe trop nombreux et trop longs. Réécrire du bas vers le haut mais peut souvent conduire à des optimisations, esp. si les exigences du projet ont changé depuis le dernier développeur (nous n'avons plus besoin de supporter IE6, bravo!) Mais encore une fois, sans voir la structure il est difficile de faire des solutions définitives.

+0

v. Les bons points ici –