Решил я для очередного своего проекта воспользоваться модным 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
я не смогу сделать кроссбраузерное решение: и когда нужно копировать эти данные, и когда не нужно (например, нумерация строк в листинге кода). Как это часто бывает, радостные вопли неискушённых кодеров и красивые демонстрации маркетологов ломаются в момент «боевого» применения, когда нужно вкладывать смысл в свою работу, а не просто следовать модным тенденциям. Поэтому до сих пор приходится делать всё по-старинке.