Как работает CSS. Создание анимационных эффектов средствами CSS

Преимуществом веб-типографики является то, что она базируется на знаниях, накопленных за столетия развития традиционной печатной типографики. По той же причине веб-типографика должна следовать стандартам лучших практик и передового опыта.

Однако, веб это пространство коммуникации со своими особенностями. Настолько, что плавный переход от печати к веб-типографике становится вызовом. Джейсон Санта Мария в своей книге о веб-типографике пишет:

Печатные книги это статический формат. От первого дизайнерского макета книга без изменений проходит свой путь к вам через типографию, склад и книжную полку. В точно таком же виде, как было задумано.

В вебе один и тот же сайт может выглядеть различно в зависимости от многих факторов - различий устройств, разрешения их экранов, личных настроек браузеров и прочего. Как далее пишет Джейсон, некоторые из этих факторов…

Могут дать впечатление, что шрифт слишком мелкий, другие выносят часть содержимого за пределы экрана, а третьи могут полностью испортить просмотр страницы.

Но также известно, что “веб это лучшее место для текста”. Текст в Интернете можно “искать, копировать, переводить, передавать в виде ссылки, распечатывать; текст в вебе удобен и доступен”.

Гибкость веба не означает отказ от контроля. Наоборот, как веб-дизайнеры мы ожидаем возможности делать осознанный выбор во всем, что составляет нашу работу и текст не исключение. Это и то, как располагается текст, его размер, шрифт и все, что позволяет донести основную идею сайта.

Главный инструмент для манипуляции видом текста в вебе это CSS.

Свойства CSS, рассматриваемые в этой статье, вы можете найти в модуле спецификации CSS текста .

Этот модуль описывает верстку CSS, то есть свойства CSS, управляющие переводом источника текста в форматированный и разделенный на строки текст.

Другими словами, модуль CSS текста это все, что касается вывода символов и слов в браузере, отступов, выравнивания, переносов и прочего.

Что считать базовой единицей текста или слова, где можно разбивать слова и прочие правила, зависит от языка сайта. Поэтому очень важно задавать данные об используемом языке в HTML-документе (обычно это атрибут lang в элементе html).

В этой статье я не буду обсуждать следующие вещи:

  • шрифты, т.е. визуальное представление символов и их свойства;
  • свойства CSS по декорированию текста, такие как подчеркивание, тени текста или акцентирование.

Если вы любопытны, вы найдете последнюю документацию о шрифтах и декорировании текста в модуле CSS шрифты третьего уровня и в модуле декорирования текста CSS третьего уровня .

Управление регистром букв: text-transform

Иногда возникает необходимость вывести слова или первые символы слов с заглавной буквы. В CSS для управления регистром буквы есть свойство text-transform .

Дефолтное значение text-transform равно none , то есть по умолчанию регистр букв не изменяется.

Значение capitalize

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

Разметка:

H2 { text-transform: capitalize; }

Отметьте, что capitalize не следует традиционным правилам - оно делает заглавными первые буквы всех слов, включая предлоги. И если вы хотите следовать нормам английского языка, вам придется делать это вручную.

Значение uppercase

Если ваша цель - сделать все буквы заглавными, то подходящим значением будет uppercase:

Разметка:

alice"s adventures in wonderland

H2 { text-transform: uppercase; }

Значение lowercase

Это значение наоборот делает все символы строчными. Естественно, оно не оказывает никакого воздействия на уже имеющиеся строчные буквы.

Разметка:

alice"s adventures in wonderland

H2 { text-transform: lowercase; }

Значение full-width

Это значение появилось в спецификации недавно. Это значение ограничивает символ внутри квадрата, аналогично иероглифам. И применение этого свойство облегчает выравнивание латинских символов с идеографическими.

Не у всех символов есть соответствующая форма, и, значит, не на все символы будет влиять это значение:

Разметка:

alice"s adventures in wonderland

H2 { text-transform: full-width; }

Это свойство на данный момент поддерживается только в Firefox.

Дополнительная информация

