Как упростить код CSS - PullRequest
       6

Как упростить код CSS

2 голосов
/ 31 августа 2010

Я работаю с существующим фрагментом кода 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;
        }

Моя главная проблема в этом заключается в сложности: каждое правило имеет 3-5 селекторов на нем, что делает очень трудно выяснить, какое правило применяется.Здесь 25 правил для оформления четырех кнопок с текстом.Это не может быть так сложно!

Некоторый фон: этот CSS стилизует виджет, который показывает четыре растровых изображения, одно из которых выбрано, из одного растрового изображения с использованием CSS-спрайтов.Невыбранные изображения поступают из одной строки большого растрового изображения, а изображение в выбранном состоянии - из другой строки.Выбранное изображение помещается в коробку, которая шире и выше, чем коробки невыбранных изображений.

Так есть ли программа, которая упростит это до чего-то познавательно управляемого?Есть ли инструмент, который может определить, какие значения не нужны, потому что они заменены более конкретными селекторами?Существуют ли лучшие практики для работы с CSS, чтобы вы не получали ненужных выборочных путей?


Обновление: 2010-08-31 12: 25

Итак, я изучил Меньше как способ концептуализации кода CSS.И поскольку мой код не меньше, я посмотрел css2less .Вот выдержка из того, что css2less создает в рассматриваемом коде:

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

Так вот в чем дело: apl_widget_levelX на самом деле уникальны.Я думаю, что хороший инструмент мог бы сгенерировать это:

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

Подобные комментарии для выбранных / невыбранных элементов.

Мне нравится, куда идут ответы, но я ищу инструменты, чтобы сделать мою жизньПолегче.Полный код CSS в этом файле составляет 2500 строк, а весь набор - 11000 строк.


Обновление: 2010-09-01 09: 50

Это то, во что я превратил егоот руки:

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

Ранее 175 строк.Сейчас 75 строк.Большая часть кода (40 строк) выполняет CSS-спрайтинг.


Обновление 2010-09-01 11: 30

HTML теперь выглядит так:

<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 ранее выглядел как:

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

Ответы [ 5 ]

3 голосов
/ 31 августа 2010

Ниже приведены только комментарии;Трудно дать однозначные ответы на подобные вопросы, особенно.когда структура HTML недоступна.


Первое, что действительно меня поразило, это длинные имена классов .Когда у вас так много повторений в названии классов, я думаю, что вы делаете что-то не так.Такие имена, как

.apl_widget_fourLevel .apl_widget_level.apl_widget_level1 .apl_widget_panel img

Действительно должны быть сокращены до (что-то вроде):

.apl_widget .fourlevel .panel img

Особенно, когда ваши селекторы в основном повторяются на 90%, как

.apl_widget_level.apl_widget_level1

Там просто нет смысла для этого!В CSS каскад гарантирует наследование, поэтому добавление префикса также для всех имен ваших классов просто необходимо.Конечно, если вы дошли до индексации имен ваших классов, самое время поменять их на id с, например

#level1

Может показаться небольшим, но этодействительно делает CSS более удобным, если у вас есть компактные и менее повторяющиеся селекторы - по крайней мере, вы не будете тратить так много времени на сканирование селекторов.


Если структура HTML виджета одинакова во всем коде, вы можете заменить некоторые классы на элементы.Это, конечно, уменьшит возможность многократного использования стилей, но, учитывая, что виджеты часто не имеют той же структуры и дизайна, что и остальная часть страницы, более простые стили виджетов могут экономить на классах.Селекторы, такие как (скажем)

.profile img

, безусловно, были бы лучше, чем просто дать этому img класс - это и сразу очевидно, что вы делаете, и легко поддерживать в то же время.


Что-то еще, что вы можете сделать, это кодировать только для особых случаев , как этот очень упрощенный случай

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

a.special {
  color: #B8E9FF;
}

a.brilliant {
  color: #FFAFAF;
}

Также удалите повторяющиеся классычто остается неизменным в каждом случае.Опять же, используйте каскад в полном объеме.


3-5 селекторов макс.3-5 для каждый один из них, однако.Селекторы CSS должны логически переходить от простого к сложному, так как добавляется больше случаев.Таким образом, попробуйте найти базу виджета, определите значение по умолчанию и закодируйте свой путь вверх.

Сам фрагмент кода не является слишком плохим, за исключением включения слишком большого и слишком длинного имени класса.Переписывание снизу вверх часто может привести к оптимизации, особенноесли требования проекта изменились со времени последнего разработчика (нам больше не нужно поддерживать IE6, ура!) Но опять же, не видя структуру, трудно принять окончательное решение.

1 голос
/ 02 сентября 2010

Исходя из опубликованного HTML, я бы предложил следующие изменения:

Внутренние классы apl_widget_label и apl_widget_value не нужны и могут быть просто заменены уникальными элементами (которые уникальны в li). Это может сделать селекторы немного длиннее, но гораздо лучше структурированными и более читабельными. Кроме того, div вокруг ссылки не требуется, поскольку ссылку можно стилизовать напрямую.

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

с

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

Вы также можете переместить свойства top, width и height в правилах уровня в правила ul.apl_widget_content li(.selected):

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

Было бы замечательно, если бы вы могли избавиться от идентификаторов «выбранного уровня» (заканчивающихся на s), но я не могу придумать разумного способа, который все еще поддерживает IE6.

Я просто вижу, что вы установили li на display: inline, сохраняя элементы блока внутри их. Вы должны быть осторожны с этим, потому что, несмотря на то, что CSS является технически правильным, его точный рендеринг на самом деле не определен. Вместо этого вы можете рассмотреть display: inline-block или float: left.

1 голос
/ 31 августа 2010

Если бы это было всего лишь для четырех кнопок, я бы поднял страницу в современном браузере и использовал бы инструментарий разработки (Firebug в Firefox, Dragonfly в Opera, инструменты разработчика WebKit в Safari / Chrome) для проверки рассматриваемых кнопок. и посмотрите, какие эффективные стили на каждом.

0 голосов
/ 31 августа 2010

я думаю, что вам нужно изменить имя ваших предложений, я вижу, что вы используете ".apl_widget_label" почти для всего и стилизуете элемент в зависимости от селекторов.

например:

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

почему бы не создать еще один класс с именем "mini-display", и тогда ваш элемент будет выглядеть так:

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

и ваш css будет:

.mini-display{..}

, есливам это не нравится ... я видел некоторых людей, которые создают классы, подобные этому

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

, где каждый класс изменяет что-то определенное для элемента (то есть left => float: left;).И у них есть библиотека классов, которые они всегда используют.

0 голосов
/ 31 августа 2010

Возможно, вы захотите просмотреть эту статью Я прочитал не так давно, у нее есть действительно хороший обзор плюсов и минусов организации вашей CSS. Я бы также взглянул на нижнюю часть статьи, где есть ссылки на дополнительную информацию.

Судя по всему, стили вашего виджета немного переоценили классит, но, по крайней мере, его документально подтверждено, я не могу сосчитать, сколько раз видел недокументированные классы CSS.

...