Від автора: стаття нашого гостя, Пітера Бизменса. Пітер – front-end розробник на сайті Audience, де він любить писати стилі на SCSS. Сьогодні він нам покаже те, що я називаю чесним CSS трюком. Весь веб має вертикальне будова. Ви читаєте сайт, як звичайну книгу: зліва направо, зверху вниз. Але іноді хочеться піти від вертикальності і зробити щось божевільне: зробити горизонтальний список. Або ще безумніше, горизонтальний сайт!
Було б непогано, якщо б ми могли робити ось так:
/* несправжній код */
div {
scroll-direction: horizontal;
}
На жаль, такого не буде. Такого навіть в планах немає в CSS.
Це дуже погано, тому що в компанії, в якій я працюю, це б дуже в нагоді. Ми робимо дуже багато презентацій, а презентація – це досить горизонтальна штука. Зазвичай співвідношення сторін у слайдів складає 4:3 або 16:9. З-за цього у нас виникає постійна проблема з горизонтальними слайдами і вертикальними веб-технологіями. Під «ми» я маю на увазі себе. Але що я люблю, так це труднощі.
Інший варіант використання
Мені в голову прийшов конкретний спосіб застосування. Ідея в тому, що покупцям було б зручно переглядати всі товари на одному слайді. Природно, каталог товарів не вмістився б в одному виді. Тому ми вирішили розбити каталог на три категорії, кожна з горизонтальною прокруткою. Таким чином, три найпопулярніших товару відображаються в кожній категорії, а до менш важливих товарів відкритий легкий доступ.
Спосіб без JavaScript
Всі ми знаємо, що на JS існує маса спосіб зробити горизонтальну прокрутку. Деякі приклади є на CSS-Tricks. Мені стало цікаво, чи можна втілити цю ідею на чистому CSS. Рішення виявилося дуже простим:
створюємо контейнер з елементами;
повертаємо контейнер на 90 градусів проти годинникової стрілки, щоб нижня грань опинилася праворуч;
повертаємо елементи всередині контейнера назад на своє місце.
Крок 1) створюємо контейнер
Створіть блок div з безліччю дочірніх елементів.
У нашому прикладі прокручується контейнер буде 300px шириною, в ньому буде 8 елементів 100х100рх. Розміри довільні, можна задати будь-які.
Висота контейнера стане шириною і навпаки. Нижче ширина контейнера буде становити 300px:
.horizontal-scroll-wrapper {
width: 100px;
height: 300px;
overflow-y: auto;
overflow-x: hidden;
}
Та дочірні елементи:
.horizontal-scroll-wrapper > div {
width: 100px;
height: 100px;
}
Крок 2) контейнер повертаємо
Тепер потрібно повернути контейнер на -90 градусів за допомогою CSS властивості transform. Ми отримали горизонтальний скроллер.
.horizontal-scroll-wrapper {
…
transform: rotate(-90deg);
transform-origin: top right;
}
Тільки є одна маленька проблема: дочірні елементи повернулися разом з контейнером.
Крок 3) повертаємо дочірні елементи назад на своє місце
Так як же повернути елементи на своє місце? Поверніть його назад за допомогою CSS властивості transform.
.horizontal-scroll-wrapper > div {
…
transform: rotate(90deg);
transform-origin: top right;
}
Крок 4) фіксоване позиціонування
Виглядає все непогано, але є кілька проблем.
Ми повернули контейнер, а в якості якоря поставили правий верхній кут, з-за цього ліва сторона змістилася на ширину контейнера. Якщо вам складно уявити, просто додайте палець до правому верхньому кутку сторінки і поверніть її. Вихід: потрібно повернути її назад за допомогою властивості translate.
Вже краще. Але першого елемента все ще не видно, так як та ж проблема спостерігається і з дочірніми елементами. Це можна поправити, задавши першому дочірньому елементу верхній margin зі значенням його ширини або трансформувавши всі елементи, як контейнер. Найпростіший спосіб, який я знайшов, це додати верхній padding до контейнера, рівний ширині дочірніх елементів, тим самим створивши буферну зону для елементів.
.horizontal-scroll-wrapper {
…
transform:rotate(-90deg) translateY(-100px);
…
}
Ще одне демо з прямокутними дочірніми елементами:
Сумісність
Я перевірив сумісність на доступних мені пристроях.
Десктоп
Так як стилізація скроллбаров поки що працює тільки в Webkit/Blink браузерах Firefox і IE показується звичайний сірий скроллбар. Це можна поправити за допомогою JS і ховати їх взагалі, але це тема для іншого уроку.
Прокрутка за допомогою колеса миші відмінно працює на десктопі. Але у мого ноутбука свою думку на цей рахунок. На пристроях з тач скрінами і тач падами демо веде себе так, ніби div взагалі не повертали.
Мобільні пристрої
Я був приємно здивований, коли дізнався, що Android розуміє, що контейнер був повернутий, і дозволяє вам скролити з допомогою свайпов вправо і вліво.
З iOS ж навпаки, все не так гладко. Браузер веде себе так, ніби контейнер не повертали зовсім. Тому для прокрутки потрібно використовувати свайпи вгору і вниз, що досить дивно. Overflow: hidden не вирішує проблему.
Висновок
За даними сайту Can I Use трансформації в CSS зараз підтримуються у 93%+ користувачів (на момент написання статті, листопад 2016). Тут проблем виникнути не повинно.
Хоча краще не використовувати цей метод в продуктиве. Я протестував його на деяких пристроях, але далеко не на всіх і не так ретельно.
Найбільша проблема – сенсорні инпуты, в яких для переходу наліво і направо потрібно робити свайпи вгору і вниз. В якості рішення можна було б прописати повідомлення на сайті з поясненням, але тоді вам доведеться покластися на те, що користувачі прочитають його. І навіть тоді це буде суперечити здоровому глузду. Інший спосіб рішення – захоплювати сенсорні инпуты з допомогою JS на пристроях, але тоді краще взагалі все писати на JS і повністю відмовитися від нашого CSS хака.