Решил я для очередного своего проекта воспользоваться модным CSS-свойством content, чтобы немного облегчить страницу и сделать настройку внешнего вида более гибкой. Так как проект ориентирован на веб-разработчиков, об обратной совместимости со старыми браузерами (IE6—7) можно было не беспокоится. Но, к сожалению, меня ожидало большое разочарование от использования этого свойства. Нет, всё отображалось правильно, но конечному пользователю было бы неудобно пользоваться результатом.
Что такое CSS-свойство content
Кому ещё не удалось познакомиться с этим замечательным свойством, кратко расскажу о нём. Само название этого свойства говорит о том, что оно управляет неким содержимым. Согласно спецификации CSS2 это свойство применяется только к псевдо-элементам :before и :after, а с версии CSS3 станет доступно и для обычных элементов (небольшой реверанс в сторону Opera, которая это уже поддерживает).
С помощью свойства content мы можем через CSS задавать текстовое содержимое для (псевдо-)элементов. Классический пример применения этого свойства — вывод содержимого ссылки рядом с элементом в версии сайта для печати:
<style type="text/css">
a:after {
content: ' (' attr(href) ')';
}
</style>
<p>В нашем <a href="/catalog/">каталоге</a> вы найдёте много чего интересного.</p>
С помощью псевдо-элемента :after мы задали некое содержимое после тэга <a>. Этим содержимым является результат конкатенации строк и функции attr(), которая выводит содержимое атрибута контекстного элемента. Браузер, полностью поддерживающий CSS2, изобразит этот код примерно так:
![]()
Интересующиеся могут подробнее почитать об этом свойстве в интернетах, мы же перейдём к сути проблемы его использования.
Проблема
Так как для конечного пользователя результат работы свойства content выглядит как обычный текст, возникает вопрос: а может ли пользователь выделить и скопировать такой текст?
Проект, который я сейчас делаю, является инструментом для удобной работы с XML-документами. Для вывода раскрашенного дерева элементов я и решил воспользоваться вышеозначенным свойством:
<style type="text/css">
.tag:before {
content:'<';
}
.tag:after {
content:'>';
}
.attr-value {
quotes:'"' '"';
}
.attr-value:before {
content:open-quote;
}
.attr-value:after {
content:close-quote;
}
</style>
<div class="tag">div <span class="attr-name">class</span>=<q class="attr-value">demo</q></div>
Плюсы такого подхода: потребуется гораздо меньше элементов для раскраски тэгов (через псевдо-элементы :before и :after я могу задать произвольный цвет у угловых скобок). Для значений атрибутов я воспользовался тэгом <q> и CSS-свойством quotes, через которое определяются открывающие и закрывающие кавычки. Кому-то нравится использовать двойные кавычки в коде, кому-то — ординарные, при таком подходе их можно на лету поменять у всего документа. Как оказалось, выбор этого тэга и CSS-свойства стал важной частью эксперимента.
В браузерах этот код выглядит замечательно:
![]()
Но XML-документ должен не только красиво выглядеть, но и правильно работать: пользователь имеет право без проблем выделить и скопировать фрагмента документа, чтобы воспользоваться им, например, в своём любимом редакторе. И тут меня ожидало полное разочарование от использования свойства content. Я проверил результат копирования в своих браузерах — Safari 4, Opera 10, Firefox 3.5, IE8 — и получил вот такой результат:
- Safari:
div class=demo - Opera:
<div class="demo"> - Firefox:
div class="demo" - IE8:
<div class="demo">
Как видите, все скопировали текст по-разному: Safari не скопировал content-данные в принципе, Opera и IE8 скопировали всё, а Firefox скопировал только кавычки вокруг атрибута.
Затем я решил вместо вместо элемента <q> написать обычный <span>, и получил вот такой результат:
- Safari:
div class=demo - Opera:
<div class="demo"> - Firefox:
div class=demo - IE8:
<div class="demo">
Всё то же самое, но Firefox уже не скопировал кавычки.
Выводы
Из этого небольшого эксперимента я сделал для себя следующие выводы:
- Safari в принципе не понимает CSS-свойство
quotes. То, что браузер отобразил кавычки вокруг<q>элемента — исключительно стандартная реакция на него. Кавычки нельзя будет поменять через свойствоquotes, например, на ординарные — они так и останутся двойными. А если элемент переименовать в<span>, то и вовсе пропадут. - Firefox при копировании текста обращает внимание на название элемента: если это
<q>— кавычки скопируются, для другого элемента получите пустоту. - Firefox всегда копирует двойные кавычки для тэга
<q>, даже если вы измените их на что-нибудь другое (на «ёлочки», например). То есть сделать трюк с управлением копирования символов у вас не получится. Либо двойные кавычки, либо ничего. - IE8 при копировании обращает внимание на тип элемента: например, если прописать тэгу
display: list-item, то скопируется буллит (хотя на странице он не будет отображаться).
В общем, выводы далеко не самые приятные. С помощью свойства content я не смогу сделать кроссбраузерное решение: и когда нужно копировать эти данные, и когда не нужно (например, нумерация строк в листинге кода). Как это часто бывает, радостные вопли неискушённых кодеров и красивые демонстрации маркетологов ломаются в момент «боевого» применения, когда нужно вкладывать смысл в свою работу, а не просто следовать модным тенденциям. Поэтому до сих пор приходится делать всё по-старинке.
