Пропустить навигацию

Избавляемся от устаревших тэгов и атрибутов с помощью CSS

12.11.2007 , ,

В момент сдачи проекта существует возможность потерять контроль над исходным HTML кодом. Некоторые части кода целиком могут заменяться динамически при помощи CMS, иногда заказчики сами редактируют шаблоны, добавляя собственную разметку.

Порой довольно сложно объяснить заказчику о том, как правильно пользоваться и редактировать шаблоны, о семантике разметки и стандартах. Заказчики часто используют свою простейшую разметку, которую они когда-то выучили и запомнили, поскольку она по прежнему выполняет все те задачи, необходимые для визуального представления документа. Скорее всего будет использоваться т.н. deprecated HTML тэги и атрибуты, такие как bgcolor, align и этот ужасный тэг <font>. Данная статья поможет избавится от всех этих тэгов при помощи CSS, постепенно направляя клиента на правильный путь.

Существует несколько решений данной проблемы. Первый, при использовании deprecated HTML добавить картинку с предупреждением при помощи CSS (подробнее о таком методе можно ознакомиться здесь или здесь). Другой подход - это написать серверный скрипт, удаляющий устаревшие тэги и атрибуты. Несмотря на то что этот подход наиболее эффективный, однако не всегда у вас может быть полный контроль над сервером, кроме этого заказчик может вообще не использовать CMS и редактировать все "руками".

Идея

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

страница с примером, демонстрирующая работу данного подхода.

Deprecated HTML

Список наиболее популярных deprecated HTML 4 тэгов и атрибутов:

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

Решение и проблемы

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

font { color:inherit; }

…перепишет следующий код HTML:

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

Тэг <font> будет отображен браузером с наследованным цветом, а не синим (blue). Именно то, что нам и требовалось. Как вы, наверное, знаете, в IE существует некоторая проблема с наследуемыми значениями, даже в 7-й версии.

Expressions и currentStyle

Значение inherit очень легкое для понимания. Некоторые CSS свойства имеют дефолтные значения наследования, наследуя значение родителя для определенных свойств. Проблема заключается в том, что если использовать например устаревший inline атрибут, такой как color наследование будет проигнорировано, даже если указать его в CSS. Поскольку IE в большинстве случаев игнорирует наследуемое значение, возникает проблема.

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

font {
 color:inherit; /* standard browsers */
 color:expression(this.parentNode.currentStyle['color']); /* IE */
}

Воспользовавшись подобным подходом мы можем скрыть устаравшие тэги и атрибуты во всех браузерах

Есть еще несколько моментов, которые имеет смысл рассмотреть, перед тем как начнем скрывать тэги.

Font-Family и font-size

Используя технику, предложенную выше можем отключить атрибут face в тэге font

font {
 font-family:inherit; /* standard browsers */
 font-family:expression(this.parentNode.currentStyle['fontFamily']); /* IE */
}

Opera 9 не наследует font-family. Поэтому заменим font-family на font:

font {
 font:inherit; /* standard browsers */
 font-family:expression(this.parentNode.currentStyle['fontFamily']); /* IE */
}

Теперь перейдем к размеру шрифта font-size. Этот момент очень тонкий, поскольку наследование размера шрифта есть вычисленное значение. expression здесь не подойдет, поскольку если мы задали размер шрифта для body 2em, расчет и наследование будет производиться от этого значения. Выход здесь тоже простой, задать font-size: 100% для всех браузеров, тем самым мы избегаем любых дополнительных расчетов.

Давайте добавим такие же значения для тэга <basefont>. Ниже представлен полный CSS код для отключения тэгов <font> и <basefont>:

font,basefont {
 color:inherit; /* Standard browsers */
 color:expression(this.parentNode.currentStyle['color']); /* IE */
 font:inherit; /* Standard browsers. Font instead of font-size for Opera */
 font-family:expression(this.parentNode.currentStyle['fontFamily']); /* IE */
 font-size:100%; /* All browsers. Sizes are inherited */
}

