Блокируем нежелательные HTML-элементы с помощью CSS

Часто, когда мы сдаем проект клиенту, мы теряем контроль над HTML-кодом. Иногда клиент использует CMS (Системы Управления Контентом), которые дают ему полный контроль над теми или иными частями HTML-кода. Иногда клиент просто использует наши темплейты для вывода своего кода в документ.

В большинстве случаев довольно тяжело проинформировать клиента о том, как использовать темплейты или CMS, которые вы ему предоставляете, а иногда просто неприемлемо толкать пламенные речи о семантической верстке и веб-стандартах. Клиент может/будет использовать “старую, добрую разметку”, ту, которую он знает, просто потому что она работает и выглядит так как он привык. Скорее всего в ней будут присутствовать нежелательные (deprecated) тэги и атрибуты, такие как bgcolor, align и “вечный” font. Эта статья о том, как блокировать нежелательные HTML-тэги с помощью CSS, тем самым аккуратно направляя клиента в правильном направлении.

Есть несколько решений проблемы. Одно из них – вывод предупреждающего изображения с помощью CSS, когда изпользуются нежелательные тэги. Подробные обьяснения этого способа есть здесь и здесь. Второе решение – “вырезание” нежелательных тегов и атрибутов на стороне сервера. Этот способ является наиболее эффективным, другое дело что не всегда есть контроль за сервером где расположен сайт.

Идея состоит в том, чтобы сохранить естественный каскад и наследие стилей во всех браузерах, элегантно “отключая” HTML, нежелательный к использованию клиентом. И тогда клиент перестанет использовать его, потому что нежелательные тэги просто перестанут “работать”. Элегантный и ненапрягающий клиента способ, который направит его по верному пути.

Нежелательные HTML-тэги и атрибуты:

 <font>
<basefont>
<center>
<strike>
<s>
<u>
bgcolor
border
align
vspace
hspace
valign
width
height

Решение

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

На пример этот CSS:

 font { color:inherit; } 

будет превалировать над этим кодом:

 <font color="blue">blue</font> 

Соответственно цвет текста внутри тэга font будет цветом, наследуемым по каскаду, а не синим, как задано в коде. То что надо. Но как вы наверняка знаете – у Internet Explorer есть проблемы с наследуемыми значениями. И в седьмой версии тоже. Так что за работу:

Expressions и currentStyle в помощь:

 font {
color:inherit; /* Нормальные браузеры */
color:expression(this.parentNode.currentStyle["color"]); /* IE */ }

Работает? Отлично, поехали дальше:

 font {
font-family:inherit; /* Нормальные браузеры */
font-family:expression(this.parentNode.currentStyle["fontFamily"]); /* IE */
} 

Все чудесно, кроме того что Opera 9 не наследует значение для font-family. К счастью font нас тоже устроит:

 font {
font:inherit; /* Нормальные браузеры */
font-family:expression(this.parentNode.currentStyle["fontFamily"]); /* IE */
}

С этим разобрались. Перейдем к свойству font-size. Здесь нужна деликатность, так как значение размера шрифта наследуется по отношению к вычисляемому (computed) значению. Предыдушие expression‘ы здесь не сработают, так как если для body выставлено значение свойства font-size, равное 2em, то вычисление значения размера шрифта начнется от этой точки. Браузер проверит значение font-size для родительского элемента тэга font, которое равняется 2em и представит вычисляемое значение, равное 4em (2em от 2em). А это не то что нам нужно. Решение простое. Нужно использовать начальное значение font-size, равное 100% для всех браузеров. Давайте добавим несколько свойств нежелательному тэгу basefont, чтобы и его утихомирить. Вот полный список правил для “укрощения” тэгов font и basefont:

 font,basefont {
color:inherit; /* Нормальные браузеры */
color:expression(this.parentNode.currentStyle["color"]); /* IE */
font:inherit; /* Нормальные браузеры. Font вместо font-size для Оперы */
font-family:expression(this.parentNode.currentStyle["fontFamily"]); /* IE */
font-size:100%; /* Все браузеры. Размеры наследуются */
}

Двигаемся дальше. Давайте воспользуемся базовой техникой, чтобы отменить тэги center, s, strike и u:

center {
text-align:inherit; /* Нормальные браузеры */
text-align:expression(this.parentNode.currentStyle["textAlign"]); /* IE */
}
s,strike,u {
text-decoration:inherit; /* Нормальные браузеры */
text-decoration:expression(this.parentNode.currentStyle["textDecoration"]); /* IE */
}

Свершилось! Мы “отключили” большинство нежелательных тэгов, используя только CSS и expression’ы.

А как же атрибуты? HTML4 включает в себя некоторое количество нежелательных атрибутов, которые могут изрядно попортить нервы. Давайте их тоже “повыключаем”. Начнем с align:

*[align] { text-align:inherit; } /* Нормальные браузеры */

Все бы хорошо, но IE6 не поддерживает селекторы атрибутов. Посему, нам надо модифицировать expression, для того чтобы он проверял наличие атрибута align у тэга. Вот что получилось:

*[align] { text-align:inherit; } /* Нормальные браузеры */
* { text-align:expression(this.align ? this.parentNode.currentStyle["textAlign"] : ''); } /* IE */

Далее на очереди атрибуты тэга img. Помимо атрибута align, мы хотим отключить атрибуты border, vspace и hspace. Так как значения margin и border не наследуются, то здесь применимо простое правило:

img { margin:0; border:none; } /* Все браузеры */ 

