Подсказки о прокрутке

Оцените материал
(0 голосов)

Проблема

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


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


Однако для того чтобы добиться этого эффекта в Google Reader, разработчикам пришлось добавить немало сценариев. Было ли это действительно необходимо или тот же эффект можно реализовать на чистом CSS?

Решение

Начнем с самой простой разметки, обычного неупорядоченного списка с бессмысленным содержимым (эксцентричными кличками для кошек!):
HTML
<ul>
<li>Ada Catlace</li>
<li>Alan Purring</li>
<li>Schrödingcat</li>
<li>Tim Purrners-Lee</li>
<li>WebKitty</li>
<li>Json</li>
<li>Void</li>
<li>Neko</li>
<li>NaN</li>
<li>Cat5</li>
<li>Vector</li>
</ul>

Теперь мы можем применить к элементу  <ul> простейшую стилизацию, для того чтобы сделать его меньше длины его содержимого и добавить возможность прокрутки:
overflow: auto;
width: 10em;
height: 8em;
padding: .3em .5em;
border: 1px solid silver;
Здесь и начинается самое интересное. Давайте создадим наверху тень с помощью радиального градиента:
background: radial-gradient(at top, rgba(0,0,0,.2),transparent 70%) no-repeat;
background-size: 100% 15px;

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

Это соответствует тому, как фоновые изображения работают по умолчанию: их позиция всегда зафиксирована относительно элемента, независимо от того, насколько сильно мы прокручиваем содержимое элемента. Это правило распространяется также и на изображения со свойством background-attachment: fixed ; единственное отличие в том, что они также остаются на своем месте, когда пользователь прокручивает содержимое страницы. Можно ли заставить фоновое изображение прокручиваться вместе с содержимым элемента? До недавнего времени реализовать этот простой эффект было невозможно. Однако наличие проблемы было очевидно, и для ее решения в Backgrounds &Borders Level 3 для  background-attachment было добавлено новое ключевое слово:  local. Но  background-attachment: local не решает нашу проблему без дополнительной обработки напильником. Если мы применим это свойство к нашей градиентной тени, то результат будет прямо противоположным: тень будет отображаться, когда содержимое прокручено до самого верха, а при прокрутке содержимого вниз тень будет пропадать. Но для начала уже неплохо — нужно же с чего-то начинать. Секрет трюка в том, чтобы использовать два фона: один для тени, а второй — представляющий собой, по сути, белый прямоугольник, закрывающий тень и играющий роль маски. Для фона, генерирующего тень, будет установлено значение  background-attachment по умолчанию ( scroll ), так как мы хотим,
чтобы он всегда оставался на своем месте. Однако для маскирующего фона мы установим значение свойства  background-attachment , равное  local , для того чтобы он закрывал тень, когда содержимое прокручивается до самого верха. Когда же мы будем прокручивать содержимое вниз, он будет прокручиваться вместе с содержимым, открывая таким образом тень. Для создания маскирующего прямоугольника мы воспользуемся линейным градиентом того же цвета, что и фоновый цвет элемента (в нашем случае это белый):
background: linear-gradient(white, white),
radial-gradient(at top, rgba(0,0,0,.2),
transparent 70%);
background-repeat: no-repeat;
background-size: 100% 15px;
background-attachment: local, scroll;

На риcунке ниже вы видите, как это решение работает на разных этапах прокрутки.

Очевидно, что нам удалось добиться желаемого эффекта, но не без одного большого недостатка: когда мы только начинаем прокручивать список, тень открывается странным образом и поначалу выглядит обрезанной. Можно ли сделать эффект более гладким и естественным? Мы можем воспользоваться преимуществом того факта, что наша «маска» по природе своей — это (вырожденный) линейный градиент, и преобразовать его в настоящий градиент от цвета  white до прозрачного белого ( hsla(0,0%,100%,0) или  rgba(255,255,255,0) ), для того чтобы обеспечить плавное отображение нашей тени:
background: linear-gradient(white, hsla(0,0%,100%,0)),
radial-gradient(at top, rgba(0,0,0,.2),
transparent 70%);



Это шаг в правильном направлении. Как вы видите на рисунке, это обеспечивает плавное постепенное отображение тени, как мы и хотели. Однако пока что у нашего решения есть довольно серьезный недостаток: когда список прокручен до самого верха, тень теперь закрывается не полностью. Этот огрех можно исправить, сместив границу перехода цвета white чуть ниже (если точнее, то на  15px — такова высота нашей тени), чтобы получить поле сплошного белого цвета, прежде чем начнется переход к прозрачности. Помимо этого, нам необходимо увеличить размер «маски», для тогочтобы он был больше тени, иначе градиента не получится. Точное значение высоты зависит от того, насколько плавный эффект вы желаете реализовать (то есть насколько быстро тень должна появляться после начала прокрутки). После серии экспериментов я пришла к выводу, что 50px — разумное значение. Финальная версия кода выглядит, как показано далее, а результат вы можете видеть на рисунке:


background: linear-gradient(white 30%, transparent),
radial-gradient(at 50% 0, rgba(0,0,0,.2),
transparent 70%);
background-repeat: no-repeat;
background-size: 100% 50px, 100% 15px;
background-attachment: local, scroll;
Почему прозрачный белый, а не просто transparent? Второе значение - это на самом деле всего лишь псевдоним для rgba(0,0,0,0), поэтому градиент может включать оттенки серого в переходах от непрозрачного белого к прозрачному черному. Если браузеры интерполируют цвета в рамках данной
спецификации в так называемом цветовом пространстве premultiplied RGBA, то такое не должно случаться.
Разумеется, для того чтобы достичь исходного эффекта, нам потребуются еще два градиента для нижней тени, а также маска для нее, но логика остается той же самой, так что я оставлю это в качестве упражнения для читателя (или загляните в пример из врезки «Попробуйте сами!» ниже).

ПОПРОБУЙТЕ САМИ!

http://play.csssecrets.io/scrolling-hints

Десерт на сегодня – как сделать арбалет из офисных принадлежностей. Жаль, я не знал такого, когда учился в школе

Прочитано 88 раз Последнее изменение Воскресенье, 14 мая 2017 10:57
Другие материалы в этой категории:
Понравилась запись? Подпишитесь на обновления по почте:

Оставить комментарий

Убедитесь, что вы вводите (*) необходимую информацию, где нужно
HTML-коды запрещены

Поиск по сайту

Google+