Идем далее

Попробуем применить подобную технику к тэгам <center>, <s>, <strike> и <u>:

center {
 text-align:inherit; /* Standard browsers */
 text-align:expression(this.parentNode.currentStyle['textAlign']); /* IE */
}
s,strike,u {
 text-decoration:inherit; /* Standard browsers */
 text-decoration:expression(this.parentNode.currentStyle['textDecoration']); /* IE */
}

Атрибуты

HTML 4 включает ряд deprected атрибутов. Отключаем атрибут align:

*[align] { text-align:inherit; }  /* Standard browsers */

Атрибутные селекторы не работают в IE6. Добавим выражение, которое проверит наличие атрибута align и получим CSS, отключающий атрибут выравнивания во всех браузерах:

*[align] { text-align:inherit; }  /* Standard browsers */
* { text-align:expression(this.align ? this.parentNode.currentStyle['textAlign'] : ''); }  /* IE */

Перейдем к атрибутам тэга <img>. В дополение к align, отключим border, vspace и hspace. Поскольку границы и бордюры не наследуются, получим следующий код:

img { margin:0; border:none; }  /* All browsers. Borders & margins are not inherited */

vspace и hspace не является границей (margin), поэтому IE6 по прежнему применит vspace и hspace . пришлось написать небольшой скрипт, удаляющий данные атрибуты при загрузке:

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

Хотелось бы избежать использования скриптов, но другой альтернативы не нашел. Далее, убираем атрибут type в нумерованных списках <ol>:

ol { list-style-type:decimal; }  /* All browsers. Removes the type attribute */

И bgcolor тэга body:

body { background-color:transparent; /* All browsers */ }

Таблица

Избавляемся от width, height, bgcolor, valign и border

table,tr,th,td {
 width:auto; /* All browsers */
 height:auto; /* All browsers */
 background-color:transparent; /* All browsers */
 vertical-align:inherit; /* All browsers (works in IE) */
 border:none; /* All browsers. Borders are not inherited */
}

В заключение

Используя подобный подход можно избавиться от устаревших тэгов и атрибутов.

Код полностью:

  <style type="text/css">

  font,basefont {
    color:inherit; /* Standard browsers */
    color:expression(this.parentNode.currentStyle['color']); /* IE */
    font:inherit; /* Standard browsers. Font instead of font-size for Opera */
    font-family:expression(this.parentNode.currentStyle['fontFamily']); /* IE */
    font-size:100%; /* All browsers. Sizes are inherited */
  }
  center {
    text-align:inherit; /* Standard browsers */
    text-align:expression(this.parentNode.currentStyle['textAlign']); /* IE */
  }
  s,strike,u {
    text-decoration:inherit; /* Standard browsers */
    text-decoration:expression(this.parentNode.currentStyle['textDecoration']); /* IE */
  }
  *[align] { text-align:inherit; }  /* Standard browsers */
  * { text-align:expression(this.align ? this.parentNode.currentStyle['textAlign'] : ''); }  /* IE */
  img { margin:0; border:none; }  /* All browsers. Borders & margins are not inherited */
  ol { list-style-type:decimal; }  /* All browsers. Removes the type attribute */
  body { background-color:transparent; /* All browsers */ }
  table,tr,th,td {
    width:auto; /* All browsers */
    height:auto; /* All browsers */
    background-color:transparent; /* All browsers */
    vertical-align:inherit; /* All browsers (works in IE) */
    border:none; /* All browsers. Borders are not inherited */
  }

  </style>
  <script type="text/javascript">
  window.onload = function() {
    for (i=0;i<document.getElementsByTagName('img').length;i++) {
      document.getElementsByTagName('img')[i].removeAttribute('vspace');
      document.getElementsByTagName('img')[i].removeAttribute('hspace');
    }
  }
  </script>

Оригинал статьи

Комментарии