Браузеры отлично поддерживают свойство text-transform , у всех основных браузеров с ним нет проблем.

Единственное исключение это значение full-width , которое работает пока только в Firefox. И такая непопулярность вполне может повлечь исключение этого значения из спецификаций.

Также есть небольшое отличие в обработке capitalize у Firefox и остальных браузеров.

Вот, например, Firefox:

Заметьте, что первая буква после дефиса не капитализируется. А вот тот же самый пример в Chrome:

В Chrome не делается исключений для первых букв после дефисов - они переводятся в заглавный регистр также как остальные. И это является дефолтным поведением для всех браузеров, кроме упомянутого выше Firefox.

И, наконец, не забывайте о каскадировании. Задание свойства text-transform для элемента-контейнера будет унаследовано всеми его потомками. Чтобы избежать неожиданных результатов, задавайте дочерним элементам text-transform в значение none .

Обработка пробелов: white-space

Когда вы нажимаете клавишу Tab , пробел или форсированно обрываете строку (с клавишей ENTER или тегом
), вы создаете пробелы в своем документе.

По умолчанию браузеры объединяют все последовательности пробелов в один, удаляют обрывы строки и заставляют строки занимать ширину контейнера. Это удобно потому что позволяет делать отступы и разделять фрагменты текста, сохраняя исходник документа читаемым и поддерживаемым, не заботясь о его отображении в браузере.

Однако, что делать, если у нас другая цель? Предположим, вы хотите сохранить все пробелы, которые вы создали в HTML-документе. Или вы хотите, чтобы фрагмент текста выводился как сниппет кода, со всеми отступами. Или же вы хотите вывести текст в одну линию, без переносов.

В тех случаях, когда вам нужно изменить дефолтное поведение браузера, свойство white-space предлагает несколько интересных вариантов.

Ключевое слово normal идентично дефолтному поведению - все лишние пробелы схлопываются в один, строка переводится после достижения края контейнера.

Значение pre

Ключевое слово pre позволяет вам вывести текст с сохранением всех пробелов и всех форсированных переводов строки в исходнике. И при превышении пределов контейнера строка не будет обрываться.

Element { white-space: pre; }

Если вы используете табы, то вы можете управлять их размером в пробелах с помощью свойства tab-size . Оно принимает значение в виде целого числа.

Element { white-space: pre; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; }

Свойство tab-size поддерживают все современные браузеры, кроме браузеров от Microsoft (и даже Edge, увы) , но если вы уверены, что вам это надо, используйте полифилл .

Значение pre-wrap

Ключевое слово pre-wrap позволяет вам достигнуть желаемого результата.

Element { white-space: pre-wrap; }

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

Однако, если вы уменьшите ширину браузера, вы заметите, что все строки ограничены шириной контейнера.

Значение pre-line

И, наконец, еще одно интересное значение свойства white-space - pre-line . Оно действует как дефолтное в части схлопывания пробелов в один и ограничения строки размером контейнера. Однако оно отрабатывает все форсированные переводы строки.

Element { white-space: pre-line; }

Значение nowrap

nowrap это, возможно, самое известное значение для white-space . Сталкивались вы с необходимостью задать какому-либо элементу дизайна неразрывность вне зависимости от ширины контейнера? Это делается с помощью white-space: nowrap; .

Для таких случаев у нас есть специальные свойства CSS.

Свойство word-wrap/overflow-wrap

Свойство overflow-wrap (раннее известное как word-wrap и до сих пор поддерживаемое во всех основных браузерах) работает, если свойство white-space допускает перенос в соответствии с размером строки. Возможные значения - normal и break-word .

Со значением normal слова разбиваются на всех традиционных маркерах - пробелы, дефисы и т.д.

Значение break-word позволяет разбить длинные слова, если иначе строка будет превышать доступный размер.

На картинке ниже изображен пример длинного слова, выходящего за пределы контейнера:

Теперь зададим этому элементу свойство overflow-wrap (и свойство word-wrap для совместимости) в значение break-word:

Element { word-wrap: break-word; overflow-wrap: break-word; }

