Плитковий шаблон статей із сайту SitePoint: компоненти, тема і Flexbox

306

Від автора: я довгий час писав статті для сайту SitePoint, і мені дуже подобається їх шаблон у вигляді плиток з дизайнерської точки зору. Плитка містить всю необхідну інформацію про статті: заголовок, автор, дата, категорія і навіть кількість лайків та коментарів.

Мені прийшло в голову, що було б цікаво створити такий компонент як з точки зору HTML, так і CSS. У цій статті ми створимо плитковий шаблон і пройдемося по кожному етапу, постараємося зробити його якомога краще зі сторони доступності, обслуговування, стилізації та SEO продуктивності.

Почнемо з вмісту

Компонент майже завжди повинен створюватися в наступному порядку: контент, розмітка, стилі і в кінці JS (якщо потрібен). Не будемо відходити від цього правила і почнемо з контенту.

HTML & CSS
8 comments
A Tale of CSS and Precision Sass
by Hugo Giraudel
May 12, 2016

Тепер можна загортати наш контент в HTML. В якості головного контейнера виступить тег article, він тут ідеально підходить. Всередині у нас буде контейнер для верхньої частини, контейнер для заголовка (хоча він і необов’язковий) і футер з метаданими.

HTML & CSS
8 comments
A Tale of CSS and Precision Sass

by Hugo Giraudel
May 12, 2016

Зверніть увагу: ми використовуємо BEM систему оголошень з просторами імен для іменування класів. Ви ж можете використовувати, що вам більше подобається. Тепер нам потрібні додаткові контейнери для наших елементів. Один для категорії, інший для лічильника коментарів, відповідний заголовок, контейнер для автора, а також для дати. Не забудемо додати посилання:

HTML & CSS
8 comments

A Tale of CSS and Precision Sass


by
Hugo Giraudel

May 12, 2016

Виглядає непогано! Пара цікавинок:

ми не використовуємо у верхній частині тег header, тому що для хедера властивий заголовок, якого у нас немає;

ми використовуємо тег span, а не p, так як нам просто нічого загортати в абзац;

для дати ми використовуємо відповідний тег time з атрибутом datetime, а не span.

Замінимо слово «comments» відповідною доступною іконкою.

8

Зверніть увагу, як ми використовуємо атрибут aria-label, щоб зробити іконку доступною для користувачів з обмеженими можливостями. Залишилося додати микроданные код, щоб полегшити його сканування та індексування пошуковими системами. Загляньте на Schema.org до розділу статей.

HTML & CSS
8

A Tale of CSS and Precision Sass


by
Hugo Giraudel

May 12, 2016

Перш ніж ми перейдемо до стилів, хотілося сказати пару слів і інкапсуляції і правильної реалізації дизайну. Компонент за своїм визначенням має бути багаторазовим. Щоб бути повторно використаним в адаптивному контексті, у компонента не повинно бути фіксованих розмірів, він повинен займати весь простір контейнера.

Таким чином, сам контейнер задає межі інкапсульованого компонента. В нашому випадку в ролі контейнера може виступати елемент списку, та його частина, відповідальна за відображення плиток (карток або чогось іншого). Плитки можуть виглядати ось так:

На даному етапі ми повністю закінчили роботу з розміткою. Розмітка чиста, доступна і дружить з SEO. Більше тут робити нічого, перейдемо до стилів!

Пишемо стилі

У частині CSS для всіх елементів ми будемо дотримуватися правильної блокової моделі. Також ми будемо багато працювати з flexbox. Власне, чому б і ні?

Компонент контейнер списку

Компонент списку дуже тонкий, тут майже нічого стилізувати. Контейнер повинен забезпечити сітку для наших плиток, керувати відстанню між ними, а також стежити, щоб плитки були однієї висоти. Завдяки flexbox, це не так вже й складно.

/**
* 1. Скидаємо стилі за промовчанням для списку
* 2. Flexbox використовується для створення сітки під плитки.
*/
.c-tile-list {
list-style: none; /* 1 */
margin: 0; /* 1 */
padding: 0; /* 1 */
display: flex; /* 2 */
flex-wrap: wrap; /* 2 */
}

Елементи списку:

/**
* 1. З допомогою flexbox плитки на одному рядку мають одну висоту.
* 2. Перевіряємо час.
* 3. Відстань між плитками.
*/
.c-tile-list__item {
display: flex; /* 1 */
flex-direction: column; /* 1 */
flex: 0 0 300px; /* 2 */
margin: 10px; /* 3 */
}

Компонент плитка статті

Перейдемо до найскладнішого – компонент плитки статті. Тут потрібно дуже багато стилів, почнемо з самої плитки. Як було сказано раніше, плитка не повинна мати фіксованих розмірів і повинна покладатися тільки на розміри свого контейнера. Також ми зробимо плитку флекс контейнером, щоб вирівняти футер в нижній частині, не спираючись на висоту самої плитки.

