1+ // 1. Scrolling shadows are implemented as pseudo elements. This way we can customise them only
2+ // with custom properties.
3+ // 2. Stack scrolling shadows over viewport content while keeping the content interactive.
4+ //
5+ // - `.scrollingShadows` is positioned absolutely over the `.root`, with auto `z-index` (this is
6+ // important!), and with `overflow: hidden` to clip the shadows (ie. its pseudo elements).
7+ // - The `.viewport` is in `.root`'s stacking context and remains interactive because its
8+ // `z-index` is higher than the auto `z-index` of `.scrollingShadows`.
9+ //
10+ // 3. Optional arrows are positioned relative to the `.root` and stacked on top of scrolling
11+ // shadows. They can be shifted outside the `ScrollView` area only because `overflow: hidden` is
12+ // **not** present at `.root`.
13+ //
14+ // 4. Make the `.content`'s bounding rectangle spread beyond the part visible through `.viewport`.
15+ // 5. Prevent undesired vertical scrolling that may occur with tables inside.
16+ // 6. Make `ScrollView` adjust to flexible layouts.
17+
118@import ' ../../../styles/tools/caret' ;
219@import ' ../../../styles/tools/hide-scrollbar' ;
320@import ' ../../../styles/tools/reset' ;
421@import ' ../../../styles/tools/transitions' ;
522@import ' theme' ;
623
7- // 1. Scrolling shadows are implemented as pseudo elements. This way we can customise them only
8- // thanks to custom properties.
9- // 2. Clip scrolling shadows.
10- // 3. Create stacking context just to avoid scrolling shadows being covered by content.
11- // 4. Make the content bounding rectangle spread beyond the visible part.
12- // 5. Prevent undesired vertical scrolling that may occur with tables inside.
13-
1424$_arrow-inner-offset : 0.5rem ;
1525$_arrow-outer-offset : 1rem ;
1626
1727.root {
18- position : relative ;
28+ position : relative ; // 2.
1929 display : flex ;
2030 flex-direction : column ;
2131 width : 100% ;
32+ }
33+
34+ // 1.
35+ .scrollingShadows {
36+ position : absolute ; // 2.
37+ width : 100% ; // 2.
38+ height : 100% ; // 2.
2239 overflow : hidden ; // 2.
2340
24- // 1.
2541 & ::before ,
2642 & ::after {
2743 @include transition ((visibility , opacity , transform ));
2844
2945 content : ' ' ;
3046 position : absolute ;
31- z-index : 1 ;
47+ z-index : 2 ; // 2.
3248 display : block ;
3349 visibility : hidden ;
3450 opacity : 0 ;
@@ -48,7 +64,7 @@ $_arrow-outer-offset: 1rem;
4864}
4965
5066.viewport {
51- position : relative ; // 3 .
67+ z-index : 1 ; // 2 .
5268 width : 100% ;
5369 scroll-behavior : smooth ;
5470 -webkit-overflow-scrolling : touch ;
@@ -59,8 +75,8 @@ $_arrow-outer-offset: 1rem;
5975 @include reset-button ();
6076 @include transition ((visibility , opacity , transform ));
6177
62- position : absolute ;
63- z-index : 2 ;
78+ position : absolute ; // 3.
79+ z-index : 3 ; // 3.
6480 display : flex ;
6581 visibility : hidden ;
6682 opacity : 0 ;
@@ -75,11 +91,12 @@ $_arrow-outer-offset: 1rem;
7591
7692.isRootVertical {
7793 height : 100% ;
94+ min-height : 0 ; // 6.
7895}
7996
8097.isRootVertical .viewport {
8198 height : 100% ;
82- overflow-y : auto ;
99+ overflow-y : auto ; // 2.
83100}
84101
85102.isRootVertical .arrowPrev {
@@ -106,6 +123,10 @@ $_arrow-outer-offset: 1rem;
106123 transform : translateY (calc (-1 * #{$scrollview-arrow-initial-offset } ));
107124}
108125
126+ .isRootHorizontal {
127+ min-width : 0 ; // 6.
128+ }
129+
109130.isRootHorizontal .arrowPrev {
110131 top : 0 ;
111132 bottom : 0 ;
@@ -132,24 +153,24 @@ $_arrow-outer-offset: 1rem;
132153 @include caret-rotate (270 );
133154}
134155
135- .isRootVertical ::before ,
136- .isRootVertical ::after {
156+ .isRootVertical .scrollingShadows ::before ,
157+ .isRootVertical .scrollingShadows ::after {
137158 right : 0 ;
138159 left : 0 ;
139160}
140161
141- .isRootVertical ::before {
162+ .isRootVertical .scrollingShadows ::before {
142163 top : 0 ;
143164 transform : translateY ($scrollview-shadow-initial-offset );
144165}
145166
146- .isRootVertical ::after {
167+ .isRootVertical .scrollingShadows ::after {
147168 bottom : 0 ;
148169 transform : translateY (calc (-1 * #{$scrollview-shadow-initial-offset } ));
149170}
150171
151172.isRootHorizontal .viewport {
152- overflow-x : auto ;
173+ overflow-x : auto ; // 2.
153174 overflow-y : hidden ; // 5.
154175}
155176
@@ -158,30 +179,30 @@ $_arrow-outer-offset: 1rem;
158179 min-width : 100% ;
159180}
160181
161- .isRootHorizontal ::before ,
162- .isRootHorizontal ::after {
182+ .isRootHorizontal .scrollingShadows ::before ,
183+ .isRootHorizontal .scrollingShadows ::after {
163184 top : 0 ;
164185 bottom : 0 ;
165186}
166187
167- .isRootHorizontal ::before {
188+ .isRootHorizontal .scrollingShadows ::before {
168189 left : 0 ;
169190 transform : translateX ($scrollview-shadow-initial-offset );
170191}
171192
172- .isRootHorizontal ::after {
193+ .isRootHorizontal .scrollingShadows ::after {
173194 right : 0 ;
174195 transform : translateX (calc (-1 * #{$scrollview-shadow-initial-offset } ));
175196}
176197
177- .isRootScrolledAtStart ::before ,
198+ .isRootScrolledAtStart .scrollingShadows ::before ,
178199.isRootScrolledAtStart .arrowPrev {
179200 visibility : visible ;
180201 opacity : 1 ;
181202 transform : translate (0 , 0 );
182203}
183204
184- .isRootScrolledAtEnd ::after ,
205+ .isRootScrolledAtEnd .scrollingShadows ::after ,
185206.isRootScrolledAtEnd .arrowNext {
186207 visibility : visible ;
187208 opacity : 1 ;
0 commit comments