Содержание

Как структурировать HTML-формы — Изучение веб-разработки

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

Уровень подготовки:Основы компьютерной грамотности, и базовые знания HTML.
Цель:Разобраться как структурировать HTML формы и задавать им семантику для того, чтобы они были удобны и доступны в использовании.

Гибкость HTML форм делает их одной из самых сложных структур в HTML; вы можете создать любую форму, используя элементы и атрибуты форм. Использование правильной структуры, при создании HTML форм, поможет гарантировать их удобство и доступность.

Элемент <form> формально определяет форму и атрибуты, которые определяют поведение этой формы. Каждый раз, когда вы хотите создать HTML-форму, вам нужно начать с создания элемента <form>, поместив внутрь него всё содержимое.

Многие вспомогательные технологии или браузерные плагины могут обнаруживать элементы <form> и реализовывать специальные хуки, чтобы их было проще использовать.

Мы уже встречались с этим в предыдущей статье.

Внимание: Строго запрещается размещать форму внутри другой формы. Такое размещение может привести к непредсказуемому поведению форм, в зависимости от браузера. 

Стоит учесть, что всегда можно использовать элементы формы вне <form>. Тогда по умолчанию этот элемент формы не имеет ничего общего со всеми формами. Вы можете связать его с формой с помощью атрибута

form. В HTML5 был представлен атрибут form для элементов HTML форм, который позволяет  явно связать элемент с формой, даже если он не заключён внутри <form>.

Элемент <fieldset> — это удобный способ стилистической и семантической группировки элементов формы. Вы можете установить заголовок <fieldset>, добавив элемент <legend> сразу после открывающего тега <fieldset>. Текст элемента <legend> формально описывает назначение содержимого

<fieldset>.

Различные вспомогательные технологии будут использовать <legend> как часть метки label всех элементов внутри <fieldset>. Например, такие экранные дикторы как Jaws или NVDA произносят заголовок формы <legend> перед произношением названия меток элементов.

Небольшой пример:

<form>
  <fieldset>
    <legend>Fruit juice size</legend>
    <p>
      <input type="radio" name="size" value="small">
      <label for="size_1">Small</label>
    </p>
    <p>
      <input type="radio" name="size" value="medium">
      <label for="size_2">Medium</label>
    </p>
    <p>
      <input type="radio" name="size" value="large">
      <label for="size_3">Large</label>
    </p>
  </fieldset>
</form>

Читая эту форму, экранный диктор произнесёт «Fruit juice size small» для первого элемента, «Fruit juice size medium» — для второго, «Fruit juice size large» — для третьего.

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

<fieldset>. Также <fieldset> можно использовать для разделения формы. В идеале, длинную форму разделяют на несколько страниц, однако, если она должна находиться на одной странице, распределение связанных элементов в разные <fieldset> может повысить удобство использования.

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

В предыдущей статье мы увидели, что элемент <label> принято использовать для указания текстов-подсказок (лейблов) в HTML-формах. Это самый важный элемент для построения доступных форм — при правильной реализации скринридеры будут озвучивать текст-подсказку вместе со связанными элементами.

Посмотрите на этот пример из предыдущей статьи:

<label for="name">Name:</label> <input type="text" name="user_name">

При правильно связанном элементе <label> с элементом <input> через атрибуты for и id соответственно (атрибут for ссылается на атрибут id соответствующего виджета формы), скринридер прочтёт вслух что-то наподобие «Name, edit text».

Если <label> не правильно установлен, скринридер прочитает это как «Edit text blank», что не несёт в себе никакой уточняющей информации, позволяющей понять предназначение данного текстового поля.

Обратите внимание на то, что виджет формы может быть вложен в элемент <label>, как на примере:

<label for="name">
  Name: <input type="text" name="user_name">
</label>

Однако даже в таких случаях лучше всё равно указывать атрибут for, так как некоторые вспомогательные технологии не распознают неявную связь между текстами-подсказками и виджетами.

Лейблы тоже кликабельны!

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

Например:

<form>
  <p>
    <label for="taste_1">I like cherry</label>
    <input type="checkbox" name="taste_cherry" value="1">
  </p>
  <p>
    <label for="taste_2">I like banana</label>
    <input type="checkbox" name="taste_banana" value="2">
  </p>
</form>

Несколько лейблов

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

Рассмотрим этот пример:

<p>Required fields are followed by <abbr title="required">*</abbr>.</p>


<div>
  <label for="username">Name:</label>
  <input type="text" name="username">
  <label for="username"><abbr title="required">*</abbr></label>
</div>


<div>
  <label for="username">
    <span>Name:</span>
    <input type="text" name="username">
    <abbr title="required">*</abbr>
  </label>
</div>


<div>
  <label for="username">Name: <abbr title="required">*</abbr></label>
  <input type="text" name="username">
</div>

Параграф на первой строке примера описывает правило для обязательных элементов. Вначале необходимо убедиться, что вспомогательные технологии, такие как программы чтения с экрана, отображают или озвучивают их пользователю, прежде чем он найдёт требуемый элемент.  Таким образом они будут знать, что означает звёздочка. Программа чтения с экрана будет произносить звёздочку как «звёздочку» или «обязательно», в зависимости от настроек программы чтения с экрана — в любом случае, первый абзац даёт понимание того, что будет означать звёздочка далее в форме.

  • В первом примере лейбл не будет прочитан вместе с текстовым полем — получится лишь «edit text blank» и отдельно читаемые тексты-подсказки. Множественные элементы
    <label>
     могут быть неправильно интерпретированы программой чтения с экрана.
  • Второй пример немного лучше — лейбл будет прочитан вместе с текстовым полем и будет звучать как «name star name edit text», однако тексты-подсказки всё ещё разделены. Это всё ещё немного сбивает с толку, но на этот раз ситуация немного лучше, потому что с текстовое поле связано с текстом-подсказкой.
  • Третий пример — лучший, так как весь лейбл будет связан с текстовым полем и озвучен целиком, а при чтении текст будет звучать как «name star edit text».

Примечание: В зависимости от программы для чтения с экрана результаты могут немного отличаться. В данной статье для тестирования использовался VoiceOver (NVDA ведёт себя аналогично). Также мы были бы рады, если бы вы поделились своим опытом.

Примечание: вы можете найти этот пример на GitHub required-labels.html (также можно посмотреть вживую). Запускайте пример, закомментировав остальные, иначе скриридеры не смогут правильно распознать контент, если у вас будет несколько лейблов и несколько текстовых полей с одинаковым ID!

Помимо структур, характерных только для HTML-форм, хорошо помнить, что формы — это просто HTML. Это означает, что вы можете использовать всю мощь HTML для структурирования HTML-формы.

Как вы можете заметить в примерах, оборачивать лейбл и виджет формы в элемент <div> — это общепринятая практика. Элемент <p> также часто используется, как и HTML-списки (последние часто используются для структурирования множественных чекбоксом или радио-кнопок).

В добавок к элементу <fieldset> часто используют HTML-заголовки (например, <h2> (en-US), <h3> (en-US)) и секционирование (например, <section>) для структурирования сложных форм.

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

Каждый отдельный раздел функциональности содержится в элементах <section> и <fieldset>, содержащий переключатели. Каждый отдельный раздел функциональности должен находиться в отдельном элементе <section> с элементами <fieldset>, содержащими переключатели.

Активное обучение: построение структуры формы

Давайте применим эти идеи на практике и построим более сложноструктурируемую форму — формы оплаты. Форма будет содержать некоторые типы виджетов формы, которые вы можете пока не понять — не переживайте об этом, вы найдёте информацию в следующей статье (Основные нативные элементы управления формами). А пока внимательно прочитайте описание, следуя приведённым ниже инструкциям, и начинайте формировать представление о том, какие элементы обёртки мы используем для структурирования формы и почему.

  1. Для начала сделайте локальную копию пустого шаблона и CSS для нашей платёжной формы в новой директории на вашем компьютере.
  2. Сначала подключите CSS к HTML, добавив следующую строку кода внутрь HTML-элемента <head>:
    <link href="payment-form.css" rel="stylesheet">
  3. Далее начните создавать свою форму с добавления внешнего элемента <form>:
  4. Внутри тега <form>, добавьте заголовок и параграф, информирующий пользователей о том, как помечены поля, обязательные для заполнения:
    <h2>Payment form</h2>
    <p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
  5. Далее нам надо добавить более крупный кусок кода под нашей предыдущей записью. Здесь вы можете увидеть, что мы оборачиваем поля с контактной информацией в отдельный элемент <section>. Более того, у нас есть набор из двух радио-кнопок, каждую из которых мы помещаем в отдельный элемент списка (<li>). Наконец, у нас есть два текстовых поля <input> и связанные с ними элементы <label>, которые находятся внутри элементов <p>, а также поле для ввода пароля. Добавьте этот код в вашу форму:
    <section>
        <h3>Contact information</h3>
        <fieldset>
          <legend>Title</legend>
          <ul>
              <li>
                <label for="title_1">
                  <input type="radio" name="title" value="M." >
                  Mister
                </label>
              </li>
              <li>
                <label for="title_2">
                  <input type="radio" name="title" value="Ms.">
                  Miss
                </label>
              </li>
          </ul>
        </fieldset>
        <p>
          <label for="name">
            <span>Name: </span>
            <strong><abbr title="required">*</abbr></strong>
          </label>
          <input type="text" name="username">
        </p>
        <p>
          <label for="mail">
            <span>E-mail: </span>
            <strong><abbr title="required">*</abbr></strong>
          </label>
          <input type="email" name="usermail">
        </p>
        <p>
          <label for="pwd">
            <span>Password: </span>
            <strong><abbr title="required">*</abbr></strong>
          </label>
          <input type="password" name="password">
        </p>
    </section>
  6. Сейчас мы перейдём к второму разделу <section> нашей формы — платёжной информации. В этом разделе у нас есть три отдельных виджета формы со связанными с ними лейблами, находящимися внутри тега <p>. Первый — это выпадающее меню (<select>) для выбора типа кредитной карты. Второй — это элемент <input> с типом number для ввода номера карты. Последний виджет — это элемент <input> с типом date для указания даты окончания действия карты (должен будет появиться виджет с выбором даты или обычное текстовое поле в браузерах, не поддерживающих данные тип). Более новые типы полей описаны в статье The HTML5 input types.

    Вставьте следующий код под предыдущим разделом:

    <section>
        <h3>Payment information</h3>
        <p>
          <label for="card">
            <span>Card type:</span>
          </label>
          <select name="usercard">
            <option value="visa">Visa</option>
            <option value="mc">Mastercard</option>
            <option value="amex">American Express</option>
          </select>
        </p>
        <p>
          <label for="number">
            <span>Card number:</span>
            <strong><abbr title="required">*</abbr></strong>
          </label>
          <input type="number" name="cardnumber">
        </p>
        <p>
          <label for="date">
            <span>Expiration date:</span>
            <strong><abbr title="required">*</abbr></strong>
            <em>formatted as mm/yy</em>
          </label>
          <input type="date" name="expiration">
        </p>
    </section>
  7. Последняя секция, которую мы добавим выглядит намного проще и содержит в себе только элемент <button> с типом submit, для отправки данных. Добавьте этот код в конец вашей формы:
    <p> <button type="submit">Validate the payment</button> </p>

Вы можете увидеть законченную форму в действии ниже (также её можно найти на GitHub — посмотрите payment-form.html и живой пример):

Вы дошли до конца статьи, но можете ли вспомнить самую важную информацию? Далее вы можете найти тест, который поможет убедиться, что вы усвоили знания прежде чем двигаться дальше — посмотрите Test your skills: Form structure.

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

Дополнительные темы

Элемент TITLE. HTML, XHTML и CSS на 100%

Читайте также

Элемент

Элемент Основой языка HTML является элемент. Он несет в себе определенную информацию, может описывать документ в целом или способ форматирования текста. Элементы можно назвать основой построения сайта. Все, что вы захотите создать на вашей странице, будет сделано с помощью

Элемент

Элемент Элементы – это любые единичные компоненты структуры, например, заголовок, абзац текста, фотография или

Элемент <xsl:if>

Элемент &lt;xsl:if&gt; При помощи элемента &lt;xsl:if&gt; осуществляются проверки условия и принимаются действия на основе результата проверки. Он во многом похож на оператор if в языках программирования. У элемента &lt;xsl:if&gt; один атрибут:• test (обязательный). Устанавливается в

Элемент <xsl:for-each>

Элемент &lt;xsl:for-each&gt; Элемент &lt;xsl:for-each&gt; позволяет применять тело шаблона в цикле снова и снова для всех элементов набора узлов. С технической точки зрения, он работает с набором узлов, который возвращает выражение XPath и выполняет одно и то же действие с каждым узлом в

Элемент <?job?>

Элемент &lt;?job?&gt; Элемент &lt;?job?&gt; задает режим отладки при выполнении WS-файла. Если значение атрибута debug равно true, то задание может быть выполнено во внешнем отладчике (см. приложение 3). Если же значение атрибута debug равно false, то отладчик для этого задания применен быть не

Элемент <job>

