μ λ°ν μ μ΄μ μ΄μ μ λ§μΆ° CSS μ€ν¬λ‘€ μ€λ μ κ°λ ₯ν κΈ°λ₯μ νμν΄ λ³΄μΈμ. μννκ³ μ νν μ€ν¬λ‘€ κ²½νμ λ§λ€μ΄ λ°μ΄λ μ¬μ©μ μΈν°νμ΄μ€λ₯Ό ꡬννλ λ°©λ²μ λ°°μ보μΈμ.
CSS μ€ν¬λ‘€ μ€λ μ λ° μμ§: μ€λ ν¬μΈνΈ μ νλ μ μ΄ λ§μ€ν°νκΈ°
CSS μ€ν¬λ‘€ μ€λ μ κ°λ°μκ° λΆλλ½κ³ μ μ΄λ μ€ν¬λ‘€ κ²½νμ λ§λ€ μ μκ² ν΄μ£Όλ κ°λ ₯ν λꡬμ λλ€. μ€ν¬λ‘€ 컨ν μ΄λκ° νΉμ μ§μ μ μ€λ λλλ‘ νμ¬ μ½ν μΈ κ° μλ²½νκ² μ λ ¬λκ³ κ°μμ€λ¬μ΄ μ νμ μ΅μνν©λλ€. μ΄ κΈ°μ¬μμλ CSS μ€ν¬λ‘€ μ€λ μ 볡μ‘ν λΆλΆμ μμΈν μ΄ν΄λ³΄κ³ , νΉν μ λ°ν μ νλλ₯Ό λ¬μ±νκ³ μ§κ΄μ μΈ μ¬μ©μ μνΈμμ©μ λ§λλ λ° μ€μ μ λ‘λλ€.
CSS μ€ν¬λ‘€ μ€λ μ κΈ°λ³Έ μ리 μ΄ν΄νκΈ°
κ³ κΈ κΈ°μ μ μ΄ν΄λ³΄κΈ° μ μ CSS μ€ν¬λ‘€ μ€λ μ μ μ΄νλ ν΅μ¬ μμ±λ€μ κ²ν ν΄ λ³΄κ² μ΅λλ€.
- scroll-snap-type: μ€λ
ν¬μΈνΈκ° μΌλ§λ μ격νκ² μ μ©λ μ§ μ μν©λλ€. μ€λ
ν μΆ(
x
,y
, λλboth
)κ³Ό μ€λ λμ(mandatory
λλproximity
)μ λ κ°μ§ κ°μ κ°μ§λλ€.mandatory
λ μ€ν¬λ‘€ 컨ν μ΄λκ° νμ μ€λ ν¬μΈνΈμ μ€λ λλλ‘ κ°μ νλ λ°λ©΄,proximity
λ μ€ν¬λ‘€ λμμ΄ μ€λ ν¬μΈνΈμ μΆ©λΆν κ°κΉμΈ λλ§ μ€λ λ©λλ€. - scroll-snap-align: μμμ μ€λ
μμμ΄ μ€ν¬λ‘€ 컨ν
μ΄λμ μ€λ
μμκ³Ό μ΄λ»κ² μ λ ¬λ μ§ μ§μ ν©λλ€. μν μΆ(
start
,center
, λλend
)κ³Ό μμ§ μΆμ λν λ κ°μ§ κ°μ λ°μ΅λλ€. - scroll-snap-stop: (λΉκ΅μ μ΅μ μμ±) μ€ν¬λ‘€ 컨ν
μ΄λκ° νμ μ€λ
ν¬μΈνΈμμ λ©μΆ°μΌ νλμ§ κ²°μ ν©λλ€.
normal
(κΈ°λ³Έκ°μΌλ‘, μ¬μ©μκ° λΉ λ₯΄κ² μ€ν¬λ‘€νλ©΄ μ€λ ν¬μΈνΈλ₯Ό μ§λμΉ μ μμ)κ³Όalways
(κ° μ€λ ν¬μΈνΈμμ μ€ν¬λ‘€ 컨ν μ΄λκ° λ©μΆλλ‘ κ°μ ν¨)μ λ κ°μ§ κ°μ κ°μ§λλ€. - scroll-padding: μ€ν¬λ‘€ 컨ν μ΄λ μ£Όμμ ν¨λ©μ μ μνμ¬ μ€λ μμμ μν₯μ μ€λλ€. κ³ μ λ ν€λλ νΈν°λ₯Ό μμ©νλ λ° μ μ©ν©λλ€.
κΈ°λ³Έ μ€ν¬λ‘€ μ€λ μμ
κΈ°λ³Έμ μΈ μν μ€ν¬λ‘€ μ€λ μ ꡬννλ κ°λ¨ν μμ μ λλ€.
.scroll-container {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.scroll-item {
flex: none;
width: 100%; /* Or a specific width */
scroll-snap-align: start;
}
μ΄ μμ μμ .scroll-container
λ .scroll-item
μμλ€μ μνμΌλ‘ μ€ν¬λ‘€νλ©° κ° μμ΄ν
μ μμ λΆλΆμ μ€λ
λ©λλ€. κ° μμ΄ν
μ 컨ν
μ΄λμ μ 체 λλΉλ₯Ό μ°¨μ§νκ² λ©λλ€.
μ λ°λ λ¬μ±νκΈ°: μ€λ ν¬μΈνΈ μ νλ λ―ΈμΈ μ‘°μ
κΈ°λ³Έ μμ±λ€μ΄ κ²¬κ³ ν κΈ°λ°μ μ 곡νμ§λ§, μ§μ ν μ λ°λλ₯Ό λ¬μ±νλ €λ©΄ μ’ μ’ λ λ―Έλ¬ν μ μ΄κ° νμν©λλ€. μ€λ ν¬μΈνΈ μ νλλ₯Ό λ―ΈμΈ μ‘°μ νκΈ° μν λͺ κ°μ§ κΈ°μ μ λ€μκ³Ό κ°μ΅λλ€.
1. μ€νμ
μ‘°μ μ μν scroll-padding
νμ©
scroll-padding
μ λ€λ₯Έ UI μμλ₯Ό μμ©νκΈ° μν΄ μ€λ
ν¬μΈνΈλ₯Ό μ‘°μ νλ λ° μ€μν μν μ ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, κ³ μ ν€λκ° μλ κ²½μ° scroll-padding-top
μ μ¬μ©νμ¬ μ€λ
ν¬μΈνΈλ₯Ό μ€νμ
νκ³ μ½ν
μΈ κ° ν€λ λ€μ μ¨κ²¨μ§λ κ²μ λ°©μ§ν μ μμ΅λλ€.
.scroll-container {
scroll-snap-type: y mandatory;
scroll-padding-top: 60px; /* Adjust to the height of your fixed header */
}
2. μ λ΅μ μΈ λ§μ§ λ° ν¨λ©κ³Ό scroll-snap-align
κ²°ν©
μ€ν¬λ‘€ μμ΄ν
μ λ§μ§κ³Ό ν¨λ©μ μ μ€νκ² μ‘°μ ν¨μΌλ‘μ¨ μ€λ
ν¬μΈνΈ μμΉλ₯Ό λμ± μΈλ°νκ² λ€λ¬μ μ μμ΅λλ€. μλ₯Ό λ€μ΄, μ½ν
μΈ κ° μ»¨ν
μ΄λ μ€μμ μ€λ
λκΈ°λ₯Ό μνλ€λ©΄ scroll-snap-align: center
λ₯Ό μ¬μ©νκ³ μ€ν¬λ‘€ μμ΄ν
μ μΌμͺ½κ³Ό μ€λ₯Έμͺ½ ν¨λ©μ μ‘°μ ν μ μμ΅λλ€.
3. λμ μ€λ ν¬μΈνΈ μ‘°μ μ μν μλ°μ€ν¬λ¦½νΈ νμ©
νλ©΄ ν¬κΈ°, μ½ν
μΈ λ³κ²½ λλ κΈ°ν μμΈμ λ°λΌ μ€λ
ν¬μΈνΈ μμΉλ₯Ό λμ μΌλ‘ μ‘°μ ν΄μΌ νλ μλ리μ€μμλ μλ°μ€ν¬λ¦½νΈκ° νμμ μ
λλ€. μλ°μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νμ¬ μ μ ν scroll-padding
λλ scroll-snap-align
κ°μ λ€μ κ³μ°νκ³ μ μ©ν μ μμ΅λλ€.
μμ : νλ©΄ ν¬κΈ°μ λ°λΌ scroll-padding λμ μΌλ‘ μ‘°μ νκΈ°.
window.addEventListener('resize', function() {
const container = document.querySelector('.scroll-container');
const headerHeight = document.querySelector('header').offsetHeight; //Get Header Height, assuming your header is above
container.style.scrollPaddingTop = headerHeight + 'px';
});
// Initial adjustment on page load
window.dispatchEvent(new Event('resize'));
4. μ£μ§ μΌμ΄μ€ λ° κ²½κ³ μ‘°κ±΄ μ²λ¦¬
μ€ν¬λ‘€ κ°λ₯ μμμ μμκ³Ό λμμ μ€ν¬λ‘€ μ€λ λμμ΄ μ΄λ»κ² μλν μ§ κ³ λ €νμμμ€. 첫 λ²μ§Έμ λ§μ§λ§ μμ΄ν μ΄ μ¬λ°λ₯΄κ² μ€λ λ κΉμ? μμλλ‘ μ€λ λλλ‘ μ²« λ²μ§Έμ λ§μ§λ§ μμ΄ν μ λ§μ§μ΄λ ν¨λ©μ μ‘°μ ν΄μΌ ν μλ μμ΅λλ€.
5. scroll-margin
μ μ¬μ©νμ¬ κ°λ³ μμ΄ν
μ€λ
ν¬μΈνΈ λ―ΈμΈ μ‘°μ νκΈ°.
scroll-paddingκ³Ό μ μ¬νκ², `scroll-margin`μ κ°λ³ μμ΄ν μ μ μ©νμ¬ μ€λ μμμ μ‘°μ ν μ μμ΅λλ€. μ΄λ νΉμ μμ΄ν μ΄ λ€λ₯Έ κ°κ²©μ κ°μ§κ±°λ κ³ μ ν μ‘°μ μ΄ νμν λ νΉν μ μ©ν μ μμ΅λλ€.
.scroll-item.special {
scroll-margin-left: 20px;
}
special
μμ΄ν
μ μ€λ
ν¬μΈνΈλ₯Ό μ€ν¬λ‘€ 컨ν
μ΄λμ μΌμͺ½ κ°μ₯μ리μμ 20pxλ§νΌ μ€νμ
ν©λλ€.
κ³ κΈ μ€ν¬λ‘€ μ€λ κΈ°μ
1. μ€μ²©λ μ€ν¬λ‘€ 컨ν μ΄λ
μ€ν¬λ‘€ 컨ν
μ΄λλ₯Ό μ€μ²©νμ¬ λ³΅μ‘ν μ€ν¬λ‘€ λ μ΄μμμ λ§λ€ μ μμ΅λλ€. μλ₯Ό λ€μ΄, κ° μμ΄ν
μ΄ μμ§μΌλ‘ μ€ν¬λ‘€λλ μ½ν
μΈ λ₯Ό ν¬ν¨νλ μν μ€ν¬λ‘€ 컨ν
μ΄λλ₯Ό κ°μ§ μ μμ΅λλ€. μΆ©λνλ μ€λ
λμμ νΌνκΈ° μν΄ κ° μ»¨ν
μ΄λμ λν΄ scroll-snap-type
μ΄ μ μ νκ² μ€μ λμλμ§ νμΈνμμμ€.
2. CSS νΈλμ€νΌκ³Ό μ€ν¬λ‘€ μ€λ κ²°ν©
μ€ν¬λ‘€ μ€λ
μ translate
, rotate
, scale
κ³Ό κ°μ CSS νΈλμ€νΌκ³Ό ν¨κ³Όμ μΌλ‘ κ²°ν©νμ¬ μκ°μ μΌλ‘ λ§€λ ₯μ μΈ μ€ν¬λ‘€ κ²½νμ λ§λ€ μ μμ΅λλ€. μλ₯Ό λ€μ΄, μμ΄ν
μ΄ λ·°μ μ€λ
λ λ ν¬κΈ°λ₯Ό μ‘°μ νκ±°λ νΉμ μ§μ μ μ§λ λ νμ μν¬ μ μμ΅λλ€.
3. μ¬μ©μ μ μ μ€λ ν¬μΈνΈ ꡬν
CSS μ€ν¬λ‘€ μ€λ μ μμ κ²½κ³λ₯Ό κΈ°λ°μΌλ‘ μλ μ€λ ν¬μΈνΈ κ°μ§λ₯Ό μ 곡νμ§λ§, μλ°μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νμ¬ μ¬μ©μ μ μ μ€λ ν¬μΈνΈλ₯Ό μ μν μλ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ μ€ν¬λ‘€ 컨ν μ΄λ λ΄μ μμμ μμΉμ μ€λ ν¬μΈνΈλ₯Ό λ§λ€ μ μμ΅λλ€.
μμ : μλ°μ€ν¬λ¦½νΈλ‘ μ¬μ©μ μ μ μ€λ ν¬μΈνΈ ꡬννκΈ°
const container = document.querySelector('.scroll-container');
const snapPoints = [100, 300, 500]; // Custom snap point positions
container.addEventListener('scroll', function() {
let closestSnapPoint = snapPoints.reduce((prev, curr) => {
return (Math.abs(curr - container.scrollLeft) < Math.abs(prev - container.scrollLeft) ? curr : prev);
});
// Optionally, animate the scroll to the closest snap point
// container.scrollTo({ left: closestSnapPoint, behavior: 'smooth' });
console.log('Closest snap point:', closestSnapPoint);
});
μ΄ μμ μμλ μ¬μ©μ μ μ μ€λ
ν¬μΈνΈ λ°°μ΄μ μ μν©λλ€. scroll
μ΄λ²€νΈ 리μ€λλ νμ¬ μ€ν¬λ‘€ μμΉμμ κ°μ₯ κ°κΉμ΄ μ€λ
ν¬μΈνΈλ₯Ό κ³μ°ν©λλ€. κ·Έλ° λ€μ behavior: 'smooth'
μ ν¨κ» scrollTo
λ₯Ό μ¬μ©νμ¬ ν΄λΉ μ€λ
ν¬μΈνΈλ‘ μ€ν¬λ‘€μ μ λλ©μ΄μ
νν μ μμ΅λλ€ (μ μμ μμλ μ£Όμ μ²λ¦¬λ¨).
4. μ κ·Όμ± κ³ λ € μ¬ν
μ€ν¬λ‘€ μ€λ μ μ¬μ©μ κ²½νμ ν₯μμν¬ μ μμ§λ§, μ κ·Όμ±μ λΆμ μ μΈ μν₯μ λ―ΈμΉμ§ μλλ‘ νλ κ²μ΄ μ€μν©λλ€. λ€μμ κ³ λ €νμμμ€.
- ν€λ³΄λ λ€λΉκ²μ΄μ : μ¬μ©μκ° ν€λ³΄λλ₯Ό μ¬μ©νμ¬ μ€ν¬λ‘€ κ°λ₯ν μ½ν μΈ λ₯Ό νμν μ μλμ§ νμΈνμμμ€. ν ν€λ‘ ν μ€νΈνμ¬ ν¬μ»€μ€κ° λ Όλ¦¬μ μΈ μμλ‘ μ΄λνλμ§ νμΈνμμμ€.
- μ€ν¬λ¦° 리λ νΈνμ±: μ€ν¬λ¦° 리λκ° μ€ν¬λ‘€ κ°λ₯ν μ½ν μΈ λ₯Ό μ¬λ°λ₯΄κ² ν΄μνκ³ μ μ ν νμ λ¨μλ₯Ό μ 곡νλμ§ νμΈνμμμ€.
- λμ μ€μ΄κΈ° μ νΈ: μ¬μ©μμ λμ μ€μ΄κΈ° μ νΈλλ₯Ό μ‘΄μ€νμμμ€. μ¬μ©μκ° μ€ν¬λ‘€ μ€λ
μ νΌλμ€λ½κ² λλλ€λ©΄ λΉνμ±νν μ μλ μ΅μ
μ μ 곡νμμμ€. μ΄λ CSSμ
prefers-reduced-motion
λ―Έλμ΄ μΏΌλ¦¬λ₯Ό μ¬μ©νκ±°λ μλ°μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νμ¬ μ€ν¬λ‘€ μ€λ κΈ°λ₯μ ν κΈν¨μΌλ‘μ¨ λ¬μ±ν μ μμ΅λλ€.
5. μ±λ₯ μ΅μ ν
μ€ν¬λ‘€ μ€λ μ νΉν μ²λ¦¬ λ₯λ ₯μ΄ μ νλ μ₯μΉμμ μ±λ₯μ μν₯μ μ€ μ μμ΅λλ€. μ±λ₯μ μ΅μ ννλ €λ©΄:
- μ§λμΉκ² 볡μ‘ν μ€ν¬λ‘€ μ€λ λ μ΄μμμ νΌνμμμ€. κ°λ₯ν κ²½μ° λμμΈμ λ¨μννμμμ€.
- νλμ¨μ΄ κ°μμ μ¬μ©νμμμ€.
transform: translate3d(0, 0, 0)
λλwill-change: scroll-position
κ³Ό κ°μ CSS μμ±μ μ μ©νμ¬ νλμ¨μ΄ κ°μμ μ΄μ§νμμμ€. - μ€ν¬λ‘€ μ΄λ²€νΈ 리μ€λλ₯Ό μ‘°μ (throttle)νμμμ€. μ¬μ©μ μ μ μ€λ
ν¬μΈνΈ ꡬνμ μν΄ μλ°μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νλ κ²½μ°,
scroll
μ΄λ²€νΈ 리μ€λλ₯Ό μ‘°μ νμ¬ κ³μ° λΉλλ₯Ό μ€μ΄μμμ€.
μ€μ μ¬λ‘ λ° μ¬μ© μ
CSS μ€ν¬λ‘€ μ€λ μ μ¬μ©μ κ²½νμ κ°μ νκΈ° μν΄ λ€μν λ§₯λ½μμ μ¬μ©λ μ μμ΅λλ€:
- μ΄λ―Έμ§ κ°€λ¬λ¦¬: κ° μ΄λ―Έμ§μ μ€λ λλ λΆλλ¬μ΄ μ€μμ΄ν κ°λ₯ν μ΄λ―Έμ§ κ°€λ¬λ¦¬λ₯Ό λ§λλλ€. μλ₯λ μμ νκ³Ό κ°μ μκ°μ μ νμ νλ§€νλ λ§μ μ μμκ±°λ μ¬μ΄νΈμμ μ΄λ₯Ό νμ©ν©λλ€.
- μ ν μΊλ¬μ : κ° μμ΄ν μ λν μ λ°ν μ€λ ν¬μΈνΈκ° μλ μΊλ¬μ νμμΌλ‘ μ νμ μ 보μ λλ€.
- λͺ¨λ°μΌ μ±κ³Ό μ μ¬ν λ€λΉκ²μ΄μ : μ νμ΄λ μλΉμ€λ₯Ό μ€λͺ νλ μΌλ ¨μ μ 체 νλ©΄ μΉμ κ³Ό κ°μ΄ λ€μ΄ν°λΈ λͺ¨λ°μΌ μ±μ λͺ¨λ°©ν μ 체 νμ΄μ§ μ€ν¬λ‘€ κ²½νμ ꡬνν©λλ€.
- λλ© νμ΄μ§ μΉμ : μνν μ νμΌλ‘ λλ© νμ΄μ§μ μ¬λ¬ μΉμ μ ν΅ν΄ μ¬μ©μλ₯Ό μλ΄ν©λλ€. μ΄λ μλΉμ€ν μννΈμ¨μ΄(SaaS) νμ¬ μΉμ¬μ΄νΈμμ νν λ³Ό μ μμ΅λλ€.
- κΈ°μ¬ νμ΄μ§λ€μ΄μ : λ μνΈμμ©μ μΈ λ μ κ²½νμ λ§λλλ€.
μμ : λͺ¨λ°μΌ μ±κ³Ό κ°μ μ 체 νμ΄μ§ μ€ν¬λ‘€ κ²½ν λ§λ€κΈ°.
body {
margin: 0;
overflow: hidden; /* Hide scrollbars */
}
.page-section {
width: 100vw;
height: 100vh;
scroll-snap-align: start;
display: flex; /* For vertical centering content */
justify-content: center;
align-items: center;
}
.scroll-container {
height: 100vh;
overflow-y: auto;
scroll-snap-type: y mandatory;
}
/* Optional: Add some styling to the sections */
.page-section:nth-child(odd) { background-color: #f0f0f0; }
.page-section:nth-child(even) { background-color: #e0e0e0; }
ν¬λ‘μ€ λΈλΌμ°μ νΈνμ±
CSS μ€ν¬λ‘€ μ€λ
μ ν¬λ‘¬, νμ΄μ΄νμ€, μ¬ν리, μ£μ§λ₯Ό ν¬ν¨ν μ΅μ λΈλΌμ°μ μ λ°μ κ±Έμ³ μ’μ ν¬λ‘μ€ λΈλΌμ°μ νΈνμ±μ 보μ
λλ€. κ·Έλ¬λ μΌκ΄λ λμμ 보μ₯νκΈ° μν΄ λ€λ₯Έ λΈλΌμ°μ μ μ₯μΉμμ ꡬνμ ν
μ€νΈνλ κ²μ΄ νμ μ’μ μ΅κ΄μ
λλ€. λ λμ μ§μμ μ 곡νκΈ° μν΄ μ΄μ λΈλΌμ°μ λ²μ μ λν΄ λ²€λ μ λμ¬(μ: -webkit-
) μ¬μ©μ κ³ λ €ν μ μμ§λ§, μ΄λ μ μ λ νμν΄μ§κ³ μμ΅λλ€. μ°Έκ³ λ‘ κ΅¬λ²μ μ μΈν°λ· μ΅μ€νλ‘λ¬λ CSS μ€ν¬λ‘€ μ€λ
μ κΈ°λ³Έμ μΌλ‘ μ§μνμ§ μμ΅λλ€.
κ²°λ‘
CSS μ€ν¬λ‘€ μ€λ μ μ§κ΄μ μ΄κ³ μκ°μ μΌλ‘ λ§€λ ₯μ μΈ μ€ν¬λ‘€ κ²½νμ λ§λλ λ° μ μ©ν λꡬμ λλ€. ν΅μ¬ μμ±μ λ§μ€ν°νκ³ , μ€λ ν¬μΈνΈ μ νλλ₯Ό λ―ΈμΈ μ‘°μ νλ©°, μ κ·Όμ± λ° μ±λ₯ μν₯μ κ³ λ €ν¨μΌλ‘μ¨ μ€ν¬λ‘€ μ€λ μ νμ©νμ¬ μΉ μ ν리μΌμ΄μ μ ν₯μμν€κ³ μ°μν μ¬μ©μ μΈν°νμ΄μ€λ₯Ό μ 곡ν μ μμ΅λλ€. μ΄ κΈ°μ¬μμ λ Όμλ κΈ°μ μ μ€ννμ¬ CSS μ€ν¬λ‘€ μ€λ μ λͺ¨λ μ μ¬λ ₯μ λ°ννκ³ μ§μ μΌλ‘ λ§€λ ₯μ μΈ μ€ν¬λ‘€ μνΈμμ©μ λ§λ€μ΄ 보μμμ€.