Pergunta

Estou trabalhando com um pedaço de código CSS existente que se parece com isso (extraído de um corpo de código muito maior):

.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;
        }

Meu principal problema com isso é a complexidade: toda regra tem 3-5 seletores, dificultando a descoberta de qual regra se aplica. Existem 25 regras aqui para modelar quatro botões com texto. Não pode ser tão difícil!

Alguns antecedentes: este CSS estiliza um widget que mostra quatro imagens de bitmap, uma das quais é selecionada, a partir de um único bitmap usando sprites CSS. As imagens não selecionadas vêm de uma linha do grande bitmap e a imagem no estado selecionado vem de outra linha. A imagem selecionada é colocada em uma caixa mais larga e mais alta que as caixas de imagens não selecionadas.

Então, existe um programa que simplificará isso para algo cognitivamente gerenciável? Existe uma ferramenta que pode identificar quais valores são desnecessários porque são substituídos por seletores mais específicos? Existem práticas recomendadas para lidar com o CSS para que você não fique desnecessariamente seletivo?


Atualização: 2010-08-31 12:25

Então eu olhei para menos como uma maneira de conceituar o código CSS. E porque meu código não está em menos, eu olhei para cima css2less. Aqui está um trecho do que o CSS2less produz no código em questão:

.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;
            }
        }
    }
    ....
}

Então, aqui está a coisa: apl_widget_levelx é realmente exclusivo. Eu acho que uma boa ferramenta poderia gerar isso:

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;
    ....
}

Comentários semelhantes para os elementos selecionados/não selecionados.

Gosto de onde as respostas estão indo, mas estou procurando ferramentas para facilitar minha vida. O código CSS completo neste arquivo é de 2500 linhas e toda a suíte é de 11000 linhas.


Atualização: 2010-09-01 09:50

Isso é o que eu transformei à mão:

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

Anteriormente 175 linhas. Agora 75 linhas. A maior parte do código (40 linhas) o CSS aumenta.


Atualização 2010-09-01 11:30

HTML agora parece:

<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 anteriormente parecia:

<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>
Foi útil?

Solução

Com base no HTML postado, sugiro seguir as alterações:

As classes internas apl_widget_label e apl_widget_value são desnecessários e podem simplesmente substituídos por elementos únicos (que é único no li). Isso pode tornar os seletores um pouco mais longos, mas muito melhor estruturados e mais legíveis. Também o div Em torno do link é desnecessário, pois o link pode ser estilizado diretamente.

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

com

.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;
}

Você também pode mover o top, width e height propriedades no nível regras para o ul.apl_widget_content li(.selected) as regras:

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

Seria ótimo se você pudesse se livrar dos IDs de "nível selecionado" (os que terminam com s), mas não consigo pensar em uma maneira razoável que ainda suporta o IE6.

Eu só vejo que você definiu o li para display: inline enquanto mantém os elementos do bloco os inseram. Você precisará ter cuidado com isso, porque, apesar de ser o CSS correto técnico, sua renderização exata não é realmente definida. Você pode considerar display: inline-block ou float: left em vez de.

Outras dicas

Os seguintes são apenas comentários; É difícil dar respostas definitivas a perguntas como essa, esp. Quando a estrutura HTML não está disponível.


A primeira coisa que realmente me pegou foi o nomes de classe longa. Quando você tem tanta repetição dentro do nome Das aulas, acho que você está fazendo algo errado. Nomes como

.apl_widget_fourLevel .apl_widget_level.apl_widget_level1 .apl_widget_panel img

Realmente deve ser abreviado para (algo como):

.apl_widget .fourlevel .panel img

Especialmente quando seus seletores são basicamente 90% repetitivos, como

.apl_widget_level.apl_widget_level1

Não há sentido para isso! No CSS, a cascata garante a herança, portanto, adicionar um prefixo também todos os nomes de suas classes são necessários. Certamente se você chegou ao ponto de indexação seus nomes de classe, é hora de trocá -los por ids, como

#level1

Pode parecer pequeno, mas realmente torna o CSS mais sustentável se você tiver seletores que sejam compactos e menos repetitivos - pelo menos você não gastará tanto tempo digitalizando os seletores.


Se a estrutura HTML do widget for a mesma em todo o código, você poderá trocar algumas das classes por elementos. É claro que reduzirá a reutilização de estilo, mas, como os widgets geralmente não compartilham a mesma estrutura e design que o restante da página, deve ser possível para que estilos de widgets mais simples economizem nas aulas. Seletores como (digamos)

.profile img

certamente seria melhor do que apenas dar isso img Uma aula - é imediatamente óbvio o que você está fazendo e fácil de manter ao mesmo tempo.


Outra coisa que você pode querer fazer é Apenas código para casos especiais, como este caso muito simplificado

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

a.special {
  color: #B8E9FF;
}

a.brilliant {
  color: #FFAFAF;
}

Além disso, remova as classes repetidas que permanecem as mesmas em cada caso. Novamente, use a cascata em todo o seu potencial.


3-5 Seletores Max não é incomum. 3-5 para todo Um deles é, no entanto. Os seletores CSS devem ir logicamente de simples para complexo, à medida que mais casos são adicionados. Assim, tente encontrar a base do widget, defina um padrão e codifique o seu caminho para cima.

O próprio trecho de código não é também Ruim, exceto pela inclusão de muitos nomes de classe muito longos. A reescrita de baixo para cima, embora muitas vezes possa levar a otimizações, esp. Se os requisitos do projeto mudaram desde o último desenvolvedor (não precisamos mais apoiar o IE6, Hurrah!), Mas, novamente, sem ver a estrutura, é difícil fazer soluções definitivas.

Se for apenas para quatro botões, eu puxaria a página em um navegador moderno e usaria um kit de ferramentas de desenvolvimento (Firebug no Firefox, Dragonfly na ópera, as ferramentas de desenvolvedor do Webkit no Safari/Chrome) para inspecionar os botões em questão e ver o que Os estilos efetivos estão em cada um.

Você pode querer ir Este artigo Eu li não muito tempo atrás, ele tem uma visão geral muito boa dos profissionais e dos vigaristas de organizar seu CSS. Eu também daria uma olhada na parte inferior do artigo, ele possui alguns links para mais informações.

Pela aparência das coisas que seus estilos de widgets pareciam exagerar com a classite, mas pelo menos está documentado, não posso contar o número de vezes que vi aulas de CSS sem documentos.

Eu acho que você precisa alterar o nome de suas clases, vejo que você está usando ".apl_widget_label" para quase tudo e estilizando o elemento, dependendo dos seletores.

por exemplo:

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

Por que não criar outra classe chamada "Mini-Display" e então seu elemento seria como:

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

E seu CSS seria:

.mini-display{..}

Se você não gosta ... eu já vi algumas pessoas que criam as aulas assim

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

onde cada classe altera algo específico no elemento (ou seja, esquerda => float: esquerda;). E eles têm como uma biblioteca de aulas que sempre usam.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top