Элемент &lt;job&gt; Элементы &lt;job&gt; позволяют определять несколько заданий (независимо выполняющихся частей) в одном WS-файле. Иначе говоря, между тегами &lt;job&gt; и &lt;/job&gt; будет находиться отдельный сценарий (который, в свою очередь, может состоять из нескольких частей,

Элемент <example>

Элемент &lt;example&gt; Внутри элемента &lt;example&gt; приводится текст из одной или нескольких строк, в котором можно описать примеры запуска сценария. Если сценарий был запущен с ключом /? в командной строке или в сценарии встретился вызов метода ShowUsage объекта WshArguments, то этот текст

Тег Title

Тег Title Содержимое тега Title является одним из наиболее значимых текстовых факторов ранжирования. С этим утверждением согласны все без исключения (что само по себе большая редкость) специалисты по продвижению сайтов, и это легко проверяется экспериментально. Уберите одно

Элемент TextBox

Элемент TextBox В предыдущем примере дата отображалась в текстовом поле. Это поле создается при помощи класса TextBox, который позволяет вводить текст. Данный элемент поддерживает такие стандартные свойства, как BackColor и ForeColor. Событие Click элементом TextBox не поддерживается, но

Элемент Label

Элемент Label В рассмотренном примере также использовался элемент Label для отображения текстовой строки. Как правило, надпись используется для отображения некоторого текста, который пользователь не может изменить. Сама отображаемая строка задается при помощи свойства Text.

Элемент RadioButton

Элемент RadioButton Элемент управления RadioButton позволяет создавать переключатели, объединенные в группы. Вся группа переключателей должна располагаться в контейнере. Примером такого контейнера может служить сама форма, но чаще используется элемент Panel.Когда пользователь

Элемент xsl:if

Элемент xsl:if Синтаксис элемента следующий:&lt;xsl:if test=»выражение»&gt; &lt;!— Содержимое: шаблон —&gt;&lt;/xsl:if&gt;Элемент xsl:if является простейшим условным оператором в XSLT. Выражение, содержащееся в обязательном атрибуте test, вычисляется и приводится к булевому типу. В том и только том

БЭМ и проблема наименования. Ускоряем и стандартизируем нейминг в HTML и CSS | by Aleksandr Serenko | F.A.F.N.U.R

Так как предыдущая статья оказалась довольно объёмной, дадим пару комментариев к использованным ранее подходам и поговорим об наименовании селекторов.

БЭМ

БЭМ (Блок, Элемент, Модификатор) — компонентный подход к веб-разработке. В его основе лежит принцип разделения интерфейса на независимые блоки. Он позволяет легко и быстро разрабатывать интерфейсы любой сложности и повторно использовать существующий код, избегая «Copy-Paste».

Формально БЭМ содержит множество инструментов для создания “умных компонентов”, но часто под БЭМ’ом подразумевают только именования CSS классов, что немного неверно. Если вы раньше никогда не слышали про БЭМ, то подробнее можно ознакомиться по ссылке.

БЭМ или не БЭМ, вот в чем вопрос.

Так как использовать весь БЭМ в Angular приложении не нужно (в фреймворке уже есть аналогичные инструменты для создания и использования компонентов), то поговорим о наименовании селекторов.

Отметим, что современные JS фреймворки, позволяют отказаться от создания классов, благодаря инкапсуляции стилей и компонентному подходу, но это работает только для небольших проектов. Данная статья приводит решения для enterprise, в котором есть множество проектов, которые взаимодействуют между собой (CRM, Accounts, Call center, Billing, …)

Разберём основы БЭМа на примерах. Есть HTML структура:

<divji jn">post post_v1">
<divji jn">post__header">
<divji jn">post__title"></div>
<divji jn">post__subtitle"></div>
</div>
<divji jn">post__body">
</div>
<divji jn">post__footer">
<divji jn">post__link"></div>
</div>
</div>

Блоки:

Элементы:

  • post__header
  • post__title
  • post__subtitle
  • post__body
  • post__footer
  • post__link

Модификаторы:

Мы создали компонент, состоящий из 1 блока с модификатором, который содержит 6 элементов.

Теперь создадим модификацию данного блока, добавив модификаторы блокам и элементам.

<divji jn">post_v1">
<div>
<div></div>
<div></div>
</div>
<divji jn">post__body_v1">
</div>
<div>
<div></div>
</div>
</div>

Как можно увидеть, у блока post и элемента post__body_v1 появились модификаторы.

Основные нюансы:

  • Правила одного блока не должны влиять на внутренний мир другого блока
  • Элемент должен быть расположен внутри блока
  • Нельзя создавать элементы элементов вида: post__header__title

Проблематика БЭМ’а

Есть четыре основные проблемы, которые возникают при первом использовании БЭМ’а.

  1. Name hell (Отсутствие требований к названиям блоков, который вводит в замешательство)
  2. Злоупотребление вложенностью элементов (Создание монолитных компонентов)
  3. Сильная связность компонентов (Монолит или множественные модификаторы)
  4. Проблема выбора имени (Выбор имён блокам, элементам, модификаторам)

Name hell

Первая проблема сводится к классической задаче вёрстки, которая звучит следующим образом:

Есть два вида сущностей: Новости (post) и События (event). Сначала идёт блок с новостью (новостями), затем блок с событием (событиями). Внешне новость и событие выглядит одинаково, но каждый из блоков имеет свои специфические отличия.

Задача: Нужно сверстать два блока, какие имена должны быть у post и event.

На практике, обычно сначала был только блок с новостями, потом добавили блок с событиями. Но блок с новостями уже свёрстан, а верстать новый блок с событиями с помощью копирования, запрещается DRY.

Есть несколько способов решения поставленной задачи:

Просто скопировать всю вёрстку одного компонента (или сверстать один компонент и продублировать). Тогда мы получим первую проблему:

<divji jn">post">
<divji jn">post__title">{{ post.title }}</div>
<divji jn">post__description">{{ post.description }}</div>
</div><divji jn">post post_{{ event. type }}">
<divji jn">post__title">{{ event.title }}</div>
<div>{{ event.description }}</div>
</div>

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

Для решения есть несколько способов, один из которых — отказаться от идеи совмещения, и благодаря препроцессорам CSS, вынести общие стили в “миксины/общие классы”, и для каждой из сущностей создать только изменяющиеся части блоков.

@mixin box {
color: white;
display: block;

&__title {
font-size: 2rem;
}

&__description {
font-size: 1rem;
}
}

. post {
@include box;
}

.event {
@include box;

&__title {
font-size: 1.25rem;
}
}

Что в результате позволит получить следующее:

<divji jn">post">
<divji jn">post__title">{{ post.title }}</div>
<divji jn">post__description">{{ post.description }}</div>
</div><divji jn">event">
<divji jn">event__title">{{ event.title }}</div>
<divji jn">event__description">{{ event.description }}</div>
</div>

Злоупотребление вложенностью элементов

Данная проблема проявляется при создании очень больших компонентов:

<divji jn">post">
<divji jn">post__row">
<divji jn">post__box">
<divji jn">post__title">. ..</div>
<divji jn">post__description">...</div>
</div>
<divji jn">post__box">
<divji jn">post__title">...</div>
<divji jn">post__description">...</div>
</div>
<divji jn">post__box">
<divji jn">post__title">...</div>
<divji jn">post__description">...</div>
</div>
</div>
</div>

И все вроде хорошо, но если вдруг потребуется использовать только часть данного блока, например:

<divji jn">post__box">
<divji jn">post__title">...</div>
<divji jn">post__description">...</div>
</div>

То тогда будет необходимо изменить основной блок и разбить его на несколько маленьких.

<divji jn">post">
<divji jn">post__row">
<divji jn">post-box">
<divji jn">post-box__title">. ..</div>
<divji jn">post-box__description">...</div>
</div>
<div>
<div>...</div>
<div>...</div>
</div>
<div>
<div>...</div>
<div>...</div>
</div>
</div>
</div>

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

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

Созданию новых БЭМ компонентов

Есть ряд рекомендаций к созданию маленьких и атомарных компонентов, которых придерживается автор, но которых нет в БЭМ’е:

  1. Используйте элементы БЭМ’а тогда и только тогда, когда элемент не может существовать без блока в принципе.

Например, мы создаём кнопку с иконкой. И стили иконки на 99% зависят от блока, и шанс, что мы захотим использовать стили расположения иконки очень малы, и тут применение БЭМ’а оправдано:

<divji jn">smart-button">
<spanji jn">smart-button__icon"></span> Upload
</div>

Однако, рассмотрим пример выше, и перепишем блок с новостями:

<div>
<div>
<div>
<divji jn">post-box">
<divji jn">post-box__title"></div>
<divji jn">post-box__description"></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>

Следующий вариант тоже будет хорошим решением:

<div>
<div>
<div>
<divji jn">post-box">
<divji jn">post-box-title">Title</div>
<divji jn">post-box-description"> Description</div>
</div>
</div>
<div>
<div>
<div>. ..</div>
<div>...</div>
</div>
</div>
<div>
<div>
<div>...</div>
<div>...</div>
</div>
</div>
</div>
</div>

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

Представим, что появились новые правки блока и теперь заголовок состоит из нескольких блоков — иконки и текста. Скорее всего, если вы использовали второй подход, то получится что-то вроде:

<divji jn">post-box">
<divji jn">post-box__title">
<divji jn">post-box__icon"></div>
<divji jn">post-box__text"></div>
</div>
<divji jn">post-box__description"></div>
</div>

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

<divji jn">post-box">
<divji jn">post-box__title">
<divji jn">post-box__icon"></div>
<divji jn">post-box__text"></div>
</div>
<divji jn">post-box__description">
<divji jn">post-box__icon"></div>
<divji jn">post-box__description-text"></div>
</div>
</div>

И конечно, украсим вишенкой на торте, изменив размер иконки в заголовке:

<divji jn">post-box">
<divji jn">post-box__title">
<divji jn">post-box__icon post-box__icon_v1"></div>
<divji jn">post-box__text"></div>
</div>
<divji jn">post-box__description">
<divji jn">post-box__icon"></div>
<divji jn">post-box__text"></div>
</div>
</div>

Если мы откажемся от элементов, то получим:

<divji jn">post-box">
<divji jn">post-box-title">
<divji jn">post-box-icon post-box-icon_v1"></div>
<divji jn">post-box-text"></div>
</div>
<divji jn">post-box-description">
<divji jn">post-box-icon"></div>
<divji jn">post-box-text"></div>
</div>
</div>

Что тоже является БЭМ’ом, где каждый HTML элемент представляет блок.

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

Сильная связность компонентов

Ещё один нюанс связанный с БЭМ’ом — темизация и изменение блоков.

Представим, что мы ведём проект несколько лет, и наш блок с новостями немного изменился. Добавились несколько различных видов, которые описываются так:

<div>
<div>
<divji jn">post-box_odd">
<divji jn">post-box__title_t1">
<div></div>
<div></div>
</div>
<div>
<div></div>
<divji jn">post-box__text_big"></div>
</div>
</div>
</div>
<div>
<divji jn">post-box_even">
<divji jn">post-box__title_t1">
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
<div>
<divji jn">post-box_odd">
<div>
<div></div>
<div></div>
</div>
<divji jn">post-box__description_small">
<div></div>
<div></div>
</div>
</div>
</div>
</div>

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

<div>
<div>
<divji jn">post-box_first post-box_odd">
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
<div>
<divji jn">post-box_second post-box_even">
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
<div>
<divji jn">post-box_third post-box_odd">
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>

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

<div>
<div>
<divji jn">post-box_first post-box_even">
<div>
<divji jn">smart-title">
<div></div>
<div></div>
</div>
</div>
<div></div>
</div>
</div>
<div>
<divji jn">post-box_second post-box_odd">
<div>
<divji jn">smart-title smart-title_second">
<div></div>
<div></div>
</div>
</div>
<div></div>
</div>
</div>
</div>

Где помимо того, что был добавлен модификатор к post-box, также был добавлен модификатор к smart-title, так как модификатор может изменять только тот блок, к которому он применён и не может изменять блоки, которые вложены в него.

Решением данной проблемы является создание темизированных компонентов.

Заметим, что данная техника противоречит одному из правил БЭМ’а, что модификатор не может влиять на другие вложенные блоки. Если необходимо строгое соблюдение БЭМ’а, то вы не должны использовать темизацию.

Темизация — модификатор родительского блока, может переопределять текущие стили блока.

Разберём на примере. Необходимо создать две карточки, которые будут иметь 2 темы — светлую и тёмную. В светлой теме белый фон чёрный текст, в тёмной теме чёрный фон, белый текст.

Создадим разметку в строгом варианте БЭМ’а:

<divji jn">post-box">
<divji jn">post-box__title"></div>
<divji jn">post-box__description">
<divji jn">post-form">
<divji jn">post-form__group">
<inputji jn">post-form__control">
</div>
<divji jn">post-form__group">
<inputji jn">post-form__control">
</div>
</div>
</div>
</div>

И соответствующие темы:

.post-box {
&__title {}
&__description {}

&_white {
background: white;
color: black;
}

&_black {
background: black;
color: white;
}
}

Так как у нас есть вложенные блоки в post-box, то для этих блоков, тоже нужны свои темы:

. post-form {
&_white {
background: white;
color: black;
}

&_black {
background: black;
color: white;
}
}

Полный вариант разметки:

<divji jn">post-box post-box_white">
<div></div>
<div>
<divji jn">post-form post-box_white">
<div>
<input>
</div>
<div>
<input>
</div>
</div>
</div>
</div>

И все стили:

.post-box {
&__title {
}
&__description {
}

&_white {
background: white;
color: black;
}

&_black {
background: black;
color: white;
}
}

. post-form {
&_white {
background: white;
color: black;
}

&_black {
background: black;
color: white;
}
}

Применим подход темизации, убрав темы для post-form на уровень родительского блока:

.post-box {
&__title {
}
&__description {
}

&_white {
background: white;
color: black;
}

&_black {
background: black;
color: white;
}
}

.post-form {
.post-box_white {
background: white;
color: black;
}

. post-box_black {
background: black;
color: white;
}
}

Тогда соответственно разметка станет:

<divji jn">post-box post-box_white">
<div></div>
<div>
<divji jn">post-form">
<div>
<input>
</div>
<div>
<input>
</div>
</div>
</div>
</div>

Как можно увидеть, теперь оформление post-form зависит от модификатора post-box.

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

Для проверки можете создать блок, с двумя вложенными в друг друга блока ( A > B > C) и для каждого из блоков задайте по несколько состояний, например блок А имеет 2 состояния, блок B имеет 3 состояния, а состояние блока С определяется по выбранному состоянию блока А и блока B, т.е. как минимум 6 состояний (A1 + B1, A1 + B2, A1 + B3, A2 + B1, A2 + B2, A2 + B3), если сам C не имеет своих собственных.

Просто представьте форму регистрации с 40 полями, где некоторые поля связаны между собой (дата выдачи паспорта и дата рождения, где дата выдачи зависит от даты рождения, так как в РФ люди должны менять паспорта в определённые года), где поле может быть не заполненным, валидным и не валидным, плюс есть автозаполнение и т.д. Если вы будете писать действительно гибкие UI интерфейсы, а также полностью придерживаться БЭМ’а это увеличит код в несколько раз. Темизация позволяет снизить нагрузку на количество и контроль классов.

Для примера приведём стили для блоков без/с использованием темизации:

. post-box {
&_white {
padding: 0.5rem;
}

&_white &__title {
color: black;
}

&_white &__description {
color: black;
}

&_black {
padding: 1rem;
}

&_black &__title {
color: white;
}

&_black &__description {
color: white;
}
}

.post-form {
&_white {
padding: 0.5rem;
}

&_white &__group {
padding: 0.5rem;
}

&_white &__control {
color: black;
}

&_black {
padding: 1rem;
}

&_black &__group {
padding: 1rem;
}
&_black &__control {
color: white;
}
}

Как можно увидеть из примера, мы получили 2 монолитных компонента, в которых есть 2 темы.

Перепишем пример, используя темизацию:

.post-box {
&_white {
padding: 0.5rem;
}

&_white &__title {
color: black;
}

&_white &__description {
color: black;
}

&_black {
padding: 1rem;
}

&_black &__title {
color: white;
}

&_black &__description {
color: white;
}
}

.post-form {
.post-box_white {
padding: 0.5rem;
}

.post-box_white &__group {
padding: 0.5rem;
}

.post-box_white &__control {
color: black;
}

. post-box_black {
padding: 1rem;
}

.post-box_black &__group {
padding: 1rem;
}
.post-box_black &__control {
color: white;
}
}

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

Применим подход маленьких атомарных блоков. Разметка примет вид:

<divji jn">post-box">
<divji jn">post-box-title"></div>
<divji jn">post-box-description">
<divji jn">post-form">
<divji jn">post-form-group">
<inputji jn">post-form-control" />
</div>
<divji jn">post-form-group">
<inputji jn">post-form-control" />
</div>
</div>
</div>
</div>

И соответствующие стили:

. post-box {
&_white {
padding: 0.5rem;
}
&_black {
padding: 1rem;
}
}

.post-box-title {
.post-box_white & {
color: black;
}
.post-box_black & {
color: white;
}
}

.post-box-description {
.post-box_white & {
color: black;
}
.post-box_black & {
color: white;
}
}

.post-form {
.post-box_white & {
padding: 0.5rem;
}

.post-box_black & {
padding: 1rem;
}
}

.post-form-group {
. post-box_white & {
padding: 0.5rem;
}
.post-box_black & {
padding: 1rem;
}
}

.post-form-control {
.post-box_white & {
color: black;
}
.post-box_black & {
color: white;
}
}

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

Проблематика имен

Используя разные методологии для задания имён, такие как БЭМ, всё равно остаётся один не решенный вопрос — какие имена выбирать.

Есть 2 критерия, которые позволяют определить, что вы неверно выбираете названия селекторам:

  1. Если после завершения вёрстки и в процессе её интеграции или внесения новых правок приходится изменять более 25% используемых селекторов.
  2. Если по окончанию работы есть желание отрефакторить проект.

Возьмём для примера, наш любимый блок новостей. Представим, что в вёрстке он используется в 3 местах:

  • 3 плашки (картинка + заголовок + короткое описание) на главной странице
  • Список последних новостей в разделе клиента (заголовок ссылка)
  • На странице товара, есть блок с новостями — 3 плашки (картинка и заголовок)

Так как мы представляем enterprise решение, одним из требований является отсутствие пересечений стилей между компонентами. Следовательно нужен механизм, который позволил бы минимизировать коллизию имён.

Одной из таких техник является Entity-ViewType-Element (сущность — тип представления — элемент).

Под сущностью подразумевается некая, атомарная, независимая часть бизнес логики проекта. Например: статья, фильм, пользователь, товар.

Под типом представления подразумевается контекст, в котором выводится сущность. Например: box, card, list, promo, action.

Под элементом подразумевается некоторая часть сущности. Например: title, description, name, link, image.

Зададим названия первому варианту:

<divji jn">post-card">
<divji jn">post-card-image">
<img src="" alt=""ji jn">post-card-image__source">
</div>
<divji jn">post-card-title">...</div>
<divji jn">post-card-description">...</div>
</div>

Где стили:

.post-card {
}.post-card-image {
&__source {}
}.post-card-title {
}.post-card-description {
}

Реализуем второй вариант:

<ulji jn">post-links">
<liji jn">post-link">
<a href=""ji jn">post-link-title">...</a>
</li>
<liji jn">post-link">
<a href=""ji jn">post-link-title">...</a>
</li>
<liji jn">post-link">
<a href=""ji jn">post-link-title">. ..</a>
</li>
<liji jn">post-link">
<a href=""ji jn">post-link-title">...</a>
</li>
<liji jn">post-link">
<a href=""ji jn">post-link-title">...</a>
</li>
</ul>

И соответствующие стили:

.post-links {
}

.post-link {
}

.post-link-title {
text-decoration: underline;
}

Реализуем третий вариант. Отметим, что данный вариант совпадает с первым вариантом, но так как мы используем EVTE, то получим:

<div>
<div>
<img src="" alt="">
</div>
<div></div>
</div>

И стили:

.post-box {
position: relative;
}

. post-box-image {
&__source {
max-width: 100%;
width: 100%;
}
}

.post-box-title {
bottom: 1rem;
left: 0;
padding: 0 1rem;
position: absolute;
}

Как можно увидеть из кода, коллизия имён решается с помощью ViewType.

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

В данных примерах, были использованы два представления — box и card. Но если нам понадобиться ещё варианты? Добавим, например, portlet!

Весь смысл EVTE сводится к тому, чтобы определить фиксированный список имён для сущностей и их представлений, элементами которых будут выступать поля сущностей.

Например, обычный интернет магазин, можно описать следующим множеством:

Сущности: User, Profile, Account, Product, Basket, Promotion, Ticket, Comment, Partner, Referral, Coupon, Tag, Post, Category.

Типы представлений: box, card, portlet, list, grid, line, table, promo, action и менее предпочтительные варианты, которых стоит избегать — hard, lite, small, large, top, bottom и т.д.

Элементы: title, description, name, fullName, id, link, url, created, updated, published, promo, action, actions, loaded, loading, amount, price и т.д.

Теперь для сущности User можно реализовать как минимум — 10 различных представлений. Но если и этого мало, всегда можно расширить список, и добавить префиксы и постфиксы к сущности, такие как — smart, new …

Заключение

В данной статье была рассмотрена техника БЭМ для именования CSS классов. Были рассмотрены основные проблемы при использовании БЭМ’а, такие как NameHell, Злоупотребление вложенностью, Темизация компонентов. Для каждой из проблем было приведено решение, которое позволяет минимизировать негативные эффекты. В конце статьи был разобрана тема связанная с заданием имён селекторам по технике EVTE.

В следующией статье поговорим о классических решениях вёрстки.

Спасибо за внимание!

Предыдущие статьи:

  1. Основы верстки в Angular c Redux и Nx. Часть 1. Верстка Header и Navbar.

Учебник CSS 3. Статья «Селекторы. Часть 3»

В этой объемной статье учебника мы с Вами продолжим изучение селекторов, рассмотрим с Вами примеры работы селекторов, предназначенных для выбора элементов с определёнными HTML атрибутами, познакомимся с псевдоклассом отрицания и рассмотрим некоторые новые для Вас, и очень полезные псевдоклассы, которые позволят нам выбирать элементы в зависимости от их расположения в документе.

Селекторы атрибутов

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

Давайте рассмотрим следующий селектор и попробуем разобраться, что он значит:


img[title] { /* выбирает все элементы <img> с атрибутом title */
блок объявлений;
}

img в данной случае аналогичен селектору типа, т.е выбирает все элементы <img>, а в квадратных скобках мы задаем имя атрибута этого элемента. То есть происходит выборка всех элементов данного типа с определённым атрибутом, в нашем примере это глобальный атрибут title, определяющий текстовую подсказку о содержимом элемента.

Вы можете использовать селекторы атрибутов не только напрямую к элементам, но и использовать их с прочими селекторами, например с селекторами класса или id селекторами:


.main[title] { /* выбирает все элементы с классом main и атрибутом title */
блок объявлений;
} 
#main[title] { /* выбирает элемент с идентификатором main и атрибутом title */
блок объявлений;
} 