Теперь сверхдлинное слово разбито на несколько строк, заполняющих всю ширину контейнера.

Свойство hyphens

Разбитие длинных слов это, конечно, хорошо. Однако, полученный текст может смутить читателей. Лучше будет, если разбитие слова будет сопровождаться установкой дефиса. Таким образом, читателям сразу становится ясно, что это одно слово, разделенное между строками. Этого можно достичь используя свойство hyphens , его можно сочетать с word-wrap: break-word .

Конкретно это значит, что значение auto свойства hyphens позволяет вывести дефис на месте разбития слова, если язык документа позволяет это делать в имеющемся источнике HTML. Чтобы это сработало, не забудьте задать правильный атрибут lang своему документу:

Break-word.hyphens-auto { -moz-hyphens: auto; -webkit-hyphens: auto; -ms-hyphens: auto; hyphens: auto; }

Вы также можете отключить вывод дефисов, задав hyphens значение none:

Break-word.hyphens-none { -moz-hyphens: none; -webkit-hyphens: none; -ms-hyphens: none; hyphens: none; }

Также у вас есть возможность вывести дефисы на разрывах строки там, где вы поставили их в разметке. Это делается с помощью значения manual:

Break-word.hyphens-manual { -moz-hyphens: manual; -webkit-hyphens: manual; -ms-hyphens: manual; hyphens: manual; }

Управляем пространством между словами и буквами

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

В CSS есть свойства word-spacing и letter-spacing для управления расстоянием между словами и буквами соответственно.

Свойство word-spacing

Это свойство может принимать следующие значения:

  • normal
  • (задание непосредственно числового значения в абсолютных единицах)
  • percentage (задание значения в процентах)

normal выводит заданное по умолчанию расстояние между буквами. Это расстояние зависит от используемого шрифта и браузера.

Normal { word-spacing: normal; }

Числовое значение добавляет указанный промежуток к дефолтному (вычитает , если задано отрицательное значение):

Length { word-spacing: 0.5em; }

Значение в процентах работает также как и числовое. На данный момент оно не поддерживается браузерами и, скорее всего, будет удалено из будущих черновиков спецификации.

Percentage { word-spacing: 1%; }

Свойство letter-spacing

Свойство letter-spacing принимает два вида значений: normal или числовое значение с единицами измерения.

Свойство normal сбрасывает любое раннее установленное значение letter-spacing на дефолтное. Например, если вы задали родительскому элементу letter-spacing в 1em , вы можете отменить это для дочерних с помощью normal .

Element { letter-spacing: normal; }

Числовое значение задается в единицах исчисления, например в em или в пикселях, вы можете увеличить расстояние дефолтное расстояние или уменьшить задав отрицательное значение.

Element { letter-spacing: 1em; }

Дополнение

word-spacing применимо не только к словам - его можно использовать с любым строчным или строчно-блочным содержимым.

Также вы можете анимировать word-spacing и letter-spacing . Однако в CSS-переходах значение normal в letter-spacing не работает в Firefox (39), просто замените значение на 0em .

Отступы в тексте: text-indent

Отступы в тексте обычно делаются в первой строке параграфа, хотя и не являются распространенной практикой на веб-сайтах. Вместо этого обычно помещается пустая строка, разделяющая параграфы.

Тем не менее, иногда отступ в первой строке иногда используется, например, для имитации классических книжных дизайнов.

Если вы хотите использовать эту технику в своем дизайне, в CSS есть свойство text-indent . Рассмотрим его возможные значения.

Числовое значение можно задать в пикселях, em’aх и других поддерживаемых единицах:

Element { text-indent: 2em; }

В том числе и в процентах от ширины контейнера:

Element { text-indent: 6%; }

Значение each-line добавляет отступ не только первой строке, но и любой строке после разрыва строки (ENTER или
). На строки, переносимые по причине заполнения контейнера эти отступы не распространяются.

Значение hanging добавляет отступ ко всем строкам, кроме первой.

Два последних значения: each-line и hanging являются экспериментальными и не реализованы на данный момент ни в одном из браузеров.

