I have an unordered list with a variable number of list items. The <ul> is of fixed height (actually the height of a single line of text) and set to overflow-y: scroll.
When I scroll the mouse-wheel, a certain vertical distance is traversed. I would like to have it exatly scroll line by line, to ensure that a <li> is always properly centered in the visible part of the <ul>.
:root {
--default-line-height: 24px;
}
.myUl {
background-color: lightblue;
height: var(--default-line-height);
list-style-type: none;
overflow-y: scroll;
outline: 1px solid black;
}
.myLi {
font-size: var(--default-line-height);
}
<ul class="myUl">
<li class="myLi">Lorem ipsum dolor sit amet</li>
<li class="myLi">Aenean commodo ligula eget dolor.</li>
<li class="myLi">Cum sociis natoque penatibus</li>
<li class="myLi">Donec quam felis, ultricies nec</li>
<li class="myLi">Nulla consequat massa quis enim.</li>
<li class="myLi">Donec pede justo, fringilla vel</li>
<li class="myLi">In enim justo, rhoncus ut</li>
</ul>
<p>Please scroll the blue area.</p>
I played with scroll-snap but to no real success. The animation "feels" awkward and it still scrolls multiple lines. I could probably build something with scroll but that seems unnecessarily cumbersome.
It seemed reasonable to be able to scroll line by line under certain conditions. List-like-controls (eg dropdowns) show this behaviour in many frameworks. I would not have thought this would need more than some clever css...
Update: Feroz’s answer below only solves the snapping aspect of the problem. It is still possible to scroll multiple lines in one go.
Please check my snippet. Now you can scroll line by line.
:root {
--default-line-height: 28px;
}
.myUl {
background-color: lightblue;
height: var(--default-line-height);
list-style-type: none;
overflow-y: scroll;
outline: 1px solid black;
scroll-snap-type: y mandatory;
}
.myLi {
font-size: 24px;
line-height: var(--default-line-height);
scroll-snap-align: start;
scroll-snap-stop: normal;
}
<ul class="myUl">
<li class="myLi">Lorem ipsum dolor sit amet</li>
<li class="myLi">Aenean commodo ligula eget dolor.</li>
<li class="myLi">Cum sociis natoque penatibus</li>
<li class="myLi">Donec quam felis, ultricies nec</li>
<li class="myLi">Nulla consequat massa quis enim.</li>
<li class="myLi">Donec pede justo, fringilla vel</li>
<li class="myLi">In enim justo, rhoncus ut</li>
</ul>
<p>Please scroll the blue area.</p>
Find the solution on https://css-tricks.com/practical-css-scroll-snapping/
<div class="container">
<section class="child"></section>
<section class="child"></section>
<section class="child"></section>
<p>...</p>
</div>
.container {
scroll-snap-type: y mandatory;
}
.child {
scroll-snap-align: start;
}