This article introduces a clever way to convert the selection control into a dial-style interaction similar to a combination lock or iOS date selector. Long lists of choices, such as country choices, are often annoying, and this approach can effectively solve this problem.
The core idea is: use scrolling operations to select options, rather than traditional click selection. Instead of building custom controls from scratch, we cleverly utilize semantic form controls—radio buttons.
HTML structure is as follows, using nested radio buttons tag group:
<label for="madrid"> Madrid <abbr>MAD</abbr> </label> <label for="malta"> Malta <abbr>MLA</abbr> </label>
The key lies in the control of CSS styles to achieve accurate management of option sizes and spacing. Here are some basic styles:
.scroll-container { /* 尺寸和布局 */ \--itemHeight: 60px; \--itemGap: 10px; \--containerHeight: calc((var(--itemHeight) * 7) + (var(--itemGap) * 6)); width: 400px; height: var(--containerHeight); align-items: center; row-gap: var(--itemGap); border-radius: 4px; /* 样式 */ \--topBit: calc((var(--containerHeight) - var(--itemHeight))/2); \--footBit: calc((var(--containerHeight) + var(--itemHeight))/2); background: linear-gradient( rgb(254 251 240), rgb(254 251 240) var(--topBit), rgb(229 50 34 / .5) var(--topBit), rgb(229 50 34 / .5) var(--footBit), rgb(254 251 240) var(--footBit)); box-shadow: 0 0 10px #eee; }
Style description:
--itemHeight
: The height of each option. --itemGap
: The spacing between options. --containerHeight
: Container height, make sure to display up to seven options (odd numbers center the selected item). --topBit
and --footBit
variables define gradient stops, visually highlighting the selected area. Use Flexbox layout vertical arrangement options:
.scroll-container { display: flex; flex-direction: column; /* 其他样式 */ }
Enable CSS scroll capture:
.scroll-container { overflow-y: scroll; scroll-snap-type: y mandatory; overscroll-behavior-y: none; /* 其他样式 */ }
scroll-snap-type: y mandatory;
Make sure the scrolling stops on the option. overscroll-behavior-y: none;
Prevent scrolling overflow.
Option style:
.scroll-item { /* 尺寸和布局 */ width: 90%; box-sizing: border-box; padding-inline: 20px; border-radius: inherit; /* 样式和字体 */ background: linear-gradient(to right, rgb(242 194 66), rgb(235 122 51)); box-shadow: 0 0 4px rgb(235 122 51); font: 16pt/var(--itemHeight) system-ui; color: #fff; input { appearance: none; } abbr { float: right; } /* 机场代码 */ /* 选中状态样式 */ &:has(:checked) { background: rgb(229 50 34); } }
scroll-snap-align: center;
Align the options centered. pointer-events: none;
Block clicking selection, select only by scrolling.
JavaScript code is used to listen for scroll events, setting the scroll to center option to select:
let observer = new IntersectionObserver(entries => { entries.forEach(entry => { with(entry) if(isIntersecting) target.children[1].checked = true; }); }, { root: document.querySelector(`.scroll-container`), rootMargin: `-51% 0px -49% 0px` }); document.querySelectorAll(`.scroll-item`).forEach(item => observer.observe(item));
IntersectionObserver
API is used to detect whether an element enters the viewport.
Use the above steps to create a form control that selects options by scrolling. If you need to pre-select an option when the page is loaded, you can get its location through JavaScript and scroll to it using the scrollTo()
method.
Reference links and further readings:
flex
property (CSS-Tricks)scrollTo()
(MDN)(GitHub page demo link and video link will be added here because I can't directly access and embed external resources.)
The above is the detailed content of How to Make a 'Scroll to Select” Form Control. For more information, please follow other related articles on the PHP Chinese website!