В данном случае первый селектор выбирает все элементы, которые имеют значение глобального атрибута class равным main и глобальным атрибутом title. Второй селектор выбирает элемент, который имеют значение глобального атрибута id равным main и глобальным атрибутом title.

Рассмотрим следующий пример в котором, мы выберем все элементы <img>, у которых присутствует атрибут alt, который задает альтернативный текст для изображения.


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Пример использования селектора атрибутов</title>
<style>
img { /* выбираем все изображения */
width: 100px;  /* задаем ширину элемента */
height: 100px;  /* задаем высоту элемента */
}
img[alt] { /* выбираем все изображения с атрибутом alt */
border: 1px solid green; /* устанавливаем сплошную границу размером 1 пиксель зеленого цвета */
} 
</style>
</head>
	<body>
		<img src = "nich.jpg" alt = "nich">
		<img src = "nich.jpg"> <!-- элемент не будет стилизован (отсутствует атрибут alt) -->
		<img src = "nich. jpg" alt = "nich">
	</body>
</html>

Результат нашего примера:

Рис. 17г Пример использования селектора атрибутов.

С помощью селектора атрибутов мы можем выбрать элементы не только с определённым атрибутом, но и указать с каким значением должен быть этот атрибут.

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


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Селектор атрибута с указанным значением</title>
<style>
input[type=password] { /* выбираем все элементы <input>, атрибут type которых имеет значение password */
border: 1px dotted red; /* устанавливаем точечную границу размером 1 пиксель красного цвета */
} 
input[type=password]:focus { /* выбираем элемент <input>, атрибут type которого имеет значение password и который находится в фокусе */
border: 1px solid green; /* устанавливаем сплошную границу размером 1 пиксель зеленого цвета */
} 
</style>
</head>
	<body>
		<form>
			Login: <input type = "text" name = "login" placeholder = "Введите ваш логин"><br><br>
			Password: <input type = "password" name = "password" placeholder = "Введите ваш пароль"><br><br>
			<input type = "submit" name = "submit" value = "Далее">
		</form>
	</body>
</html>

В этом примере мы использовали два селектора атрибутов с указанным значением, которые позволили нам выбрать поле, предназаченное для ввода пароля, а во втором случае с использованием псевдокласса :focus мы создали стили для того состояния, когда это поле находится в фокусе (пользователь кликнул на него, или выбрал с помощью клавиатуры). = «https://»] { /* групповой селектор атрибутов */ color: orange; /* устанавливаем цвет текста */ } </style> </head> <body> <p>Сайт компании доступен как по протоколу http, так и по протоколу https:</p> <ul> <li><a href = «http://сайткомпании.ссср»>Адрес с http</a></li> <li><a href = «https://сайткомпании.ссср»>Адрес с https</a></li> </ul> <p>Может вы настроите перенаправление?</p> </body> </html>


Обратите внимание, что значение атрибута в этом случае мы указываем в кавычках, чтобы браузер не интерпретировал это как начало гиперссылки.


Результат нашего примера:

Рис. 17е Пример использования селектора атрибута со значением, начинающимся с определённых символов.

В CSS 3 был введен не только селектор атрибутов, который позволяет выбирать элементы, чьи атрибуты начинаются с определённых символов, но и элементы, чьи атрибуты заканчиваются определёнными символами.

Давайте рассмотрим пример в котором мы выберем гиперссылки, которые заканчиваются определённым разрешением файла.


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Селектор атрибута со значением, заканчивающимся определёнными символами</title>
<style> 
a[href$=".doc"] { /* выбираем все элементы с атрибутом href, значение которого закачивается на .doc */
color: green; /* устанавливаем цвет текста */
background-color: lightblue; /* устанавливаем цвет заднего фона */
}
a[href$=".mp3"] { /* выбираем все элементы с атрибутом href, значение которого закачивается на .mp3 */
background-color: khaki; /* устанавливаем цвет заднего фона */
}
</style>
</head>
	<body>
		<a href ="http:/path.to/test.doc">Инструкция</a><br>
		<a href ="http:/path.to/test.mp3">Песня про зайцев</a>
	</body>
</html>

Обратите внимание, что значение атрибута в этом случае мы указываем в кавычках, чтобы браузер не интерпретировал это как разрешение файла.


Результат нашего примера:

Рис. 18 Пример использования селектора атрибутов со значением, заканчивающимся определёнными символами.

Давайте рассмотрим с Вами какие еще выборки можно сделать с использованием селектора атрибутов и перейдем к изучению такого полезного инструмента как псевдокласс отрицания.

