30.06.2008

JavaScript + CSS

Задача: Подружить JavaScript и CSS, чтобы при отсутствии JavaScript применялись немного другие стили.

Предположим, что у нас есть блок <div id="block">блок</div>, который изначально должен быть скрыт и появляться по нажатию на псевдоссылку <span id="link">псевдоссылка</span>. Если же джаваскрипта нет, то блок должен показаться сразу, а псевдоссылка спрятаться с глаз долой.

Вариант 1. С использованием тега <noscript> (олд скул)

<style type="text/css">
    #block {display: none;}
</style>

<noscript>
    <style type="text/css">
        #block {display: block;}
        #link {display: none;}
    </style>
</noscript>

Это работает, но приходится создавать отдельный кусок стилей. К тому же валидатор ругается что есть сил, поскольку <style> запрещен внутри <noscript>, а <noscript> запрещен внутри <head>. Плохой способ, не рекомендую так делать.

Вариант 2.

Гораздо лучше пойти по пути последовательного улучшения (progressive enhancement), суть которого заключается в том, что сначала мы добиваемся корректной работы в самом простом, доступном окружении (в данном случае — в браузере с неработающим джаваскриптом), а затем постепенно улучшаем наше решение, добавляя функционал для повышения удобства пользователей в браузерах поддерживающих этот функционал.

Это означает, что стили изначально должны быть настроены для случая отсутствия джаваскрипта. Далее загружается джаваскрипт, находит наш блок и скрывает его, находит псевдоссылку и показывает ее. Недостаток такого решения в том, что блок может «моргать» — пользователь может увидеть его на какое-то короткое время (пока загружается и выполняется джаваскрипт).

Вариант 3.

Как можно побороть моргание блока? Я использую такое решение. В теге <head> добавляем простую строчку:

<script type="text/javascript">document.documentElement.className = "js";</script>

Если джаваскрипт включен, элементу <html> присвоится класс js. Что важно, это произойдет до загрузки контента. Теперь можно написать такие стили:

#link {display: none;}

.js #link {display: inline;}
.js #block {display: none;}

3 комментария:

ast комментирует...

Вариант 3 заюзаю :-)

Анонимный комментирует...

В Техногрет?

alpha комментирует...

Хороший способ. Только стоит вынести это из кода страницы в какой-нибудь js-файл. Я вынес в Common.js :)