/**
* 1. Вирівняємо футер всередині плитки з мінімальною висотою.
* 2. Зробимо так, щоб плитка займала всю висоту батьків, якщо вона перебуває всередині
* флекс контейнера.
*/
.c-article-tile {
display: flex; /* 1 */
flex-direction: column; /* 1 */
flex: 1 0 auto; /* 2 */
border: 1px solid rgba(0, 0, 0, 0.1);
background-color: rgb(255, 255, 255);
}

Можна перейти на наступний рівень і стилізувати внутрішні контейнери (хедер, основний контейнер, футер). Усім їм необхідно прописати горизонтальний padding, і для спрощення подальшого позиціонування необхідно перетворити їх у флекс контейнери.

.c-article-tile__header,
.c-article-tile__body,
.c-article-tile__footer {
display: flex;
padding-left: 20px;
padding-right: 20px;
}

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

.c-article-tile__header,
.c-article-tile__footer {
font-size: 80%;
}

Ми прописали основні стилі для контейнерів. Перейдемо до стилізації окремих елементів. Почнемо з хедера. Необхідно додати вертикальних відступів і символічну нижню межу, щоб блок візуально схожий на хедер.

/**
* 1. Дуже зручно спиратися на властивість `color` для установки кольору нижньої межі
* це підвищує рівень стилізації теми.
*/
.c-article-tile__header {
padding-top: 15px;
padding-bottom: 10px;
border-bottom: 2px solid; /* 1 */
}

Напрямок за промовчанням для флекс контейнера – row. Саме тому ми задаємо його для внутрішніх контейнерів в неявному вигляді. Є два способи вирівняти лічильник коментарів в хедері по правому краю. Перший спосіб – встановити властивість justify-content: space between для хедера, щоб виштовхнути елементи. Ми скористаємося другим способом – встановити властивість margin-left: auto на самому лічильнику і покластися на найбільший секрет flexbox.

/**
* 1. Праве вирівнювання лічильника коментарів у хедері.
*/
.c-article-tile__comment-count {
margin-left: auto; /* 1 */
}

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

.c-article-tile__body {
padding-top: 20px;
padding-bottom: 20px;
}
.c-article-tile__title {
margin: 0;
color: #333;
font-size: 150%;
}

Нарешті, можна розібратися з футером – найцікавішою частиною. По-перше, футер повинен бути вирівняний по нижньому краю плитки.

По-друге, футер повинен поміщатися на одній рядку. Зробити це можна за допомогою властивості white-space: nowrap. Однак ми не знаємо точну довжину імені автора, тому потрібно перевірити, щоб макет не зламався з дуже довгим ім’ям. Я знаю, що «усічення рядків не підходить для контен…», але в нашому випадку це менше із двох зол.

/**
* 1. Нижня вирівнювання футера в плитці.
* 2. Робимо так, щоб вміст у футері не перестрибував на другий рядок
*/
.c-article-tile__footer {
padding-top: 10px;
padding-bottom: 15px;
margin-top: auto; /* 1 */
white-space: nowrap; /* 2 */
color: #949494;
}
/**
* 1. Робимо так, щоб ім’я автора і дата не перекривали один одного в разі, якщо
* вони не влазять на один рядок; додаємо до імені три крапки.
* 2. Якщо автор і дата влазять, то візуально це непомітно; але все одно
* додаємо відступ між ними, якщо вони наблизяться на одному рядку.
*/
.c-article-tile__author {
text-overflow: ellipsis; /* 1 */
overflow: hidden; /* 1 */
margin-right: 5px; /* 2 */
}
/**
* 1. Контейнер дати з правим вирівнюванням в футері.
*/
.c-article-tile__date {
margin-left: auto; /* 1 */
}

За стилями плитки закінчили! Залишилося обговорити всього одну річ.

Теми

Ви могли помітити, що про темизацию компонента ми не сказали ні слова. Я вважаю, що колірні схеми повинні бути відокремлені від макету: їх мета в іншому, тому з ними не можна працювати точно так само (і не потрібно). У випадку з темизацией я люблю використовувати безкомпонентные класи з префіксом t-. Додамо клас до теми нашої плитці:

Тепер на основі цього класу ми можемо прописувати стилі для нашої плитки. Ми додамо колір нашої плитці і всім її посиланнях. Стилі ефектно перейдуть на нижню межу хедера, але не торкнуться текст футера, у якого він вже є (#949494).

.c-article-tile.t-sass,
.c-article-tile.t-sass a {
color: #c69;
}

Відмінно, залишилося вирішити проблему з кольором заголовка. Він рожевий, а повинен бути чорним і тільки при наведенні стає рожевим. Необхідно примусити посилання успадкувати колір батьків (#333), коли батько не перебуває у стані hover або active. Можна по-розумному скористатися псевдоклассом :not():

/**
* 1. Робимо так, щоб посилання наслідувала колір батька, коли він не
* у стані hover/active.
*/
.c-article-tile__title:not(:hover):not(:active) > a {
color: inherit; /* 1 */
}

Висновок

От і все! Стаття вийшла великий, але, сподіваюся, вам сподобалося. Думаю, це ідеальний приклад правильної інкапсуляції компонентів, управління темою, а також роботи з flexbox. Поиграйтесь з демо. Якщо придумаєте, як зробити його ще краще, пишіть про це в коментарях!