Следующий селектор позволит нам, к примеру, выбрать изображения, которые содержат в названии IMG_ (как правило такое наименование файлов использует компания Canon):


img [src*="IMG_"] { /* выбирает все элементы img, атрибут src, которых содержит символы "IMG_" */
блок объявлений;
}  
/* селектор выбирает элементы с такими значениями как "xxxIMG_", "IMG_xxxx" и "xxxIMG_xxxx" */

Браузер интерпретирует это как необходимость выбора всех изображений, атрибут src которых содержит IMG_ (в любом месте). Зачастую такой способ позволяет быстрее отформатировать необходимые элементы, по сравнению с созданием и присвоением стилевого класса для каждого элемента.

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


p[title ~="home"] { /* выбирает элементы <p>, которые содержат определенное слово */
блок объявлений;
}  

<p title = "go home">Абзац title="go home"</p> <!-- абзац будет стилизован (содержит home) -->
<p title = "home home" >Абзац title="home home"</p> <!-- абзац будет стилизован (содержит home) -->
<p title = "home-1" >Абзац title="home1"</p> <!-- абзац не будет стилизован -->
<p title = "homes" >Абзац title="homes"</p> <!-- абзац не будет стилизован -->
<p title = "shome">Абзац title="shome"</p> <!-- абзац не будет стилизован -->

Ну и заключительный селектор атрибута, который имеется в современном стандарте, позволяет выбрать элемент значение атрибута которого начинается с определенного слова:


[title | = home] { /* выбирает все элементы с атрибутом, значение которого начинается с определённого слова (после него не должно быть никаких символов, либо допускается продолжать значение через дефис, иначе выборка не будет произведена) */
блок объявлений;
}  

<p title = "home">Абзац title="home"</p> <!-- абзац будет стилизован (начинается с home) -->
<p title = "home-1" >Абзац title="home-1"</p> <!-- абзац будет стилизован (начинается с home после которого следует дефис) -->
<p title = "home home">Абзац title="home home"</p> <!-- абзац не будет стилизован -->
<p title = "not home">Абзац title="not home"</p> <!-- абзац не будет стилизован -->
<p title = "homes" >Абзац title="homes"</p> <!-- абзац не будет стилизован -->
<p title = "shome">Абзац title="shome"</p> <!-- абзац не будет стилизован -->
Обратите внимание, что условие выборки будет соблюдено если атрибут содержит значение, которое содержит только указанное слово, или если после указанного слова сразу следует дефис (значение продолжается через дефис).

Псевдокласс отрицания :not()

Селектор :not() или псевдокласс отрицания, позволяет выбрать элементы, или селекторы отличные от указанных.


Что нельзя использовать с псевдоклассом :not():

  • Использовать в одном селекторе несколько псевдоклассов :not().
  • Использовать с псевдоэлементами (::first-letter, ::first-line и так далее).
  • Нельзя использовать с селекторами потомков (например, div ul a).
  • Использовать в групповых селекторах (комбинации из селекторов).

Давайте рассмотрим пример в котором по разному стилизуем изображения. Допустим у нас есть изображения фиксированного размера со следующими значениями:


img { /* выбираем все изображения */
width: 100px; /* ширина элемента в пикселях */
height: 100px; /* высота элемента в пикселях */
}

Создадим селектор класса .photo и применим его к необходимым изображениям, чтобы они получили оранжевую границу.


.photo { /* выбираем все элементы с классом photo */
border: 2px solid orange; /* сплошная граница размером 2 пикселя оранжевого цвета */
}

Перед Вами стоит задача изменить стиль для всех изображений (предположим, что их сотни), но при этом у Вас ограниченное количество времени и необходимо сделать так, чтобы эти изменения затронули изображения с классом .photo. Для этого Вам необходимо создать селектор совместно с псевдоклассом отрицания:


img:not(.photo)  { /* выбираем все изображения, которые не имеют класса photo */
border: 2px dashed green; /* пунктирная граница размером 2 пикселя зеленого цвета */
}

Всё вместе и результат:


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Псевдокласс отрицания :not()</title>
<style>
img { /* выбираем все изображения */
width: 100px; /* ширина элемента в пикселях */
height: 100px; /* высота элемента в пикселях */
}
. photo { /* выбираем все элементы с классом photo */
border: 2px solid orange; /* сплошная граница размером 2 пикселя оранжевого цвета */
}
img:not(.photo)  { /* выбираем все изображения, которые не имеют класса photo */
border: 2px dashed green; /* пунктирная граница размером 2 пикселя зеленого цвета */
}
</style>
</head>
	<body>
		<img src = "nich.jpg" alt = "nich" class = "photo">
		<img src = "nich.jpg" alt = "nich" class = "photo"><br>
		<img src = "nich.jpg" alt = "nich"> 
		<img src = "nich.jpg" alt = "nich"> 
		<img src = "nich.jpg" alt = "nich">
	</body>
</html>

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

Рис. 19 Пример использования псевдокласса отрицания :not() в CSS.

Селекторы дочерних элементов

Селектор дочерних элементов позволяет форматировать элементы, вложенные внутрь других элементов (выбирает все дочерние элементы внутри элемента родителя).

Элемент, подчиненный другому элементу более высокого уровня, является дочерним. На изображении ниже оба элемента <h3> и <p> являются дочерними по отношению к <body>, но элемент <i> при этом не является дочерним для элемента <body>, так как он расположен внутри тега <p>, и является дочерним именно для него.


Рис. 20 Дочерние элементы в HTML документе.

Перед нами стоит задача стилизовать гиперссылку (элемент <a>), который выделен оранжевым цветом на изображении:


Рис. 20а Задача выбора элемента на странице.

При использовании селектора потомков body a приведет к выбору всех элементов <a>, так как они являются вложенными по отношению к элементу <body>, если мы используем селектор потомков p a, то это приведет к выбору двух элементов <a>, которые вложены внутри элементов <p>, так как они оба являются его потомками. Селекторы потомков мы с Вами рассматривали в статье «Селекторы. Часть 2».

В нашем случае, как никогда лучше подойдет селектор дочерних элементов, благодаря которому мы можем добраться до необходимого нам элемента <a> самым простым способом.


p > a { /* выбирает любой элемент <a> дочерний по отношению к <p> */
блок объявлений;
}

Рассмотрим пример:


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Селектор дочерних элементов</title>
<style>
p>a { /* селектор дочерних элементов (выбираем дочерние <а>, вложенные в <p>) */
color: orange; /* устанавливаме цвет текста */
font-size: /* устанавливаме размер текста текста */
}
p a { /* селектор потомков (выбираем все потомки <a>, вложенные в <p>) */
text-decoration: none; /* убираем декорирование текста (нижнее подчеркивание) */
}
</style>
</head>
	<body>
		<p><a href = "https://ru. wikipedia.org/">Ссылка</a> внутри &amplt;p&ampgt;.</p>
		<a href = "https://ru.wikipedia.org/">Ссылка</a> внутри &amplt;body&ampgt;.
		<p><span><a href = "https://ru.wikipedia.org/">Ссылка</a></span> внутри элемента &amplt;p&ampgt;, вложенного в элемент &amplt;p&ampgt;.</p>
	</body>
</html>

В этом примере с использованием селектора дочерних элементов мы выбрали все дочерние <a>, вложенные в <p> (один элемент), а с помощью селектора потомков стилизовали все потомки <a>, вложенные в <p> (убрали декорирование текста у двух элементов).

Результат нашего примера:

Рис. 20б Пример использования селектора дочерних элементов.

Псевдоклассы дочерних элементов

Псевдокласс :first-child

Псевдокласс :first-child применяет стиль к элементу в том случае, если элемент является первым дочерним элементом своего родителя.


Рис. 21 Выборка с использованием псевдокласса дочерних элементов.

Давайте рассмотрим пример, в котором перед Вами стоит задача изменить стиль для всех элементов, которые выделены оранжевым цветом на изображении:


Рис. 21а Пример выбора селектора дочерних элементов.

Что общего у элементов, выделенных на изображении? А общее у них то, что выделенные элементы <h3> и <li> являются первыми дочерними элементами своих родителей, и чтобы нам их стилизовать необходимо использовать псевдокласс :first-child.

Перейдем к примеру:


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Псевдокласс :first-child</title>
<style>
h3:first-child { /* выбираем каждый элемент <h3>, который является первым дочерним элементом своего родителя */
color: blue; /* устанавливаем цвет текста */
}
li:first-child{ /* выбираем каждый элемент <li>, который является первым дочерним элементом своего родителя */
color: red; /* устанавливаем цвет текста */
font-size: 24px; /* устанавливаем размер шрифта */
}
</style>
</head>
	<body>
		<h3>Первый заголовок h3 тега body</h3>
		<ul>
			<li>один</li>
			<li>два</li>
			<li>три</li>
		</ul>
		<h3>Второй заголовок h3 тега body</h3>
		<article>
			<h3>Первый заголовок h3 тега article</h3>
			<ul>
				<li>один</li>
				<li>два</li>
				<li>три</li>
			</ul>
		</article>
	</body>
</html> 

В этом примере с использованием псевдокласса :first-child мы стилизовали элементы <h3> и <li>, которые являются первыми дочерними элементами своих родителей.

Результат нашего примера:

Рис. 22 Пример использования псевдокласса :first-child.

Псевдокласс :last-child

Псевдокласс :last-child применяет стиль к элементу в том случае, если элемент является последним дочерним элементом своего родителя.

Этот псевдокласс в отличие от псевдокласса :first-child выбирает последний дочерний элемент своего родителя, а не первый.

Давайте рассмотрим пример, в котором перед Вами стоит задача изменить стиль для всех элементов, которые выделены оранжевым цветом на изображении:


Рис. 23 Пример выбора селектора дочерних элементов.

Что общего у элементов, выделенных на изображении? А общее у них то, что выделенные элементы <article> и <li> являются последними дочерними элементами своих родителей, и чтобы нам их стилизовать необходимо использовать псевдокласс :last-child.

Если вы сходу сможете ответить почему ни один элемент <h3> на изображении выше нельзя стилизовать с использованием псевдокласса :last-child, то можете сразу перейти к примеру, если нет, то внимательно изучите следующее изображение, оно поможет Вам до конца понять как работает псевдокласс :last-child:


Рис. 23а Схема работы псевдокласса :last-child.

Еще раз поясню, если вы создадите селектор h3:last-child, то браузер не найдет этот элемент по той причине, что нет элементов <h3>, которые являются последними дочерними элементами своего родителя, важно это понять, так как подобные вещи иногда ставят людей в ступор.

Перейдем к примеру:


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Псевдокласс :last-child</title>
<style>
article:last-child { /* выбираем каждый элемент <article>, который является последним дочерним элементом своего родителя */
background-color: orange; /* устанавливаем цвет фона */
}
li:last-child{ /* выбираем каждый элемент <li>, который является последним дочерним элементом своего родителя */
color: red; /* устанавливаем цвет текста */
font-size: 24px; /* устанавливаем размер шрифта */
}
</style>
</head>
	<body>
		<h3>Первый заголовок h3 тега body</h3>
		<ul>
			<li>один</li>
			<li>два</li>
			<li>три</li>
		</ul>
		<h3>Второй заголовок h3 тега body</h3>
		<article>
			<h3>Первый заголовок h3 тега article</h3>
			<ul>
				<li>один</li>
				<li>два</li>
				<li>три</li>
			</ul>
		</article>
	</body>
</html> 

В этом примере с использованием псевдокласса :last-child мы стилизовали элементы <article> и <li>, которые являются последними дочерними элементами своих родителей.

Результат нашего примера:

Рис. 23б Пример использования псевдокласса :last-child.

Псевдокласс :nth-child

Стилизация по порядковому номеру

Ну что сказать, у нас остались неоконченные дела, которые касаются стилизации того самого неуловимого элемента <h3>, а на помощь в этом нам придет псевдокласс :nth-child.

Псевдокласс :nth-child позволяет выбрать дочерние элементы внутри родительского элемента в зависимости от их размещения (порядкового номера). Применение данного псевдокласса широко распространено, он позволяет чередовать стили строк в таблицах, списках, придать стиль сочетанию дочерних элементов и так далее.

Давайте рассмотрим пример, в котором перед Вами стоит задача изменить стиль для всех элементов, которые выделены оранжевым цветом на изображении:


Рис. 24 Пример выбора селектора дочерних элементов.

Что общего у элементов, выделенных на изображении? А общее у них то, что они выделены оранжевым цветом. Смешно? Не думаю. Общее у них все же есть, элементы <li> являются вторыми дочерними элементами своих родителей, а элемент <h3> тоже можно посчитать, и его порядковый номер будет третьим (третий дочерний элемент своего родителя <body>). Чтобы стилизовать эти элементы, нам необходимо использовать псевдокласс :nth-child.

Перейдем к примеру:


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Псевдокласс :first-child</title>
<style>
/* групповой селектор, который выбирает каждый третий дочерний элемент <h3> своего родителя
и каждый второй элемент <li> своего родителя  */
h3:nth-child(3), li:nth-child(2) { 
background-color: orange; /* устанавливаем цвет заднего фона */
}
</style>
</head>
	<body>
		<h3>Первый заголовок h3 тега body</h3>
		<ul>
			<li>один</li>
			<li>два</li>
			<li>три</li>
		</ul>
		<h3>Второй заголовок h3 тега body</h3>
		<article>
			<h3>Первый заголовок h3 тега article</h3>
			<ul>
				<li>один</li>
				<li>два</li>
				<li>три</li>
			</ul>
		</article>
	</body>
</html> 