Доброго времени суток, уважаемые подписчики!

В html существуют возможность делать объект видимым или невидимым, причем есть различные варианты, и они по-разному отображают содержимое.

Итак, начнем.

Представим ситуацию: нам нужно в блок размером 200 на 300 пикселей вместить достаточно большой фрагмент текста (в принципе это может быть что угодно).

Если мы зададим блоку с помощью стилей ширину равную 200 и высоту равную 300 пикселей, то по высоте он растянется на столько, сколько будет содержимого в блоке. Но нам нужно строго 300 пикселей по высоте! В этом случае делаем следующее:

Для нашего блока задаем свойство overflow со значением scroll . Блок становится с нужными нам размерами, все содержимое поместилось в нем, и появились полосы прокрутки.

Значения свойства overflow приведены ниже:

overflow – управление размерами объекта, если его содержимое не может быть показано целиком.

Значения:

auto – определяется браузером.

visible – размер растягивается до такой степени, что бы все содержимое было видимым.

hidden – то, что выходит за границы элемента просто не отображается.

scroll – все содержимое отображается, и появляются полосы прокрутки.

Для нашего конкретного случая пример:

XHTML

#st1{ overflow: scroll; width:200px; height:300px; } Достаточно большой фрагмент текста

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

visibility - управляет в CSS, видимостью содержимого элемента.

Значения:

XHTML

содержимое этого заголовка не отобразится

Следующее свойство, которое позволяет управлять видимостью блока – это display .

display — определяет, как будет отображаться элемент

Значения:

none — элемент не отображается

block - разбивает строку до и после элемента (т.е. элемент не может находится на одной линии с другими элементами)

inline - не разбивает строку

Как этим свойством пользоваться?

Допустим у нас идет текст, среди этого текста есть тэг или это может быть ссылка, и нам нужно, что бы содержимое этого тэга или ссылки отображались на отдельной строке, то для них мы зададим свойство display cо значением block. И наоборот, если нужно, допустим, чтобы тег был не на отдельной сроке, а в той же что и текст, то ему задаем свойство display cо значением inline .

XHTML

будет на одной строке с текстом отобразиться на отдельной строке

Особого внимания заслуживает значение none . Если мы зададим какому-либо элементу, свойство display со значением none, то этот элемент не отобразиться. Причем, в отличие от свойства visibility со значением hidden , этот элемент не отобразится полностью (свойства visibility со значением hidden не отобразит содержимое элемента, а сам элемент будет занимать свое место на странице).

Аннотация: Доступ к таблицам стилей. Свойства таблиц стилей. Добавление и удаление правил. Изменение стилей элементов. Имена классов элементов.

Давайте рассмотрим (в данный момент) теоретический пример - пусть имеется web - сайт , где представлена серия технических статей. Мы хотим привлечь внимание к некоторым из этих статей с помощью интересной анимированной карусели, но как быть с пользователями, у которых JavaScript не включен по каким-то причинам? Вспоминая полученные знания о ненавязчивом JavaScript, мы хотим, чтобы функции Web -сайта также работали для этих пользователей, но мы можем захотеть оформить сайт для этих пользователей по-другому, чтобы им было удобно использовать сайт , даже без карусели.

Если требуется удалить это правило , можно вызвать функцию stylesheet.deleteRule(index) , где index будет индексом правила , которое будет удалено.