Вот здесь мы как раз сталкиваемся с неразрешимой проблемой для IE6. vspace и hspace не равнозначны свойству margin в нем, поэтому IE6 будет продолжать отображать их. Единственное решение, которое пришло мне в голову это написать маленький скриптик, который будет просто удалять эти атрибуты при загрузке документа:

window.onload = function() {
for (i=0;i
document.getElementsByTagName("img")[i].removeAttribute("vspace");
document.getElementsByTagName("img")[i].removeAttribute("hspace");
}
}

Я бы предпочел не использовать javascript, но в данном случае я просто не вижу другой альтернативы. Так что пусть будет. Теперь добьем атрибут type в тэге ol:

ol { list-style-type:decimal; } /* Все браузеры */

А теперь атрибут bgcolor для body:

body { background-color:transparent; } /* Все браузеры */

Таблицы. Финальный шаг. В таблицах, в HTML4/4.01, есть ряд нежелательных атрибутов, которые активно использовались для верстки страниц. Но мы же не хотим, чтобы клиент использовал таблицы для верстки? Поэтому давайте отключим атрибуты width, height, bgcolor, valign и border:

table,tr,th,td {
width:auto; /* Все браузеры */
height:auto; /* Все браузеры */
background-color:transparent; /* Все браузеры */
vertical-align:inherit; /* Все браузеры (включая IE) */
border:none; /* Все браузеры */
}

Подведем итоги:

Используя CSS-правила и минимальный javascript, нам удалось “отключить” большинство нежелательных тэгов и атрибутов, элегантно сохраняя естественное наследование. Нам не нужно “учить” клиента, он в любом случае должен будет использовать правильную разметку. С учетом одной, очень важной ремарки – очень важно предоставить клиенту достаточное количество описаных CSS-классов, чтобы он не был ограничен в работе с разметкой.

Все стили вместе:

font,basefont {
color:inherit; /* Нормальные браузеры */
color:expression(this.parentNode.currentStyle["color"]); /* IE */
font:inherit; /* Нормальные браузеры. Font вместо font-size для Оперы */
font-family:expression(this.parentNode.currentStyle["fontFamily"]); /* IE */
font-size:100%; /* Все браузеры */
}
center {
text-align:inherit; /* Нормальные браузеры */
text-align:expression(this.parentNode.currentStyle["textAlign"]); /* IE */
}
s,strike,u {
text-decoration:inherit; /* Нормальные браузеры */
text-decoration:expression(this.parentNode.currentStyle["textDecoration"]); /* IE */
}
*[align] { text-align:inherit; }  /* Нормальные браузеры */
* { text-align:expression(this.align ? this.parentNode.currentStyle["textAlign"] : ''); }  /* IE */
img { margin:0; border:none; }  /* Все браузеры */
ol { list-style-type:decimal; }  /* Все браузеры */
body { background-color:transparent; /* Все браузеры */ }
table,tr,th,td {
width:auto; /* Все браузеры */
height:auto; /* Все браузеры */
background-color:transparent; /* Все браузеры */
vertical-align:inherit; /* Все браузеры (включая IE) */
border:none; /* Все браузеры */
}

По материалам monc.se

19 thoughts on “Блокируем нежелательные HTML-элементы с помощью CSS

  1. Ух ты! Хорошая идея, и грамотное воплощение! Спасибо!

  2. Всем привет!

    Кто-то использует TinyMCE (редактор) или что-то подобное? Ведь он занимается тем-же самым – постоянно пихает свои атрибуты в создаваемые в нем теги. Предложенное способно устранить эти косяки?

  3. [quote comment="2207"]Всем привет! Кто-то использует TinyMCE (редактор) или что-то подобное? Ведь он занимается тем-же самым – постоянно пихает свои атрибуты в создаваемые в нем теги. Предложенное способно устранить эти косяки?[/quote]

    Думаю что да.

  4. А почему бы не вырезать эти теги и атрибуты перед сохранением в базу, или перед отображением на сайте, получится надежней и проще.

    Встраиваем соответствующий фильтр в CMS клиента и проблемы нет.

    Как бонус получаем валидный HTML и CSS.

  5. Евгений, когда это возможно то так и надо делать, но такая возможность есть не всегда.

  6. > Евгений, когда это возможно то так и надо делать, но такая возможность есть не всегда.

    Если заниматься web-разработкой серьёзно, то такая возможность есть всегда и, думаю, во всех cms-системах. Берём и пишем плагин или заказываем.

    А вообще статья очень полезная. Спасибо.

  7. Сорри за полуоффтоп.

    Это у меня одного в мозиле косяки с кусками кода, если смотреть эту страницу не в развернутом виде?))

  8. Ну, если уменьшать размер окна браузера ( да или просто смотреть его не в полноэкранном режиме) то длинные строки кода начинают вылазить за границы.

    Например, "<i>* { text-align:expression(this.align ? this.parentNode.currentStyle["textAlign"] : ”); } /* IE */</i>"

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

  9. Все изложенное в этой статье взял себе на заметку,автору благодарность

  10. Такой ксс не пройдет валидацию (((
    Если только сформировать его через документ.врайт, чтобы валидатор его проигнорировал, но это извращение…

  11. Валидацию CSS пройдет, если вынести экспрешены в отдельный css для ИЕ6 :)

    А вот второе, что хотел подметить – я знаю точно что ТиниМЦЕ настраивается очень и очень хорошо и в правильных руках он не пихает ничего лишнего в код.

  12. **алово какое-то… Какое дело, что клиент сделает с версткой? проект сдан, бухглатерия закрыта..

    А если в верстке нужно сделать обычную, человечесскую таблицу? Дивами? не думаю, что это здорово…

Leave a Reply

Your email address will not be published. Required fields are marked *