В этом примере с использованием псевдокласса :nth-child мы стилизовали элементы <h3> и <li>, которые имеют определённый порядковый номер дочернего элемента внутри своих родительских элементов.

Результат нашего примера:

Рис. 24а Пример использования псевдоэлемента :last-child.

Продвинутое использование псевдокласса :nth-child

Стилизация по ключевому слову

В качестве значения псевдокласса :nth-child может выступать не только порядковый номер дочерних элементов, которые необходимо стилизовать, но и ключевые слова, которые могут определять целую группу элементов. В качестве ключевого слова можно использовать два значения:

  • even (четные элементы)
  • odd (нечетные элементы)

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

Давайте для примера создадим две простые таблицы с разными стилевыми классами и рассмотрим наглядно разницу в применении значений ключевых слов псевдокласса :nth-child для HTML элемента <tr>, который определяет строку таблицы:


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Стилизация четных и нечетных дочерних элементов</title>
<style>
. primer1 tr:nth-child(even)  { /* стилизация четных дочерних элементов */
background-color: #AAA; /* устанавливаем цвет заднего фона */
}
.primer2 tr:nth-child(odd)  { /* стилизация нечетных дочерних элементов */
background-color: #AAA; /* устанавливаем цвет заднего фона */
}
caption {/* селектор типа (выбираем HTML элемент <caption>) */
color: red; /* устанавливаем цвет текста */
}
</style>
</head>
	<body>
		<table class = "primer1">
			<caption>Значение even (четные)</caption>
			<tr>
				<th>1 строка</th><th>Позиция</th><th>Количество</th>
			</tr>
			<tr>
				<td>2 строка</td><td></td><td></td>
			</tr>
			<tr>
				<td>3 строка</td><td></td><td></td>
			</tr>
			<tr>
				<td>4 строка</td><td></td><td></td>
			</tr>
			<tr>
				<td>5 строка</td><td></td><td></td>
			</tr>
		</table>
		<table class = "primer2">
			<caption>Значение odd (нечетные)</caption>
			<tr>
				<th>1 строка</th><th>Позиция</th><th>Количество</th>
			</tr>
			<tr>
				<td>2 строка</td><td></td><td></td>
			</tr>
			<tr>
				<td>3 строка</td><td></td><td></td>
			</tr>
			<tr>
				<td>4 строка</td><td></td><td></td>
			</tr>
			<tr>
				<td>5 строка</td><td></td><td></td>
			</tr>
		</table>
	</body>
</html>

В этом примере с использованием псевдокласса :nth-child мы стилизовали четные строки первой таблицы (элементы <tr>) и нечетные во второй таблице.

Рис. 24б Пример стилизации четных и нечетных дочерних элементов.
Стилизация по простой математической формуле

Псевдокласс :nth-child позволяет выбрать не только чётные, нечетные, или дочерние элементы с определённым порядковым номером, но и дочерние элементы, заданные по элементарной математической формуле. Давайте рассмотрим следующий селектор и разберем, что значит эта запись:


td:nth-child(4n+2)  {
background-color: lightblue; /* устанавливаем цвет заднего фона */
}

Этот селектор означает, что каждая четвёртая ячейка таблицы (<td>) внутри строки, начиная со второй ячейки таблицы, будет стилизована:

  • 4n – каждый четвертый элемент.
  • 2 – с какого элемента начинать.

В формулах допускается использование значений со знаком вычитания, но в этом как правило нет необходимости:


td:nth-child(4n-1)  {
background-color: lightblue; /* устанавливаем цвет заднего фона */
}

Этот селектор означает, что каждая четвёртая ячейка таблицы (<td>) внутри строки, начиная с третьей ячейки таблицы (-1 ячейки нет по объективным причинам, поэтому происходит сдвиг влево), будет стилизована:

  • 4n – каждый четвертый элемент.
  • -1 – с какого элемента начинать.

Давайте рассмотрим пример использования:


<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Стилизация дочерних элементов по математической формуле</title>
<style>
td, th{ /* групповым селектором выбираем заголовочные ячейки и ячейки данных */
border: 1px solid green; /* задаём сплошную границу размером 1 пиксель зеленого цвета */
width: 50px;  /* устанавливаем ширину заголовочным ячейкам и ячейкам данных */
}
td:nth-child(4n+2) {
background-color: lightblue; /* устанавливаем цвет заднего фона */
}
</style>
</head>
	<body>
		<table>
			<tr>
				<th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>10</th><th>11</th><th>12</th><th>13</th><th>14</th>
			</tr>
			<tr>
				<td>2</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>
			</tr>
			<tr>
				<td>3</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>
			</tr>
			<tr>
				<td>4</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>
			</tr>
		</table>
	</body>
</html>


В этом примере с использованием псевдокласса :nth-child мы выбрали и стилизовали каждую четвёртую ячейку таблицы (<td>) внутри строки, начиная со второй ячейки таблицы. Результат нашего примера:

Рис. 25 Пример cтилизации дочерних элементов по математической формуле.

Вопросы и задачи по теме

Перед тем как перейти к изучению следующей темы пройдите практические задания:

  • Для выполнения задания вам понадобится скачать архив и скопировать содержимое архива (HTML файлы и изображения) в любую папку на вашем жестком диске:

  • Составьте следующие HTML страницы:
    1. Составьте селектор, который позволит Вам стилизовать все изображения, которые имеют глобальный атрибут title: Практическое задание № 5.
    2. Продвинутое задание: составьте селектор, который позволит Вам стилизовать все изображения, но не изображение, которое имеет значение атрибута alt равным «medved»: Практическое задание № 6.
    3. С использованием изученных псевдоклассов составьте селекторы, которые позволят Вам стилизовать абзацы (элементы <p>) в соответствии с изображением: Практическое задание № 7.

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

на Русском · Примеры · CSS, HTML, Toolkit для Front-end разработчиков

Заголовки & основной текст

HTML-заголовки, от <h2> до <h6>:

h3. Заголовок 2

h4. Заголовок 3

h5. Заголовок 4
h5. Заголовок 5
h6. Заголовок 6

Пример основного текста

В Bootstrap по умолчанию font-size равняется 14px, а line-height составляет 20px. Эти правила применяются к элементу <body> и всему тексту. В дополнение, элемент <p> (Параграф) имеет отсуп снизу в половину line-height т.е. равен 10px по умолчанию.

Было восемь часов утра — время, когда офицеры, чиновники и приезжие обыкновенно после жаркой, душной ночи купались в море и потом шли в павильон пить кофе или чай. Иван Андреич Лаевский, молодой человек лег двадцати восьми, худощавый блондин, в фуражке министерства финансов и в туфлях, придя купаться, застал на берегу много знакомых и между ними своего приятеля, военного доктора Самойленко.

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

Это письмо должен Вам доставить мой ключник Трофим ровно в 8 часов вечера. Если же привезет его пожже, то побейте его по щекам, по профессорски, нечего с этим племенем церемонится. Если доставит пожже то значит в кабак анафема заходил. Обычай ездить к соседям не нами выдуман не нами и окончится, а потому непременно приежжайте с машинками и книгами. Я бы сам к Вам поехал, да конфузлив очень и смелости не хватает..

<p>...</p>

Класс Lead

Выделите параграф добавив класс .lead.

Это письмо должен Вам доставить мой ключник Трофим ровно в 8 часов вечера.

<p>...</p>

Созданно при помощи Less

Оформление основанно на двух LESS-переменных в файле variables.less: @baseFontSize и @baseLineHeight. Первая задает font-sizec, вторая устанавливает line-height. Используя простые матиматические уравнения мы задаем внешние и внутренние отсупы элементов, высоту строки и многое другое. Редактируйте их для оптимизации и создания своего персонального Bootstrap’а.


Выделение шрифта

Используйте стандартные HTML-теги для выделения шрифта.

<small>

Для уменьшения значения текста на странице используйте тег small.

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

<p>
  <small>Было восемь часов утра - время, когда офицеры, чиновники и приезжие обыкновенно после жаркой, душной ночи купались в море и потом шли в павильон пить кофе или чай.</small>
</p>

Выделение полужирным

Используется для выделения важного текста

Следующие слова в предложении очень важные и требуют особого внимания со стороны читателя.

<strong>Это полужирный и очень важный текст</strong>

Выделение Курсивом

Используйте для выделения цитат и речи в тексте

Следующий текст был сказан очень давно: Никогда не воюйте с русскими. На каждую вашу военную хитрость они ответят непредсказуемой глупостью.

<em>Это чья-то речь</em>

Минуту внимания! Используйте тег <b> и <i> в стандарте HTML5. Тег <b> используйте для простого выделения текста, акцентируя на нем внимание, когда как тег <i> используется для выделения речи, технической информации и т.п.

Классы для выделения текста

Передайте дополнительное значение текста используя цветвовое решение.

Науки юношей питают

Отраду старым подают

В счастливой жизни украшают

В несчастный случай берегут

В домашних трудностях утеха

<p>Науки юношей питают</p>
<p>Отраду старым подают</p>
<p>В счастливой жизни украшают</p>
<p>В несчастный случай берегут</p>
<p>В домашних трудностях утеха</p>

Abbreviations

Stylized implemenation of HTML’s <abbr> element for abbreviations and acronyms to show the expanded version on hover. Abbreviations with a title attribute have a light dotted bottom border and a help cursor on hover, providing additional context on hover.

<abbr>

For expanded text on long hover of an abbreviation, include the title attribute.

An abbreviation of the word attribute is attr.

<abbr title="attribute">attr</abbr>

<abbr>

Add .initialism to an abbreviation for a slightly smaller font-size.

HTML is the best thing since sliced bread.

<abbr title="HyperText Markup Language">HTML</abbr>

Addresses

Present contact information for the nearest ancestor or the entire body of work.

<address>

Preserve formatting by ending all lines with <br>.

Twitter, Inc.
795 Folsom Ave, Suite 600
San Francisco, CA 94107
P: (123) 456-7890
Full Name
[email protected]
<address>
  <strong>Twitter, Inc.</strong><br>
  795 Folsom Ave, Suite 600<br>
  San Francisco, CA 94107<br>
  <abbr title="Phone">P:</abbr> (123) 456-7890
</address>

<address>
  <strong>Full Name</strong><br>
  <a href="mailto:#">[email protected]</a>
</address>

Blockquotes

For quoting blocks of content from another source within your document.

Default blockquote

Wrap <blockquote> around any HTML as the quote. For straight quotes we recommend a <p>.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

<blockquote>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
</blockquote>

Blockquote options

Style and content changes for simple variations on a standard blockquote.

Naming a source

Add <small> tag for identifying the source. Wrap the name of the source work in <cite>.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

Someone famous in Source Title
<blockquote>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
  <small>Someone famous <cite title="Source Title">Source Title</cite></small>
</blockquote>
Alternate displays

Use .pull-right for a floated, right-aligned blockquote.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

Someone famous in Source Title
<blockquote>
  ...
</blockquote>

Lists

Unordered

A list of items in which the order does not explicitly matter.

  • Lorem ipsum dolor sit amet
  • Consectetur adipiscing elit
  • Integer molestie lorem at massa
  • Facilisis in pretium nisl aliquet
  • Nulla volutpat aliquam velit
    • Phasellus iaculis neque
    • Purus sodales ultricies
    • Vestibulum laoreet porttitor sem
    • Ac tristique libero volutpat at
  • Faucibus porta lacus fringilla vel
  • Aenean sit amet erat nunc
  • Eget porttitor lorem
<ul>
  <li>...</li>
</ul>

Ordered

A list of items in which the order does explicitly matter.

  1. Lorem ipsum dolor sit amet
  2. Consectetur adipiscing elit
  3. Integer molestie lorem at massa
  4. Facilisis in pretium nisl aliquet
  5. Nulla volutpat aliquam velit
  6. Faucibus porta lacus fringilla vel
  7. Aenean sit amet erat nunc
  8. Eget porttitor lorem
<ol>
  <li>...</li>
</ol>

Unstyled

A list of items with no list-style or additional left padding.

  • Lorem ipsum dolor sit amet
  • Consectetur adipiscing elit
  • Integer molestie lorem at massa
  • Facilisis in pretium nisl aliquet
  • Nulla volutpat aliquam velit
    • Phasellus iaculis neque
    • Purus sodales ultricies
    • Vestibulum laoreet porttitor sem
    • Ac tristique libero volutpat at
  • Faucibus porta lacus fringilla vel
  • Aenean sit amet erat nunc
  • Eget porttitor lorem
<ul>
  <li>...</li>
</ul>

Description

A list of terms with their associated descriptions.

Description lists
A description list is perfect for defining terms.
Euismod
Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
Donec id elit non mi porta gravida at eget metus.
Malesuada porta
Etiam porta sem malesuada magna mollis euismod.
<dl>
  <dt>...</dt>
  <dd>...</dd>
</dl>
Horizontal description

Make terms and descriptions in <dl> line up side-by-side.

Description lists
A description list is perfect for defining terms.
Euismod
Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
Donec id elit non mi porta gravida at eget metus.
Malesuada porta
Etiam porta sem malesuada magna mollis euismod.
Felis euismod semper eget lacinia
Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
<dl>
  <dt>...</dt>
  <dd>...</dd>
</dl>

Heads up! Horizontal description lists will truncate terms that are too long to fit in the left column fix text-overflow. In narrower viewports, they will change to the default stacked layout.

Inline

Wrap inline snippets of code with <code>.

For example, <section> should be wrapped as inline.

For example, <code><section></code> should be wrapped as inline.

Basic block

Use <pre> for multiple lines of code. Be sure to escape any angle brackets in the code for proper rendering.