В примере демонстрации статей можно создать правило , которое делает свойство display равным none для всех статей о HTML и JavaScript - посмотрите в примере карусели (http://dev.opera.com/articles/view/dynamic-style-css-javascript/carousel.html), чтобы увидеть это в действии.

Примечание : IE не реализует правила в соответствии со стандартами. Вместо атрибута cssRules он использует rules . IE использует также removeRule вместо deleteRule и addRule( selector , rule, index) вместо insertRule .

Изменение стилей элементов

Теперь вы должны понимать, как редактировать таблицы стилей , соединенные со страницей, и создавать и модифицировать в них правила CSS . Что делать, если вы захотите изменить определенный элемент в DOM ? Используя DOM API можно получить доступ к определенным элементам страницы. Возвращаясь к примеру карусели можно видеть, что функции определены таким образом, что при щелчке на статье эта статья выделяется, в то время как основной текст статьи выводится ниже.

С помощью DOM мы получаем доступ к объекту style , который описывает стиль документа. Этот объект style определен как CSSStyleDeclaration ; подробное объяснение этого можно найти в документации W3C по интерфейсу CSSStyleDeclaration (http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration). Объект style работает не совсем так, как некоторые другие свойства, определенные в элементе HTML . В отличие от element.href или element.id , которые возвращают строки, element.style возвращает объект . Это означает, что невозможно задать стиль, присваивая строку для element.style .

Объект style имеет атрибуты, которые соответствуют различным заданным свойствам CSS . Например, style.color возвращает заданный на элементе цвет. Выполняя element.style.color = "red"; можно динамически изменять стиль. Ниже показана функция , которая превращает цвет элемента в красный, когда ей передается id элемента.

function colorElementRed(id) { var el = document.getElementById(id); el.style.color = "red"; }

Можно также использовать setAttribute(key, value) для задания стиля элемента. Например, задать цвет элемента как красный, вызывая на элементе element.setAttribute("style", "color: red"); , но будьте осторожны, так как это удаляет любые изменения, сделанные в объекте style .

Когда стиль элемента задается таким образом, то это то же самое, как если бы мы задавали его как объявление атрибута style элемента html . Этот стиль будет применяться только в том случае, когда важность и специфичность правила будут больше, чем другие примененные к элементу правила (специфичность объясняется в лекции 28 о наследовании и каскадировании CSS ).

У некоторых из вас может возникнуть вопрос, что происходит, когда заданное свойство

You can set attributes of the various styles directly in the markup or use a style sheet. The property can be used to assign a CSS class to a menu style that controls some aspect of the control"s appearance. The following example shows how to specify a property for a number of properties that you can then reference in a style sheet.

...

Note that it is a best practice to either specify inline styles in the markup or use the property and specify styles using a style sheet. It is not recommended that you both specify inline styles and use a style sheet, because unexpected behavior could result. For a general discussion of using CSS with server controls, see ASP.NET Web Server Controls and CSS Styles .

Menu Behavior and Styles

To control the appearance of the dynamic portion of the menu, you can use the style properties with the word "Dynamic" in the name:

The following example creates a collection of four styles that apply to the first four levels of menu items and could be referenced in a style sheet by using the value.

The first style in the collection applies to the first-level menu items; the second style applies to the second-level menu items, and so on. Note that there is no inheritance between level styles so that styles applied to one level do not affect subsequent levels.

The following example creates a collection of three styles that apply to the first three levels of menu items and could be referenced in a style sheet.

И в этот же день учёные заставили гравитацию поволноваться. Совпадение? Не иначе.

Паттерн из предыдущей статьи охватывал 90% случаев многоэтапной загрузки CSS, и его простота вполне очевидна. Но не угодно ли вам послушать про паттерн, который подходит к ~100% случаев и при этом до нелепого сложен? Тогда приглашаю вас пройти вместе со мной в следующий абзац…

Недостающие 10%

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

Мобильники Компьютеры

Это здорово для мобильных, где каждый CSS для раздела блокирует себя и все последующие разделы, но на десктопе CSS для main и comments в левой колонке блокирует отрисовку about-me в правой колонке, даже если CSS для about-me загружается первым. Это потому, что очередность блокировки определяется порядком в исходном коде, но для этого дизайна было бы здорово, чтобы правая колонка отобразилась раньше левой.

Нам нужно выстроить дерево зависимостей, где отрисовка каждого элемента блокируется до отрисовки других определённых элементов. Также зависимости должны уметь изменяться при изменении ширины области просмотра. Звучит заманчиво, не правда ли?

Это можно сделать с помощью пользовательских свойств CSS

Пользовательские свойства CSS

Но для нашей сегодняшней беседы достаточно знать вот что…

Html { background: var(--gloop, red); }

Здесь мы задаём фону страницы значение из пользовательского свойства --gloop , а если его нет - red в качестве запасного варианта. В результате фон будет красным. Но если добавить:

:root { --gloop: green; }

…мы устанавили пользовательскому свойству --gloop значение green , так что теперь страница зелёная. Но если добавить:

:root { --gloop: initial; }

Значение initial здесь обрабатывается особым образом. Оно фактически отменяет --gloop , так что теперь фон страницы снова красный.

Построение дерева зависимостей отрисовки с помощью пользовательских свойств CSS

Дописывая этот заголовок, я аж сам порадовался, какой я умный.

The HTML [ "/main.css", "/comments.css", "/about-me.css", "/footer.css" ].map(url => { const link = document.createElement("link"); link.rel = "stylesheet"; link.href = url; document.head.appendChild(link); });

Так что можно загрузить /initial.css с помощью или встроить его, раз уж всё равно он блокирует отрисовку. Но мы загружаем все остальные таблицы стилей асинхронно.

initial.css main, .comments, .about-me, footer { display: none; } :root { --main-blocker: none; --comments-blocker: none; --about-me-blocker: none; --footer-blocker: none; } /* Остальные начальные стили... */

Скрываем разделы, которые мы ещё не готовы отобразить, а затем для каждого раздела создаём пользовательское свойство-«блокировщик».

main.css :root { --main-blocker: initial; } main { display: var(--main-blocker, block); } /* Остальные стили основного содержимого... */

У основного содержания нет никаких зависимостей отображения. Как только CSS загрузится, его блокировщик отменяется (с помощью initial) и отображает его.

comments.css :root { --comments-blocker: var(--main-blocker); } .comments { display: var(--comments-blocker, block); } /* Остальные стили комментариев... */

Комментарии не должны отображаться до основного содержимого, поэтому блокировщик комментариев связывается с --main-blocker . Блок.comments становится видимым, как только этот CSS загружается и --main-blocker отменяется

about-me.css :root { --about-me-blocker: var(--comments-blocker); } .about-me { display: var(--about-me-blocker, block); }

Аналогично приведённому выше коду, .about-me зависит от своего CSS и комментариев. Но когда страница шире, она отображается в двух колонках, поэтому нам больше не нужно, чтобы.about-me зависел от комментариев в плане отображения:

@media (min-width: 600px) { :root { --about-me-blocker: initial; } } /* Остальные стили для about-me… */

Готово! Когда ширина области просмотра свыше 600px , .about-me отображается сразу после загрузки его CSS.

footer.css :root { --footer-blocker: var(--main-blocker, var(--about-me-blocker)); } footer { display: var(--footer-blocker, block); } /* Остальные стили… */

Подвал должен отобразиться после появления главных разделов content и about-me . Для этого --footer-blocker берёт своё значение из --main-blocker , но сразу после отмены --main-blocker --footer-blocker откатывается к значению, взятому из --about-me-blocker .

Демо

Требуется Chrome Canary или Firefox.

В этом демо CSS загружается асинхронно, затрачивая на загрузку каждого файла примерно 0-5 секунд. Несмотря на это, страница никогда не отобразится не в том порядке, а каждый раздел отобразится при первой возможности в зависимости от ширины браузера.

Но… практично ли это?

Этот способ гораздо сложнее , с минимумом преимуществ и огромными проблемами обратной совместимости. Но он демонстрирует мощь пользовательских свойств CSS, недоступную решениям вроде переменных Sass, применяющихся во время компиляции.

Если и правда есть желание делать что-то подобное уже сегодня, то можете взвалить основную часть работы на плечи асинхронной загрузки CSS с помощью loadCSS , и добавлять классы к , как только определенные стили загрузятся (), хотя это приведёт к множеству специфических проблем, решаемых через хаки.

Думаю, эту статью можно расценивать, как «забавный пример», но мы едва начали открывать мощь пользовательских свойств CSS.

Благодарю Реми Шарпа за исправления. Будет ли когда-нибудь у меня статья без орфографических ошибок? Нидокга .



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: