image


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


Я подумал почему бы не воспользоваться горизонталью? Разработчики браузеров дали достаточно CSS инструментов чтобы выстроить статьи по горизонтали и сделать удобный переход между ними.


Я создал минимальную демку которая работает за счёт CSS и имеет такие свойства:


  1. Статьи выстраиваются по горизонтали.
  2. Часть статьи не надо скрывать под спойлером так как вертикальная прокрутка для каждой статьи индивидуальна.
  3. На следующую статью можно перейти из любого места предыдущей прокрутив колёсико мышки с зажатым Shift или смахнув статью влево на планшете.

В статье я разберу СSS используемый для горизонтального блога.


Пример HTML
<html>
    <head>
        <title>horizontal blog demo</title>
        <link href="horizontal-blog.css" rel="stylesheet" media="screen">
        <link href="css-min-fix.css" rel="stylesheet" media="screen">
    </head>
    <body>
        <div class="hb-viewport">
            <div class="hb-container">
                <article class="hb-page">
                    <h1>Lorem ipsum dolor sit amet</h1>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Leo integer malesuada nunc vel risus...
                </article>
                <article class="hb-page">
                    <h1>Consectetur a erat nam at lectus urna duis</h1>
                    Consectetur a erat nam at lectus urna duis. Cursus vitae congue mauris rhoncus aenean. Quis auctor elit sed vulputate mi sit amet mauris commodo. Odio pellentesque diam volutpat commodo sed...
                </article>  
            </div>
        </div>
    </body>
</html>

Разбираем CSS


horizontal-blog.css:
/*
Это окно через которое пользователь читает содержимое статьи. Изначально его функции выполнял :root элемент но я решил отвязаться от структуры html документа.
*/


.hb-viewport{

/*
Избавляемся от отступа поумолчанию у body не трогая стили css body.
*/


    position: absolute;
    top: 0;
    left: 0;

/*
Задаём размеры viewport размером видимой области окна чтобы была возможна прокрутка по горизонтали.
*/


    width: 100vw;
    height: 100vh;

/*
Задаём прокрутку по горизонтали а вертикальную скрываем так как нужно чтобы прокручивалась вниз каждая статья индивидуально.
*/


    overflow-x: auto;
    overflow-y: hidden;

/*
Чтобы облегчить прокрутку задаём автоматическое выравнивание прокрутки по горизонтали.
*/


    scroll-snap-type: x mandatory;

/*
Скрываем горизонтальную полосу прокрутки так как по умолчанию в Firefox она не скрывается и перекрывает последние строки текста. Благодаря этому правилу мы можем вывести указатель за пределы .hb-viewport и прочитать перекрытый горизонтальной полосой прокрутки текст.
*/


    scrollbar-width: none;
}

/*
Показываем горизонтальную полосу прокрутки. Это позволяет пользоваться ей когда указатель находится внутри .hb-viewport
*/


.hb-viewport:hover{
    scrollbar-width: auto;
}

/*
Благодаря display: flex; .hb-container выстраивает своё содержимое в длинную горизонтальную полосу.
*/



.hb-container{
    display: flex;
}

/*
.hb-page содержит в себе статью.
*/



.hb-page{

/*
Чтобы статью индивидуально можно было прокручивать по вертикали ограничиваем её по высоте её размером видимой части окна.
*/


    max-height: 100vh;

/*
Скрываем то что не влезло добавляя полосу прокрутки по необходимости.
*/


    overflow-y: auto;

/*
Привязываем выравнивание прокрутки по центру .hb-page.
*/


    scroll-snap-align: center;

/*
Задаём ширину статьи до 80 символов для удобства чтения и добавляем поля по бокам до 100vw.
*/


    min-width: min(80ch, 100vw);
    padding: 0 calc((100vw - 80ch) / 2);
}

Поправляем CSS


Есть проблема с моим Firefox на Android планшете который перестал обновляться с версии 68.11. Он не поддерживает css функцию min(). Можно это поправить при помощи директивы @supports и @media.


css-min-fix.css:
/*
Проверяем что браузер не поддерживает min.
*/


@supports not (min-width: min(80ch, 100vw)) {

/*
Задаём ширину по умолчанию в 100vw.
*/


    .hb-page{
        min-width: 100vw;
    }

/*
Если видимая часть окна шире 80 символов то задаём ширину 80 символов.
*/


    @media screen and (min-width: 80ch) {
      .hb-page{
          min-width: 80ch;
      }
    }
}

Готово


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


Ссылки