<p>Sample text here...</p>
<pre>
  &lt;p&gt;Sample text here...&lt;/p&gt;
</pre>

Heads up! Be sure to keep code within <pre> tags as close to the left as possible; it will render all tabs.

You may optionally add the .pre-scrollable class which will set a max-height of 350px and provide a y-axis scrollbar.

Default styles

For basic styling—light padding and only horizontal dividers—add the base class .table to any <table>.

#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larrythe Bird@twitter
<table>
  …
</table>

Optional classes

Add any of the follow classes to the .table base class.

.table-striped

Adds zebra-striping to any table row within the <tbody> via the :nth-child CSS selector (not available in IE7-IE8).

#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larrythe Bird@twitter
<table>
  …
</table>

.table-bordered

Add borders and rounded corners to the table.

#First NameLast NameUsername
1MarkOtto@mdo
MarkOtto@TwBootstrap
2JacobThornton@fat
3Larry the Bird@twitter
<table>
  …
</table>

.table-hover

Enable a hover state on table rows within a <tbody>.

#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larry the Bird@twitter
<table>
  …
</table>

.table-condensed

Makes tables more compact by cutting cell padding in half.

#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larry the Bird@twitter
<table>
  …
</table>

Optional row classes

Use contextual classes to color table rows.

ClassDescription
.successIndicates a successful or positive action.
.errorIndicates a dangerous or potentially negative action.
.warningIndicates a warning that might need attention.
.infoUsed as an alternative to the default styles.
#ProductPayment TakenStatus
1TB — Monthly01/04/2012Approved
2TB — Monthly02/04/2012Declined
3TB — Monthly03/04/2012Pending
4TB — Monthly04/04/2012Call in to confirm
...
  <tr>
    <td>1</td>
    <td>TB - Monthly</td>
    <td>01/04/2012</td>
    <td>Approved</td>
  </tr>
...

Supported table markup

List of supported table HTML elements and how they should be used.

TagDescription
<table> Wrapping element for displaying data in a tabular format
<thead> Container element for table header rows (<tr>) to label table columns
<tbody> Container element for table rows (<tr>) in the body of the table
<tr> Container element for a set of table cells (<td> or <th>) that appears on a single row
<td> Default table cell
<th> Special table cell for column (or row, depending on scope and placement) labels
Must be used within a <thead>
<caption> Description or summary of what the table holds, especially useful for screen readers
<table>
  <caption>...</caption>
  <thead>
    <tr>
      <th>...</th>
      <th>...</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>...</td>
      <td>...</td>
    </tr>
  </tbody>
</table>

Default styles

Individual form controls receive styling, but without any required base class on the <form> or large changes in markup. Results in stacked, left-aligned labels on top of form controls.

<form>
  <legend>Legend</legend>
  <label>Label name</label>
  <input type="text" placeholder="Type something…">
  <span>Example block-level help text here.</span>
  <label>
    <input type="checkbox"> Check me out
  </label>
  <button type="submit">Submit</button>
</form>

Optional layouts

Included with Bootstrap are three optional form layouts for common use cases.

Search form

Add .form-search to the form and .search-query to the <input> for an extra-rounded text input.

<form>
  <input type="text">
  <button type="submit">Search</button>
</form>

Inline form

Add .form-inline for left-aligned labels and inline-block controls for a compact layout.

<form>
  <input type="text" placeholder="Email">
  <input type="password" placeholder="Password">
  <label>
    <input type="checkbox"> Remember me
  </label>
  <button type="submit">Sign in</button>
</form>

Horizontal form

Right align labels and float them to the left to make them appear on the same line as controls. Requires the most markup changes from a default form:

  • Add .form-horizontal to the form
  • Wrap labels and controls in .control-group
  • Add .control-label to the label
  • Wrap any associated controls in .controls for proper alignment
<form>
  <div>
    <label for="inputEmail">Email</label>
    <div>
      <input type="text" placeholder="Email">
    </div>
  </div>
  <div>
    <label for="inputPassword">Password</label>
    <div>
      <input type="password" placeholder="Password">
    </div>
  </div>
  <div>
    <div>
      <label>
        <input type="checkbox"> Remember me
      </label>
      <button type="submit">Sign in</button>
    </div>
  </div>
</form>

Supported form controls

Examples of standard form controls supported in an example form layout.

Inputs

Most common form control, text-based input fields. Includes support for all HTML5 types: text, password, datetime, datetime-local, date, month, time, week, number, email, url, search, tel, and color.

Requires the use of a specified type at all times.

<input type="text" placeholder="Text input">

Textarea

Form control which supports multiple lines of text. Change rows attribute as necessary.

<textarea rows="3"></textarea>

Checkboxes and radios

Checkboxes are for selecting one or several options in a list while radios are for selecting one option from many.

Default (stacked)
<label>
  <input type="checkbox" value="">
  Option one is this and that—be sure to include why it's great
</label>

<label>
  <input type="radio" name="optionsRadios" value="option1" checked>
  Option one is this and that—be sure to include why it's great
</label>
<label>
  <input type="radio" name="optionsRadios" value="option2">
  Option two can be something else and selecting it will deselect option one
</label>
Inline checkboxes

Add the .inline class to a series of checkboxes or radios for controls appear on the same line.

<label>
  <input type="checkbox" value="option1"> 1
</label>
<label>
  <input type="checkbox" value="option2"> 2
</label>
<label>
  <input type="checkbox" value="option3"> 3
</label>

Selects

Use the default option or specify a multiple="multiple" to show multiple options at once.

<select>
  <option>1</option>
  <option>2</option>
  <option>3</option>
  <option>4</option>
  <option>5</option>
</select>

<select multiple="multiple">
  <option>1</option>
  <option>2</option>
  <option>3</option>
  <option>4</option>
  <option>5</option>
</select>

Extending form controls

Adding on top of existing browser controls, Bootstrap includes other useful form components.

Prepended and appended inputs

Add text or buttons before or after any text-based input. Do note that select elements are not supported here.

Default options

Wrap an .add-on and an input with one of two classes to prepend or append text to an input.

<div>
  <span>@</span><input size="16" type="text" placeholder="Username">
</div>
<div>
  <input size="16" type="text"><span>.00</span>
</div>
Combined

Use both classes and two instances of .add-on to prepend and append an input.

<div>
  <span>$</span><input size="16" type="text"><span>.00</span>
</div>
Buttons instead of text

Instead of a <span> with text, use a .btn to attach a button (or two) to an input.

<div>
  <input size="16" type="text"><button type="button">Go!</button>
</div>

<div>
  <input size="16" type="text"><button type="button">Search</button><button type="button">Options</button>
</div>
Search form
<form>
  <div>
    <input type="text">
    <button type="submit">Search</button>
  </div>
  <div>
    <button type="submit">Search</button>
    <input type="text">
  </div>
</form>

Control sizing

Use relative sizing classes like .input-large or match your inputs to the grid column sizes using .span* classes.

Relative sizing
<input type="text" placeholder=".input-mini">
<input type="text" placeholder=".input-small">
<input type="text" placeholder=".input-medium">
<input type="text" placeholder=".input-large">
<input type="text" placeholder=".input-xlarge">
<input type="text" placeholder=".input-xxlarge">

Heads up! In future versions, we’ll be altering the use of these relative input classes to match our button sizes. For example, .input-large will increase the padding and font-size of an input.

Grid sizing

Use .span1 to .span12 for inputs that match the same sizes of the grid columns.

<input type="text" placeholder=".span1">
<input type="text" placeholder=".span2">
<input type="text" placeholder=".span3">
<select>
  ...
</select>
<select>
  ...
</select>
<select>
  ...
</select>

For multiple grid inputs per line, use the .controls-row modifier class for proper spacing. It floats the inputs to collapse white-space, sets the proper margins, and the clears the float.

<div>
  <input type="text" placeholder=".span5">
</div>
<div>
  <input type="text" placeholder=".span4">
  <input type="text" placeholder=".span1">
</div>
...

Uneditable inputs

Present data in a form that’s not editable without using actual form markup.

<span>Some value here</span>

Form actions

End a form with a group of actions (buttons). When placed within a .form-horizontal, the buttons will automatically indent to line up with the form controls.

<div>
  <button type="submit">Save changes</button>
  <button type="button">Cancel</button>
</div>

Help text

Inline and block level support for help text that appears around form controls.

Inline help
<input type="text"><span>Inline help text</span>
Block help
<input type="text"><span>A longer block of help text that breaks onto a new line and may extend beyond one line.</span>

Form control states

Provide feedback to users or visitors with basic feedback states on form controls and labels.

Input focus

We remove the default outline styles on some form controls and apply a box-shadow in its place for :focus.

<input type="text" value="This is focused...">

Disabled inputs

Add the disabled attribute on an input to prevent user input and trigger a slightly different look.

<input type="text" placeholder="Disabled input here..." disabled>

Validation states

Bootstrap includes validation styles for error, warning, info, and success messages. To use, add the appropriate class to the surrounding .control-group.

<div>
  <label for="inputWarning">Input with warning</label>
  <div>
    <input type="text">
    <span>Something may have gone wrong</span>
  </div>
</div>
<div>
  <label for="inputError">Input with error</label>
  <div>
    <input type="text">
    <span>Please correct the error</span>
  </div>
</div>
<div>
  <label for="inputSuccess">Input with success</label>
  <div>
    <input type="text">
    <span>Woohoo!</span>
  </div>
</div>

Default buttons

Button styles can be applied to anything with the .btn class applied. However, typically you’ll want to apply these to only <a> and <button> elements for the best rendering.

Buttonclass=»»Description
DefaultbtnStandard gray button with gradient
Primarybtn btn-primaryProvides extra visual weight and identifies the primary action in a set of buttons
Infobtn btn-infoUsed as an alternative to the default styles
Successbtn btn-successIndicates a successful or positive action
Warningbtn btn-warningIndicates caution should be taken with this action
Dangerbtn btn-dangerIndicates a dangerous or potentially negative action
Inversebtn btn-inverseAlternate dark gray button, not tied to a semantic action or use
Linkbtn btn-linkDeemphasize a button by making it look like a link while maintaining button behavior
Cross browser compatibility

IE9 doesn’t crop background gradients on rounded corners, so we remove it. Related, IE9 jankifies disabled button elements, rendering text gray with a nasty text-shadow that we cannot fix.

Button sizes

Fancy larger or smaller buttons? Add .btn-large, .btn-small, or .btn-mini for additional sizes.

Large button Large button

Default button Default button

Small button Small button

Mini button Mini button

<p>
  <button type="button">Large button</button>
  <button type="button">Large button</button>
</p>
<p>
  <button type="button">Default button</button>
  <button type="button">Default button</button>
</p>
<p>
  <button type="button">Small button</button>
  <button type="button">Small button</button>
</p>
<p>
  <button type="button">Mini button</button>
  <button type="button">Mini button</button>
</p>

Create block level buttons—those that span the full width of a parent— by adding .btn-block.

Block level button Block level button

<button type="button">Block level button</button>
<button type="button">Block level button</button>

Disabled state

Make buttons look unclickable by fading them back 50%.

Anchor element

Add the .disabled class to <a> buttons.

Primary link Link

<a href="#">Primary link</a>
<a href="#">Link</a>

Heads up! We use .disabled as a utility class here, similar to the common .active class, so no prefix is required. Also, this class is only for aesthetic; you must use custom JavaScript to disable links here.

Button element

Add the disabled attribute to <button> buttons.

Primary button Button

<button type="button" disabled="disabled">Primary button</button>
<button type="button" disabled>Button</button>

One class, multiple tags

Use the .btn class on an <a>, <button>, or <input> element.

<a href="">Link</a>
<button type="submit">Button</button>
<input type="button" value="Input">
<input type="submit" value="Submit">

As a best practice, try to match the element for your context to ensure matching cross-browser rendering. If you have an input, use an <input type="submit"> for your button.

Add classes to an <img> element to easily style images in any project.

<img src="...">
<img src="...">
<img src="...">

Heads up! .img-rounded and .img-circle do not work in IE7-8 due to lack of border-radius support.

Icon glyphs

140 icons in sprite form, available in dark gray (default) and white, provided by Glyphicons.

  • icon-glass
  • icon-music
  • icon-search
  • icon-envelope
  • icon-heart
  • icon-star
  • icon-star-empty
  • icon-user
  • icon-film
  • icon-th-large
  • icon-th
  • icon-th-list
  • icon-ok
  • icon-remove
  • icon-zoom-in
  • icon-zoom-out
  • icon-off
  • icon-signal
  • icon-cog
  • icon-trash
  • icon-home
  • icon-file
  • icon-time
  • icon-road
  • icon-download-alt
  • icon-download
  • icon-upload
  • icon-inbox
  • icon-play-circle
  • icon-repeat
  • icon-refresh
  • icon-list-alt
  • icon-lock
  • icon-flag
  • icon-headphones
  • icon-volume-off
  • icon-volume-down
  • icon-volume-up
  • icon-qrcode
  • icon-barcode
  • icon-tag
  • icon-tags
  • icon-book
  • icon-bookmark
  • icon-print
  • icon-camera
  • icon-font
  • icon-bold
  • icon-italic
  • icon-text-height
  • icon-text-width
  • icon-align-left
  • icon-align-center
  • icon-align-right
  • icon-align-justify
  • icon-list
  • icon-indent-left
  • icon-indent-right
  • icon-facetime-video
  • icon-picture
  • icon-pencil
  • icon-map-marker
  • icon-adjust
  • icon-tint
  • icon-edit
  • icon-share
  • icon-check
  • icon-move
  • icon-step-backward
  • icon-fast-backward
  • icon-backward
  • icon-play
  • icon-pause
  • icon-stop
  • icon-forward
  • icon-fast-forward
  • icon-step-forward
  • icon-eject
  • icon-chevron-left
  • icon-chevron-right
  • icon-plus-sign
  • icon-minus-sign
  • icon-remove-sign
  • icon-ok-sign
  • icon-question-sign
  • icon-info-sign
  • icon-screenshot
  • icon-remove-circle
  • icon-ok-circle
  • icon-ban-circle
  • icon-arrow-left
  • icon-arrow-right
  • icon-arrow-up
  • icon-arrow-down
  • icon-share-alt
  • icon-resize-full
  • icon-resize-small
  • icon-plus
  • icon-minus
  • icon-asterisk
  • icon-exclamation-sign
  • icon-gift
  • icon-leaf
  • icon-fire
  • icon-eye-open
  • icon-eye-close
  • icon-warning-sign
  • icon-plane
  • icon-calendar
  • icon-random
  • icon-comment
  • icon-magnet
  • icon-chevron-up
  • icon-chevron-down
  • icon-retweet
  • icon-shopping-cart
  • icon-folder-close
  • icon-folder-open
  • icon-resize-vertical
  • icon-resize-horizontal
  • icon-hdd
  • icon-bullhorn
  • icon-bell
  • icon-certificate
  • icon-thumbs-up
  • icon-thumbs-down
  • icon-hand-right
  • icon-hand-left
  • icon-hand-up
  • icon-hand-down
  • icon-circle-arrow-right
  • icon-circle-arrow-left
  • icon-circle-arrow-up
  • icon-circle-arrow-down
  • icon-globe
  • icon-wrench
  • icon-tasks
  • icon-filter
  • icon-briefcase
  • icon-fullscreen

Glyphicons attribution

Glyphicons Halflings are normally not available for free, but an arrangement between Bootstrap and the Glyphicons creators have made this possible at no cost to you as developers. As a thank you, we ask you to include an optional link back to Glyphicons whenever practical.


How to use

All icons require an <i> tag with a unique class, prefixed with icon-. To use, place the following code just about anywhere:

<i></i>

There are also styles available for inverted (white) icons, made ready with one extra class. We will specifically enforce this class on hover and active states for nav and dropdown links.

<i></i>

Heads up! When using beside strings of text, as in buttons or nav links, be sure to leave a space after the <i> tag for proper spacing.


Icon examples

Use them in buttons, button groups for a toolbar, navigation, or prepended form inputs.

Buttons
Button group in a button toolbar
<div>
  <div>

    <a href="#"><i></i></a>
    <a href="#"><i></i></a>
    <a href="#"><i></i></a>
    <a href="#"><i></i></a>
  </div>
</div>
Dropdown in a button group
<div>
  <a href="#"><i></i> User</a>
  <a data-toggle="dropdown" href="#"><span></span></a>
  <ul>
    <li><a href="#"><i></i> Edit</a></li>
    <li><a href="#"><i></i> Delete</a></li>
    <li><a href="#"><i></i> Ban</a></li>
    <li></li>
    <li><a href="#"><i></i> Make admin</a></li>
  </ul>
</div>
Small button
<a href="#"><i></i></a>
Navigation
<ul>
  <li><a href="#"><i></i> Home</a></li>
  <li><a href="#"><i></i> Library</a></li>
  <li><a href="#"><i></i> Applications</a></li>
  <li><a href="#"><i></i> Misc</a></li>
</ul>
Form fields
<div>
  <label for="inputIcon">Email address</label>
  <div>
    <div>
      <span><i></i></span>
      <input type="text">
    </div>
  </div>
</div>

Простые правила разметки • Как писать классы по БЭМ?

Простой пример: Блок + Элемент #

Допустим, у вас есть блок с заголовком, текстом и кнопкой внутри, например, это всплывающее окно — попап. Разметка:

<div>
  <h4>Заголовок</h4>
  <div>Текст</div>
  <button>Кнопка</button>
</div>

Добавляем класс содержащий назначение элемента: .popup:

<div>
  <h4>Заголовок</h4>
  <div>Текст</div>
  <button>Кнопка</button>
</div>

Теперь попробуем добавить классы вложенным элементам:

<div>
  <h4>Заголовок</h4>
  <div>Текст</div>
  <button>Кнопка</button>
</div>

Классы удобные, но не уникальные. Если на странице будут ещё элементы с классами .title и .text, их стили могут затронуть элементы в попапе. Селектор типа .popup .title может в будущем создать проблемы со специфичностью. Можно придумать другие классы, но чем больше похожих по смыслу элементов, тем сложнее придумывать новые классы.

А теперь применим БЭМ-нотацию: каждому элементу внутри блока добавим префикс с классом родителя, например, для заголовка это будет popup__title:

<div>
  <h4>Заголовок</h4>
  <div>Текст</div>
  <button>Кнопка</button>
</div>

Теперь эти классы легко решают сразу две задачи: во-первых, благодаря уникальным классам стили для них никогда не пересекутся с другими подобными элементами на странице, а во-вторых, по таким классам сразу видно, что это элементы блока .popup.

Пример посложнее: Блок + Элемент + Модификатор #

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

<div>
  <h4>Заголовок сообщения</h4>
  <div>Текст сообщения</div>
</div>

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

<div>
  <h4>Заголовок сообщения</h4>
  <div>Текст сообщения</div>
</div>

<div>
  <h4>Заголовок сообщения</h4>
  <div>Текст сообщения</div>
</div>

Обоим элементам можно добавить одинаковые стили используя общий класс .message и так же легко можно добавить отдельные стили для каждого из них, используя уникальный класс с модификатором:

.message {
  border: 1px solid gray;
}
  .message--success {
    border-color: green;
  }

  .message--error {
    border-color: red;
  }

Оба сообщения будут иметь рамку толщиной один пиксель, но для сообщения об успешной операции она будет зелёной, а для сообщения об ошибке — красной.

Ещё сложнее: что делать, если хочется сделать элемент элемента? #

Например, на странице есть блок новостей:

<div>
    <h4>Новости</h4>

    <ul>
      <li><!-- новость --></li>
      <li><!-- новость --></li>
    </ul>
</div>

Заголовок блока логично получает класс .news__title, список — .news__list, а отдельная новость — .news__item:

<div>
    <h4>Новости</h4>

    <ul>
      <li><!-- новость --></li>
      <li><!-- новость --></li>
    </ul>
</div>

Тут никаких проблем возникнуть не должно. Теперь добавим разметку отдельной новости:

<div>
    <h4>Новости</h4>

    <ul>
      <li>
        <h5>Заголовок новости</h5>
        <p>Текст новости</p>
      </li>
      <li><!-- новость --></li>
    </ul>
</div>

Нам нужно добавить класс заголовку новости. Первым делом приходит в голову .news__title, но такой класс уже занят. Предположим, что второй элемент будет не .title, а .subject, тогда в CSS получается такое:

.news__title { ... }
.news__subject { ... }

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

Следующий вариант — .news__item__title, но в БЭМ нельзя создавать элемент элемента, и это понятно, потому что получается каша. Ещё вариант: .news__item-title — тоже не годится, потому что может быть неочевидным как title соотносится с item. Как же быть?

Решение простое: на уровне элемента .news__item можно объявить новый блок (например, .news-item), и строить вложенные классы уже от него. Да, это не самостоятельный переиспользуемый блок, здесь объявление блока нужно только для того, чтобы разгрузить селекторы. Что получается:

<div>
    <h4>Новости</h4>

    <ul>
      <li>
        <h5>Заголовок новости</h5>
        <p>Текст новости</p>
      </li>
      <li><!-- новость --></li>
    </ul>
</div>

Проблема решена: нам больше не нужно использовать монструозные классы, при этом класс точно описывает элемент, и в CSS будет сразу понятно какой класс за что отвечает:

.news__title { ... }
.news-item__title { ... }

Простой и удобный выход из неудобной ситуации.

Способы интеграции CSS в HTML

Введение 

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

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

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

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


Способ 1. Внутренние стили

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

<p>Hello My World! p>

<br/>

<p>Первый простой пример p>

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

Способ 2. Таблицы глобальных стилей – в заглавии самого документа.

При таком варианте использования стили определяются непосредственно в веб-документе и определяются между тегами <head>…</head> веб-страницы внутри тега <style>, можно смело сказать, что этот способ намного превосходит предыдущий в гибкости и по своим возможностям, кроме того он упрощает работу с большим числом стилей на странице.

Видео курсы по схожей тематике:

<head>

    <style>

        p {

        font-family: ‘Segoe UI’;

        font-size: 35px;

        color: #43e936;

        }

   style>

head>

<body>

    <p>Второй простой пример p>

    <div>

        <p>Второй простой пример, повтор р>

    div>

body>

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

Способ 3. Таблицы связанных стилей – задаем в отдельном файле.

Пожалуй, один из самых мощных и удобных способов использования стилей и правил отображения элементов для многостраничного сайта. При нем стили, предопределённые разработчиком, размещаются в отдельном файле с произвольным названием example.css, который можно использовать для любой веб-страницы на сайте. Для того чтобы подключить этот файл на странице, необходимо в заголовке страницы (в пределах тега <head>…</head>) использовать тег <link>.

<head>

    <title>CSS </title>

    <link href=»example.css» rel=»stylesheet» type=»text/css» />

head>

<body>

    <pre>Hello World pre>

    <br/>

    <p>Третий простой пример p>

body>

Бесплатные вебинары по схожей тематике:

Содержимое файла example.css:

p {

    font-size: 37px;

    color: #ff0000;

}

CSS-оформление текста

Пример <стиль> h2 { шрифт: 100 11vw без засечек; цвет: горячий розовый; текст-оформление: надстрочный; }

Пример наложения

Свойство text-decoration является сокращенным свойством для установки text-decoration-line , text-decoration-style и text-decoration-color в одном объявлении.

При использовании сокращенного свойства text-decoration пропущенным значениям присваиваются их начальные значения.

Синтаксис

текст-украшение: || ||

Возможные значения

текст-украшение-строка
Указывает, какие линейные украшения, если они есть, добавляются к элементу. Допустимы следующие значения:
нет
Не производит и не запрещает оформление текста.
подчеркнуть
Каждая строка текста подчеркнута.
дополнительный
Каждая строка текста имеет над ней черту.
сквозной
Каждая строка текста проходит через линию посередине.
мигает
Текст мигает (чередуется между видимым и невидимым). Обратите внимание, что это значение не рекомендуется в пользу анимации CSS.
стиль оформления текста
Стиль оформления текста.
цельный
Сплошная линия.
волнистый
Волнистая линия.
пунктир
Пунктирная линия.
штриховая
Строка, состоящая из тире.
двойной
Двойная сплошная линия.
текст-украшение-цвет
Цвет оформления текста. Может быть любым допустимым цветом .

Кроме того, все свойства CSS также принимают следующие значения ключевых слов всего CSS в качестве единственного компонента значения своего свойства:

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

Основная информация об имуществе

Начальное значение
Текущий цвет
Относится к
Все элементы
Унаследовано?
Нет
Медиа
Визуальный
Анимационный
Да, но только как цвет (т.е. можно анимировать только свойство text-decoration-color сокращения). (см. пример)

Пример кода

Базовый CSS

Вот пример базовой декларации. Объявление состоит из свойства и его значений для различных полных свойств.

оформление текста: оранжевая пунктирная линия подчеркивания;

Любые пропущенные значения устанавливаются на свои начальные значения. Таким образом, справедливо и следующее.

текст-оформление: подчеркивание;

Фактически, это единственный синтаксис, распознаваемый CSS1 и CSS2 (поскольку они не поддерживают длинные свойства).

Итак, вы можете использовать следующий код для предоставления функций CSS3, при этом обеспечивая обратную совместимость для браузеров CSS1 и CSS2:

:ссылка на сайт { оранжевый цвет; текст-оформление: подчеркивание; / * Используется браузерами CSS1 и CSS2 * / оформление текста: подчеркнутый зеленый пунктир; / * Используется браузерами CSS3 * / }

В браузерах CSS1 и CSS2 текст ссылки и ее подчеркивание будут оранжевыми. Его подчеркивание будет сплошным (это единственный вариант до CSS3).

В браузерах CSS3 текст ссылки будет оранжевым, а подчеркивание — зеленым. Его подчеркивание также будет пунктирным.

Рабочий пример в HTML-документе

Пример <стиль> h2 { шрифт: 100 3em без засечек; цвет: золото; текст-оформление: оверлейный волнистый желто-зеленый; }

Пример наложения

Попробуй

Официальные спецификации

Поддержка браузера

Следующая таблица предоставлена ​​Caniuse.com показывает уровень поддержки этой функции браузером.

CSS свойство оформления текста

В этой главе вы узнаете:

О свойстве выравнивания текста
Значения этого объекта недвижимости
Пример этой собственности

Свойство CSS text-decoration используется для указания оформления текста элемента. Вы можете украсить текст подчеркиванием, надчеркиванием и т. Д.

Стоимость объекта —
Значения Описание
нет Это значение по умолчанию для text-decoration, которое используется для отображения обычного текста
дополнительный Используется для рисования линии поверх текста
подчеркивание Используется для рисования линии под текстом
сквозной Используется для выделения строки текста
начальный Используется для указания значения свойства по умолчанию
наследовать наследовать свойство от родительского элемента

Пример этого свойства
 

     Пример свойства text-decoration 
    
    

Простой абзац

Это пример оформления текста: подчеркивание

Это пример оформления текста: overline

Это пример оформления текста: сквозное

Руководство: —

Когда вы запустите данную программу, вы увидите, что содержание абзаца оформлено иначе.

Выход: —
РЕЗЮМЕ

В этой главе вы узнали о свойстве CSS text-decoration, так что теперь вы можете использовать это свойство в своей программе, чтобы сделать веб-страницу привлекательной. Нажмите кнопку «Далее», чтобы продолжить обучение —

Свойство оформления текста CSS

— server2client.com

Определение

Свойство CSS text-decoration позволяет нам украшать текст.

Применимо к

Все элементы.

Значения свойств

мигание — определяет мигающий текст.

inherit — текст наследует оформление своего родительского селектора.

сквозная линия — текст будет иметь линию, проведенную через центр.

нет — определяет обычный текст без оформления (по умолчанию).

overline — над текстом будет нарисована линия.

подчеркивание — Под текстом будет нарисована линия.

Значение по умолчанию

По умолчанию установлено значение none, что не приводит к оформлению текста.

Наследование

Свойство оформления текста НЕ наследуется от родительского элемента.

Аномалии браузера

IE5, IE6 и IE7 не поддерживают значение наследуемого свойства.
IE8 делает с допустимым! DOCTYPE.
IE9 + поддерживает значение наследуемого свойства.

Chrome, Internet Explorer и Safari не распознают значение свойства blink.

Пример

 





 Справочник по CSS - Свойство CSS text-decoration 



   



 

Все заголовки h2 будут подчеркнуты

Использование мигания может сильно отвлекать и раздражать пользователей.

Все заголовки h3 будут перекрыты

Использование мигания может сильно отвлекать и раздражать пользователей.

Весь текст h4 будет иметь линию через середину

Использование мигания может сильно отвлекать и раздражать пользователей.

Это птица? Это самолет? Нет! Ссылка без украшения

Как это выглядит

Результаты использования свойства text-decoration со значениями выше будут выглядеть примерно так:

Домашняя страница Топ

pdfmake

Навигация: Начиная — На стороне клиента — Методы — Поддерживаемые браузеры — Примеры — На стороне сервера — поддерживаемый узел.js версии — Примеры Шрифты — Пользовательские шрифты (на стороне клиента) — через виртуальную файловую систему (VFS) — Создание файла шрифта с помощью сценария PHP — Создание файла шрифта с помощью сценария оболочки — по протоколу URL — Иконки — Стандартные 14 шрифтов Документ-определение-объект- Стиль- Столбцы- Таблицы- Списки- Верхние и нижние колонтитулы- Фоновый слой- Поля- Стек абзацев- Изображения- SVG- Ссылки- QR-код- Оглавление- Водяной знак- Размеры, ориентация и поля страницы- Метаданные документа — Шаблоны — Сжатие — Шифрование и права доступа Опции

pdfmake позволяет стилизовать любой абзац или его часть:

  var docDefinition = {
  содержание: [
    // если вам не нужны стили, вы можете использовать простую строку для определения абзаца
    'Это стандартный абзац со стилем по умолчанию',

    // используя {текст: '... '} позволяет вам устанавливать свойства стиля
    {text: 'Этот абзац будет иметь более крупный шрифт', fontSize: 15},

    // если вы установите значение текста в массив вместо строки, вы сможете
    // индивидуальный стиль любой части
    {
      текст: [
        'Этот абзац определяется как массив элементов, позволяющих сделать это возможным',
        {text: 'изменить стиль части и увеличить ее', fontSize: 15},
        чем остальные.
      ]
    }
  ]
};
  
Словари стилей

Также можно определить словарь многоразовых стилей:

  var docDefinition = {
  содержание: [
    {текст: 'Это заголовок', стиль: 'заголовок'},
    "Никакого стиля, это стандартный абзац",
    {text: 'Другой текст', style: 'anotherStyle'},
    {text: 'Применено несколько стилей', style: ['header', 'anotherStyle']}
  ],

  стили: {
    header: {
      fontSize: 22,
      жирный: правда
    },
    anotherStyle: {
      курсив: правда,
      выравнивание: 'право'
    }
  }
};
  

Для более глубокого понимания стилей в pdfmake, наследования стилей и локального переопределения стилей просмотрите примеры STYLES1, STYLES2 и STYLES3 на игровой площадке.

Стиль по умолчанию

Также можно определить стиль по умолчанию:

  var docDefinition = {
  содержание: [
    "Стиль текста по умолчанию"
  ],

  defaultStyle: {
    fontSize: 15,
    жирный: правда
  }
};
  
Свойства стиля
  • шрифт: строка : название шрифта
  • fontSize: number : размер шрифта в pt
  • fontFeatures: string [] : массив расширенных типографских функций, поддерживаемых в шрифтах TTF (поддерживаемые функции зависят от файла шрифта)
  • lineHeight: число : высота строки (по умолчанию: 1)
  • полужирный: логический : использовать ли полужирный текст (по умолчанию: false)
  • курсив: логический : использовать ли курсивный текст (по умолчанию: false)
  • выравнивание: строка : («влево» или «по центру», «вправо» или «по ширине») выравнивание текста
  • символов Расстояние: число : размер межбуквенного интервала в pt
  • цвет: строка : цвет текста (название цвета e.g., «синий» или шестнадцатеричный цвет, например, «# ff5500»)
  • фон: строка цвет фона текста
  • markerColor: string : цвет маркеров в маркированном списке
  • украшение: строка : текстовое оформление, которое нужно применить («подчеркивание», «сквозная линия» или «наложение»)
  • decorationStyle: string : стиль оформления текста («пунктирная», «пунктирная», «двойная» или «волнистая»)
  • decorationColor: string : цвет оформления текста, см. Цвет

10 бесплатных заголовков HTML и CSS фрагментов

Заголовок

— одна из самых важных частей любого веб-сайта, потому что часто именно его посетители видят первыми, когда попадают на ваш сайт.Чтобы не пропустить концепцию и дизайн этой важной входной двери, вот 10 отличных примеров заголовка.

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

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

Поэтому я отобрал для вас 10 лучших примеров шапки для вашего сайта . Все эти примеры имеют открытый доступ и созданы с помощью Bootstrap, который является наиболее часто используемым фреймворком в мире. Наслаждаться!

1. Bootstrap Прозрачная панель навигации

Комбинируя Bootstrap 4 и Javascript, можно легко создать элегантную прозрачную панель навигации, которая станет непрозрачной при прокрутке на рабочем столе.

Он простой, чистый, эффективный и отлично выполняет работу .

2. Фоновое изображение начальной загрузки

Технически здесь очень интересен подход, заключающийся в создании контейнера с высотой, равной 100% окна, благодаря min-height: 100vh .

Затем мы используем .bg-cover , чтобы фон поместился во все окна. Это очень хорошо сделано, и рендеринг очень приятный на любом экране. Молодец!

3.Bootstrap Mega Menu

Здесь мегаменю управляется раскрывающимся списком, собственным свойством Bootstrap 4. Затем мы создаем класс CSS, чтобы это мегаменю было на месте. статический , а не абсолютный .

Опять же, это очень просто, очень умно и очень легко повторно использовать на вашем веб-сайте.

4. Статический заголовок Boostrap

Мы используем изобретательную технику, описанную в первом примере, для отображения фонового изображения, к которому мы применяем классы CSS jumbotron bg-cover .

В результате получается очень чистый и эффективный статический заголовок.

5. Слайдер заголовка начальной загрузки

В этом примере ползунок управляется непосредственно фреймворком благодаря карусели класса CSS . Поэтому осталось добавить еще несколько строк CSS для улучшения отображения.

6. Bootstrap Video Embed

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

7. Бутстрап прозрачный Jumbotron

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

8. Карусель журнала Bootstrap

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

9. Анимированный заголовок начальной загрузки

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

10. Видео заголовка начальной загрузки

Видео в фоновом режиме всегда приятно смотреть и отображать благодаря тегу HTML video .Для простоты все управляется фреймворком без использования JavaScript.

Заключение

Я надеюсь, что эти 10 примеров заголовков убедили вас, что вы без колебаний воспользуетесь теми, которые вас больше всего вдохновляют, и что вы поделитесь этой статьей вокруг себя. Опять же, это всего лишь примеры того, что можно создать с некоторыми навыками и творчеством. Что вы думаете? Какой из них вы предпочитаете? У вас есть другие примеры, которыми можно поделиться? Жду ваших комментариев!

Passionné par le Web depuis 2007, Daniel defend la veuve et l'orphelin du web, созданный на сайтах, уважаемых W3C.Fort d'une expérience de plusieurs années, il partage ses connaissances dans un état d'esprit open source.
Très impliqué dans la communauté Joomla depuis 2014, il est actif au sein de plusieurs projets, conférencier et fondateur du JUG Breizh.


Стиль гиперссылок CSS - Как изменить цвет гиперссылки

CSS Hyperlinks Style работает при наведении курсора или нажатии на определенную гиперссылку. вы можете установить стили гиперссылок, используя различные свойства CSS, такие как background-color, font-family, font-weight, color, font-size и многое другое.

Вы также можете установить специальные стили в зависимости от выполнения особого события по гиперссылке.

Ниже приведены специальные события гиперссылки для применения стиля CSS, когда это происходит.

  • a: ссылка Обычная непосещаемая ссылка
  • a: посещено Ссылка уже посещена пользователем
  • a: hover Когда пользователь наводит указатель мыши на ссылку
  • a: active Перешли по ссылке в тот момент

Здесь применяются некоторые правила, когда вы устанавливаете стиль для гиперссылки.

  • a: hover всегда следует после ссылки: или после: visit
  • a: активные всегда идут после a: hover

Следующее свойство CSS гиперссылки «Стиль» - это список различных стилей типа.

Пример

  


   Гиперссылка CSS 
  


  
Щелкните здесь, чтобы открыть пример CSS страницы.

Запустите ... »

Цвет фона ссылок CSS

Здесь гиперссылка устанавливает цвет фона на: ссылка,: посетил,: наведен,: активен.

Пример

  


   Цвет фона для гиперссылки CSS 
  


  
Щелкните здесь, чтобы открыть пример CSS страницы.

Запустите ... »

Оформление текста CSS

Здесь гиперссылка устанавливает цвет фона на: ссылка,: посетил,: наведен,: активен.

Пример

  


   Гиперссылка CSS 
  


  
Щелкните здесь, чтобы открыть пример CSS страницы.

Запустите ... »

Как создать дизайн заголовка CSS? 5 примеров говорят вам

Важность

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

Дизайн CSS-заголовка - движущая сила веб-сайта, которая побуждает других зрителей изучить страницу. А с появлением последней версии CSS 3 возможность писать в HTML5 полностью изменила структуру веб-дизайна.

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

Создание дизайна заголовка без CSS и HTML

Wondershare Mockitt - это интерактивный веб-инструмент для разработки продуктов, приложений и веб-сайтов. Не только заголовок, но и вы можете создать полноценный дизайн веб-сайта и приложения с предварительным просмотром в реальном времени и ссылками на страницы. Mockitt избавляет от необходимости часами набирать код в CSS, а затем проводить A / B-тестирование для выявления задержек.

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

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

Почему Mockitt лучше, чем создание дизайна заголовков в HTML CSS?

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

  • Добавьте несколько пунктов меню при связывании с выделенной страницей и просмотрите переход с одной страницы на другую.
  • Mockitt дополнен несколькими анимациями, которые также можно встроить в меню, изображения или кнопку CTA для крутого и интерактивного дизайна.
  • Проектирование на основе векторов позволяет изменять размеры с префиксом для создания пользовательских форм, которые обеспечивают плотно прилегающий дизайн.
  • Создайте несколько эффектов с изображениями и получите точные размеры и размеры всех элементов.

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


Что такое CSS / HTML и как создать дизайн заголовка с помощью CSS и HTML?

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

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

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

Чтобы создать дизайн заголовка в коде HTML и CSS, следуйте процедуре, описанной ниже:

Другой простой пример создания HTML-тегов для дизайна заголовка CSS приведен ниже:

Ну, это всего лишь один аспект дизайна заголовка в HTML CSS. Если вы хотите получить очень сложный дизайн, придется много писать. Следовательно, предпочтительнее использовать онлайн-инструмент перетаскивания, такой как Mockitt. Он чистый, простой в использовании и экономит время.


5 вдохновляющих примеров создания дизайна заголовков в коде HTML и CSS

# 1: Зигги

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

В углу страницы есть опция панели поиска, а внизу находится корзина покупок. Затем с помощью скользящих элементов @keyframes изображения вращаются в цикле. Каждое изображение перемещается по истечении определенного времени и может содержать различное содержимое, добавляемое с помощью тега HTML.

# 2: Орангина

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

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

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

# 3: Цена чернил

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

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

Наконец, CTA вместо этого выполняется путем выбора класса в HTML (div или button) и последующего добавления кода CSS к кнопке для перенаправления пользователя на выделенную страницу.

# 4: WorldInMyLens

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

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

# 5: RunRunit

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

Это один из лучших дизайнов заголовков HTML из-за его простоты, быстрого призыва к действию, простого статического изображения, созданного на заказ, и двух опций (Логин и Смена языка).

Сводка

Любой дизайн заголовка CSS - это не что иное, как то, что вы можете создать с помощью любого другого онлайн-инструмента или PHP. Но проблема с CSS, HTML и PHP - это кодирование.Это ограничивает круг возможностей и ограничивает вас фантазией и профессиональными знаниями разработчика и дизайнера. По сути, вы будете во власти того, кто умеет программировать.

Вот почему такие инструменты, как Mockitt, произвели революцию в индустрии веб-дизайна. Mocking - это интеллектуальный, быстрый, универсальный инструмент, специфичный для каждой функции и платформы, которые нужны пользователю.

Автор записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *