uikit 3.10.2-dev.c8aa7eda2 → 3.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +35 -14
  2. package/build/icons.js +4 -4
  3. package/build/scope.js +4 -6
  4. package/dist/css/uikit-core-rtl.css +10 -1
  5. package/dist/css/uikit-core-rtl.min.css +1 -1
  6. package/dist/css/uikit-core.css +10 -1
  7. package/dist/css/uikit-core.min.css +1 -1
  8. package/dist/css/uikit-rtl.css +10 -1
  9. package/dist/css/uikit-rtl.min.css +1 -1
  10. package/dist/css/uikit.css +10 -1
  11. package/dist/css/uikit.min.css +1 -1
  12. package/dist/js/components/countdown.js +1 -1
  13. package/dist/js/components/countdown.min.js +1 -1
  14. package/dist/js/components/filter.js +1 -1
  15. package/dist/js/components/filter.min.js +1 -1
  16. package/dist/js/components/lightbox-panel.js +1 -1
  17. package/dist/js/components/lightbox-panel.min.js +1 -1
  18. package/dist/js/components/lightbox.js +1 -1
  19. package/dist/js/components/lightbox.min.js +1 -1
  20. package/dist/js/components/notification.js +1 -1
  21. package/dist/js/components/notification.min.js +1 -1
  22. package/dist/js/components/parallax.js +257 -264
  23. package/dist/js/components/parallax.min.js +1 -1
  24. package/dist/js/components/slider-parallax.js +215 -257
  25. package/dist/js/components/slider-parallax.min.js +1 -1
  26. package/dist/js/components/slider.js +1 -1
  27. package/dist/js/components/slider.min.js +1 -1
  28. package/dist/js/components/slideshow-parallax.js +215 -257
  29. package/dist/js/components/slideshow-parallax.min.js +1 -1
  30. package/dist/js/components/slideshow.js +1 -1
  31. package/dist/js/components/slideshow.min.js +1 -1
  32. package/dist/js/components/sortable.js +1 -1
  33. package/dist/js/components/sortable.min.js +1 -1
  34. package/dist/js/components/tooltip.js +1 -1
  35. package/dist/js/components/tooltip.min.js +1 -1
  36. package/dist/js/components/upload.js +1 -1
  37. package/dist/js/components/upload.min.js +1 -1
  38. package/dist/js/uikit-core.js +28 -26
  39. package/dist/js/uikit-core.min.js +1 -1
  40. package/dist/js/uikit-icons.js +1 -1
  41. package/dist/js/uikit-icons.min.js +1 -1
  42. package/dist/js/uikit.js +284 -289
  43. package/dist/js/uikit.min.js +1 -1
  44. package/package.json +5 -5
  45. package/src/js/components/parallax.js +38 -8
  46. package/src/js/core/grid.js +2 -2
  47. package/src/js/core/svg.js +9 -7
  48. package/src/js/mixin/parallax.js +209 -242
  49. package/src/js/util/dimensions.js +4 -2
  50. package/src/js/util/viewport.js +9 -13
  51. package/src/less/components/position.less +2 -0
  52. package/src/less/components/sticky.less +6 -0
  53. package/src/scss/components/position.scss +2 -0
  54. package/src/scss/components/sticky.scss +6 -0
  55. package/tests/index.html +1 -1
  56. package/tests/js/index.js +1 -1
  57. package/tests/notification.html +5 -5
  58. package/tests/parallax.html +66 -50
  59. package/tests/sticky-parallax.html +274 -0
  60. package/tests/sticky.html +2 -2
  61. package/tests/tab.html +1 -1
@@ -1,333 +1,300 @@
1
1
  import Media from '../mixin/media';
2
2
  import {getMaxPathLength} from '../core/svg';
3
- import {css, Dimensions, each, isNumber, isString, isUndefined, startsWith, toFloat, toPx, ucfirst} from 'uikit-util';
3
+ import {css, Dimensions, each, isNumber, isString, isUndefined, noop, startsWith, toFloat, toPx, ucfirst} from 'uikit-util';
4
+
5
+ const props = {
6
+ x: transformFn,
7
+ y: transformFn,
8
+ rotate: transformFn,
9
+ scale: transformFn,
10
+ color: colorFn,
11
+ backgroundColor: colorFn,
12
+ borderColor: colorFn,
13
+ blur: filterFn,
14
+ hue: filterFn,
15
+ fopacity: filterFn,
16
+ grayscale: filterFn,
17
+ invert: filterFn,
18
+ saturate: filterFn,
19
+ sepia: filterFn,
20
+ opacity: cssPropFn,
21
+ stroke: strokeFn,
22
+ bgx: backgroundFn,
23
+ bgy: backgroundFn
24
+ };
4
25
 
5
- const props = ['x', 'y', 'bgx', 'bgy', 'rotate', 'scale', 'color', 'backgroundColor', 'borderColor', 'opacity', 'blur', 'hue', 'grayscale', 'invert', 'saturate', 'sepia', 'fopacity', 'stroke'];
26
+ const {keys} = Object;
6
27
 
7
28
  export default {
8
29
 
9
30
  mixins: [Media],
10
31
 
11
- props: props.reduce((props, prop) => {
12
- props[prop] = 'list';
13
- return props;
14
- }, {}),
32
+ props: fillObject(keys(props), 'list'),
15
33
 
16
- data: props.reduce((data, prop) => {
17
- data[prop] = undefined;
18
- return data;
19
- }, {}),
34
+ data: fillObject(keys(props), undefined),
20
35
 
21
36
  computed: {
22
37
 
23
38
  props(properties, $el) {
24
-
25
- return props.reduce((props, prop) => {
26
-
27
- if (isUndefined(properties[prop])) {
28
- return props;
39
+ return keys(props).reduce((result, prop) => {
40
+ if (!isUndefined(properties[prop])) {
41
+ result[prop] = props[prop].call(this, prop, $el, properties[prop].slice());
29
42
  }
43
+ return result;
44
+ }, {});
45
+ }
30
46
 
31
- const isColor = prop.match(/color/i);
32
- const isCssProp = isColor || prop === 'opacity';
33
-
34
- let pos, bgPos, diff;
35
- let steps = properties[prop].slice();
36
-
37
- if (isCssProp) {
38
- css($el, prop, '');
39
- }
40
-
41
- if (steps.length < 2) {
42
- steps.unshift((prop === 'scale'
43
- ? 1
44
- : isCssProp
45
- ? css($el, prop)
46
- : 0) || 0);
47
- }
48
-
49
- const unit = getUnit(steps, prop);
50
-
51
- if (isColor) {
52
-
53
- const {color} = $el.style;
54
- steps = steps.map(step => parseColor($el, step));
55
- $el.style.color = color;
47
+ },
56
48
 
57
- } else if (startsWith(prop, 'bg')) {
49
+ methods: {
58
50
 
59
- const attr = prop === 'bgy' ? 'height' : 'width';
60
- steps = steps.map(step => toPx(step, attr, $el));
51
+ reset() {
52
+ each(this.getCss(0), (_, prop) => css(this.$el, prop, ''));
53
+ },
61
54
 
62
- css($el, `background-position-${prop[2]}`, '');
63
- bgPos = css($el, 'backgroundPosition').split(' ')[prop[2] === 'x' ? 0 : 1]; // IE 11 can't read background-position-[x|y]
55
+ getCss(percent) {
56
+ return keys(this.props).reduce((css, prop) => {
57
+ this.props[prop](css, percent);
58
+ return css;
59
+ }, {transform: '', filter: ''});
60
+ }
64
61
 
65
- if (this.covers) {
62
+ }
66
63
 
67
- const min = Math.min(...steps);
68
- const max = Math.max(...steps);
69
- const down = steps.indexOf(min) < steps.indexOf(max);
64
+ };
70
65
 
71
- diff = max - min;
66
+ function transformFn(prop, el, steps) {
72
67
 
73
- steps = steps.map(step => step - (down ? min : max));
74
- pos = `${down ? -diff : 0}px`;
68
+ const unit = getUnit(steps) || {x: 'px', y: 'px', rotate: 'deg'}[prop] || '';
75
69
 
76
- } else {
70
+ if (prop === 'x' || prop === 'y') {
71
+ prop = `translate${ucfirst(prop)}`;
72
+ }
77
73
 
78
- pos = bgPos;
74
+ steps = steps.map(toFloat);
79
75
 
80
- }
76
+ if (steps.length === 1) {
77
+ steps.unshift(prop === 'scale' ? 1 : 0);
78
+ }
81
79
 
82
- } else {
80
+ return (css, percent) => {
81
+ let value = getValue(steps, percent);
83
82
 
84
- steps = steps.map(toFloat);
83
+ if (startsWith(prop, 'translate')) {
84
+ value = toFloat(value).toFixed(unit === 'px' ? 0 : 6);
85
+ }
85
86
 
86
- }
87
+ css.transform += ` ${prop}(${value}${unit})`;
88
+ };
89
+ }
87
90
 
88
- if (prop === 'stroke') {
91
+ function colorFn(prop, el, steps) {
89
92
 
90
- if (!steps.some(step => step)) {
91
- return props;
92
- }
93
+ if (steps.length === 1) {
94
+ steps.unshift(getCssValue(el, prop, ''));
95
+ }
93
96
 
94
- const length = getMaxPathLength($el);
95
- css($el, 'strokeDasharray', length);
97
+ steps = steps.map(step => parseColor(el, step));
96
98
 
97
- if (unit === '%') {
98
- steps = steps.map(step => step * length / 100);
99
- }
99
+ return (css, percent) => {
100
100
 
101
- steps = steps.reverse();
101
+ const [start, end, p] = getStep(steps, percent);
102
+ const value = start.map((value, i) => {
103
+ value += p * (end[i] - value);
104
+ return i === 3 ? toFloat(value) : parseInt(value, 10);
105
+ }).join(',');
106
+ css[prop] = `rgba(${value})`;
107
+ };
108
+ }
102
109
 
103
- prop = 'strokeDashoffset';
104
- }
110
+ function parseColor(el, color) {
111
+ return getCssValue(el, 'color', color)
112
+ .split(/[(),]/g)
113
+ .slice(1, -1)
114
+ .concat(1)
115
+ .slice(0, 4)
116
+ .map(toFloat);
117
+ }
105
118
 
106
- props[prop] = {steps, unit, pos, bgPos, diff};
119
+ function filterFn(prop, el, steps) {
107
120
 
108
- return props;
121
+ if (steps.length === 1) {
122
+ steps.unshift(0);
123
+ }
109
124
 
110
- }, {});
125
+ const unit = getUnit(steps) || {blur: 'px', hue: 'deg'}[prop] || '%';
126
+ prop = {fopacity: 'opacity', hue: 'hue-rotate'}[prop] || prop;
127
+ steps = steps.map(toFloat);
111
128
 
112
- },
129
+ return (css, percent) => {
130
+ const value = getValue(steps, percent);
131
+ css.filter += ` ${prop}(${value + unit})`;
132
+ };
133
+ }
113
134
 
114
- bgProps() {
115
- return ['bgx', 'bgy'].filter(bg => bg in this.props);
116
- },
135
+ function cssPropFn(prop, el, steps) {
117
136
 
118
- covers(_, $el) {
119
- return covers($el);
120
- }
137
+ if (steps.length === 1) {
138
+ steps.unshift(getCssValue(el, prop, ''));
139
+ }
121
140
 
122
- },
141
+ steps = steps.map(toFloat);
123
142
 
124
- disconnected() {
125
- delete this._image;
126
- },
143
+ return (css, percent) => {
144
+ css[prop] = getValue(steps, percent);
145
+ };
146
+ }
127
147
 
128
- update: {
148
+ function strokeFn(prop, el, steps) {
129
149
 
130
- read(data) {
150
+ if (steps.length === 1) {
151
+ steps.unshift(0);
152
+ }
131
153
 
132
- if (!this.matchMedia) {
133
- return;
134
- }
154
+ const unit = getUnit(steps);
155
+ steps = steps.map(toFloat);
135
156
 
136
- if (!data.image && this.covers && this.bgProps.length) {
137
- const src = css(this.$el, 'backgroundImage').replace(/^none|url\(["']?(.+?)["']?\)$/, '$1');
157
+ if (!steps.some(step => step)) {
158
+ return noop;
159
+ }
138
160
 
139
- if (src) {
140
- const img = new Image();
141
- img.src = src;
142
- data.image = img;
161
+ const length = getMaxPathLength(el);
162
+ css(el, 'strokeDasharray', length);
143
163
 
144
- if (!img.naturalWidth) {
145
- img.onload = () => this.$update();
146
- }
147
- }
164
+ if (unit === '%') {
165
+ steps = steps.map(step => step * length / 100);
166
+ }
148
167
 
149
- }
168
+ steps = steps.reverse();
150
169
 
151
- const {image} = data;
170
+ return (css, percent) => {
171
+ css.strokeDashoffset = getValue(steps, percent);
172
+ };
173
+ }
152
174
 
153
- if (!image || !image.naturalWidth) {
154
- return;
155
- }
175
+ function backgroundFn(prop, el, steps) {
156
176
 
157
- const dimEl = {
158
- width: this.$el.offsetWidth,
159
- height: this.$el.offsetHeight
160
- };
161
- const dimImage = {
162
- width: image.naturalWidth,
163
- height: image.naturalHeight
164
- };
177
+ if (steps.length === 1) {
178
+ steps.unshift(0);
179
+ }
165
180
 
166
- let dim = Dimensions.cover(dimImage, dimEl);
181
+ prop = prop.substr(-1);
182
+ const attr = prop === 'y' ? 'height' : 'width';
183
+ steps = steps.map(step => toPx(step, attr, el));
167
184
 
168
- this.bgProps.forEach(prop => {
185
+ css(el, `background-position-${prop}`, '');
186
+ const bgPos = css(el, 'backgroundPosition').split(' ')[prop === 'x' ? 0 : 1]; // IE 11 can't read background-position-[x|y]
169
187
 
170
- const {diff, bgPos, steps} = this.props[prop];
171
- const attr = prop === 'bgy' ? 'height' : 'width';
172
- const span = dim[attr] - dimEl[attr];
188
+ return getCssValue(el, 'backgroundSize', '') === 'cover'
189
+ ? backgroundCoverFn.call(this, prop, el, steps, bgPos, attr)
190
+ : setBackgroundPosFn(prop, steps, bgPos);
191
+ }
173
192
 
174
- if (span < diff) {
175
- dimEl[attr] = dim[attr] + diff - span;
176
- } else if (span > diff) {
193
+ function backgroundCoverFn(prop, el, steps, bgPos, attr) {
177
194
 
178
- const posPercentage = dimEl[attr] / toPx(bgPos, attr, this.$el);
195
+ const image = getBackgroundImage.call(this, el);
179
196
 
180
- if (posPercentage) {
181
- this.props[prop].steps = steps.map(step => step - (span - diff) / posPercentage);
182
- }
183
- }
197
+ if (!image.naturalWidth) {
198
+ return noop;
199
+ }
184
200
 
185
- dim = Dimensions.cover(dimImage, dimEl);
186
- });
201
+ const min = Math.min(...steps);
202
+ const max = Math.max(...steps);
203
+ const down = steps.indexOf(min) < steps.indexOf(max);
187
204
 
188
- data.dim = dim;
189
- },
205
+ const diff = max - min;
206
+ let pos = (down ? -diff : 0) - (down ? min : max);
190
207
 
191
- write({dim}) {
208
+ const dimEl = {
209
+ width: el.offsetWidth,
210
+ height: el.offsetHeight
211
+ };
192
212
 
193
- if (!this.matchMedia) {
194
- css(this.$el, {backgroundSize: '', backgroundRepeat: ''});
195
- return;
196
- }
213
+ const dimImage = {
214
+ width: image.naturalWidth,
215
+ height: image.naturalHeight
216
+ };
197
217
 
198
- dim && css(this.$el, {
199
- backgroundSize: `${dim.width}px ${dim.height}px`,
200
- backgroundRepeat: 'no-repeat'
201
- });
218
+ const baseDim = Dimensions.cover(dimImage, dimEl);
219
+ const span = baseDim[attr] - dimEl[attr];
202
220
 
203
- },
221
+ if (span < diff) {
222
+ dimEl[attr] = baseDim[attr] + diff - span;
223
+ } else if (span > diff) {
204
224
 
205
- events: ['resize']
225
+ const posPercentage = dimEl[attr] / toPx(bgPos, attr, el, true);
206
226
 
207
- },
227
+ if (posPercentage) {
228
+ pos -= (span - diff) / posPercentage;
229
+ }
230
+ }
208
231
 
209
- methods: {
232
+ const dim = Dimensions.cover(dimImage, dimEl);
210
233
 
211
- reset() {
212
- each(this.getCss(0), (_, prop) => css(this.$el, prop, ''));
213
- },
234
+ const fn = setBackgroundPosFn(prop, steps, `${pos}px`);
235
+ return (css, percent) => {
236
+ fn(css, percent);
237
+ css.backgroundSize = `${dim.width}px ${dim.height}px`;
238
+ css.backgroundRepeat = 'no-repeat';
239
+ };
240
+ }
214
241
 
215
- getCss(percent) {
242
+ function setBackgroundPosFn(prop, steps, pos) {
243
+ return function (css, percent) {
244
+ css[`background-position-${prop}`] = `calc(${pos} + ${getValue(steps, percent)}px)`;
245
+ };
246
+ }
216
247
 
217
- const {props} = this;
218
- return Object.keys(props).reduce((css, prop) => {
219
-
220
- let {steps, unit, pos} = props[prop];
221
- const value = getValue(steps, percent);
222
-
223
- switch (prop) {
224
-
225
- // transforms
226
- case 'x':
227
- case 'y': {
228
- unit = unit || 'px';
229
- css.transform += ` translate${ucfirst(prop)}(${
230
- toFloat(value).toFixed(unit === 'px' ? 0 : 2)
231
- }${unit})`;
232
- break;
233
- }
234
- case 'rotate':
235
- unit = unit || 'deg';
236
- css.transform += ` rotate(${value + unit})`;
237
- break;
238
- case 'scale':
239
- css.transform += ` scale(${value})`;
240
- break;
241
-
242
- // bg image
243
- case 'bgy':
244
- case 'bgx':
245
- css[`background-position-${prop[2]}`] = `calc(${pos} + ${value}px)`;
246
- break;
247
-
248
- // color
249
- case 'color':
250
- case 'backgroundColor':
251
- case 'borderColor': {
252
-
253
- const [start, end, p] = getStep(steps, percent);
254
-
255
- css[prop] = `rgba(${
256
- start.map((value, i) => {
257
- value += p * (end[i] - value);
258
- return i === 3 ? toFloat(value) : parseInt(value, 10);
259
- }).join(',')
260
- })`;
261
- break;
262
- }
263
- // CSS Filter
264
- case 'blur':
265
- unit = unit || 'px';
266
- css.filter += ` blur(${value + unit})`;
267
- break;
268
- case 'hue':
269
- unit = unit || 'deg';
270
- css.filter += ` hue-rotate(${value + unit})`;
271
- break;
272
- case 'fopacity':
273
- unit = unit || '%';
274
- css.filter += ` opacity(${value + unit})`;
275
- break;
276
- case 'grayscale':
277
- case 'invert':
278
- case 'saturate':
279
- case 'sepia':
280
- unit = unit || '%';
281
- css.filter += ` ${prop}(${value + unit})`;
282
- break;
283
- default:
284
- css[prop] = value;
285
- }
248
+ function getBackgroundImage(el) {
249
+ const src = css(el, 'backgroundImage').replace(/^none|url\(["']?(.+?)["']?\)$/, '$1');
286
250
 
287
- return css;
251
+ const data = this._data;
288
252
 
289
- }, {transform: '', filter: ''});
253
+ if (data[src]) {
254
+ return data[src];
255
+ }
290
256
 
257
+ if (src) {
258
+ const img = new Image();
259
+ img.src = src;
260
+ if (!img.naturalWidth) {
261
+ img.onload = () => this.$update();
291
262
  }
292
263
 
264
+ return data[src] = img;
293
265
  }
294
-
295
- };
296
-
297
- function parseColor(el, color) {
298
- return css(css(el, 'color', color), 'color')
299
- .split(/[(),]/g)
300
- .slice(1, -1)
301
- .concat(1)
302
- .slice(0, 4)
303
- .map(toFloat);
304
266
  }
305
267
 
306
268
  function getStep(steps, percent) {
307
269
  const count = steps.length - 1;
308
270
  const index = Math.min(Math.floor(count * percent), count - 1);
309
- const step = steps.slice(index, index + 2);
310
-
311
- step.push(percent === 1 ? 1 : percent % (1 / count) * count);
312
271
 
313
- return step;
272
+ return steps
273
+ .slice(index, index + 2)
274
+ .concat(percent === 1 ? 1 : percent % (1 / count) * count);
314
275
  }
315
276
 
316
- function getValue(steps, percent, digits = 2) {
277
+ function getValue(steps, percent) {
317
278
  const [start, end, p] = getStep(steps, percent);
318
- return (isNumber(start)
279
+ return isNumber(start)
319
280
  ? start + Math.abs(start - end) * p * (start < end ? 1 : -1)
320
- : +end
321
- ).toFixed(digits);
281
+ : +end;
322
282
  }
323
283
 
324
- function getUnit(steps) {
325
- return steps.reduce((unit, step) => isString(step) && step.replace(/-|\d/g, '').trim() || unit, '');
284
+ function getUnit(steps, defaultUnit) {
285
+ return steps.reduce((unit, step) => unit || isString(step) && step.replace(/[\d-]/g, '').trim(), '') || defaultUnit;
326
286
  }
327
287
 
328
- function covers(el) {
329
- const {backgroundSize} = el.style;
330
- const covers = css(css(el, 'backgroundSize', ''), 'backgroundSize') === 'cover';
331
- el.style.backgroundSize = backgroundSize;
332
- return covers;
288
+ function getCssValue(el, prop, value) {
289
+ const prev = el.style[prop];
290
+ const val = css(css(el, prop, value), prop);
291
+ el.style[prop] = prev;
292
+ return val;
293
+ }
294
+
295
+ function fillObject(keys, value) {
296
+ return keys.reduce((data, prop) => {
297
+ data[prop] = value;
298
+ return data;
299
+ }, {});
333
300
  }
@@ -156,7 +156,7 @@ export function flipPosition(pos) {
156
156
  return pos;
157
157
  }
158
158
 
159
- export function toPx(value, property = 'width', element = window) {
159
+ export function toPx(value, property = 'width', element = window, offsetDim = false) {
160
160
  return isNumeric(value)
161
161
  ? +value
162
162
  : endsWith(value, 'vh')
@@ -164,7 +164,9 @@ export function toPx(value, property = 'width', element = window) {
164
164
  : endsWith(value, 'vw')
165
165
  ? percent(width(toWindow(element)), value)
166
166
  : endsWith(value, '%')
167
- ? percent(dimensions(element)[property], value)
167
+ ? percent(offsetDim
168
+ ? element[`offset${ucfirst(property)}`]
169
+ : dimensions(element)[property], value)
168
170
  : toFloat(value);
169
171
  }
170
172
 
@@ -102,7 +102,7 @@ export function scrollIntoView(element, {offset: offsetBy = 0} = {}) {
102
102
 
103
103
  }
104
104
 
105
- export function scrolledOver(element, heightOffset = 0) {
105
+ export function scrolledOver(element, startOffset = 0, endOffset = 0) {
106
106
 
107
107
  if (!isVisible(element)) {
108
108
  return 0;
@@ -110,18 +110,14 @@ export function scrolledOver(element, heightOffset = 0) {
110
110
 
111
111
  const [scrollElement] = scrollParents(element, /auto|scroll/, true);
112
112
  const {scrollHeight, scrollTop} = scrollElement;
113
- const clientHeight = getViewportClientHeight(scrollElement);
114
- const viewportTop = offsetPosition(element)[0] - scrollTop - offsetPosition(scrollElement)[0];
115
- const viewportDist = Math.min(clientHeight, viewportTop + scrollTop);
116
-
117
- const top = viewportTop - viewportDist;
118
- const dist = Math.min(
119
- element.offsetHeight + heightOffset + viewportDist,
120
- scrollHeight - (viewportTop + scrollTop),
121
- scrollHeight - clientHeight
122
- );
123
-
124
- return clamp(-1 * top / dist);
113
+ const viewportHeight = getViewportClientHeight(scrollElement);
114
+ const maxScroll = scrollHeight - viewportHeight;
115
+ const elementOffsetTop = offsetPosition(element)[0] - offsetPosition(scrollElement)[0];
116
+
117
+ const start = Math.max(0, elementOffsetTop - viewportHeight + startOffset);
118
+ const end = Math.min(maxScroll, elementOffsetTop + element.offsetHeight - endOffset);
119
+
120
+ return clamp((scrollTop - start) / (end - start));
125
121
  }
126
122
 
127
123
  export function scrollParents(element, overflowRe = /auto|scroll|hidden/, scrollable = false) {
@@ -219,6 +219,8 @@
219
219
 
220
220
  .uk-position-z-index { z-index: 1; }
221
221
 
222
+ .uk-position-z-index-negative { z-index: -1; }
223
+
222
224
 
223
225
  // Hooks
224
226
  // ========================================================================
@@ -23,6 +23,12 @@
23
23
  Component: Sticky
24
24
  ========================================================================== */
25
25
 
26
+ /*
27
+ * Create position context so it's t the same like when fixed.
28
+ */
29
+
30
+ .uk-sticky { position: relative; }
31
+
26
32
  /*
27
33
  * 1. Force new layer to resolve frame rate issues on devices with lower frame rates
28
34
  */
@@ -219,6 +219,8 @@ $position-large-margin-l: 50px !default;
219
219
 
220
220
  .uk-position-z-index { z-index: 1; }
221
221
 
222
+ .uk-position-z-index-negative { z-index: -1; }
223
+
222
224
 
223
225
  // Hooks
224
226
  // ========================================================================
@@ -23,6 +23,12 @@ $sticky-reverse-animation-duration: 0.2s !default;
23
23
  Component: Sticky
24
24
  ========================================================================== */
25
25
 
26
+ /*
27
+ * Create position context so it's t the same like when fixed.
28
+ */
29
+
30
+ .uk-sticky { position: relative; }
31
+
26
32
  /*
27
33
  * 1. Force new layer to resolve frame rate issues on devices with lower frame rates
28
34
  */
package/tests/index.html CHANGED
@@ -598,7 +598,7 @@
598
598
  <li><a href="#" uk-icon="icon: pencil"></a></li>
599
599
  <li><a href="#"><span uk-icon="icon: bag"></span> (2)</a></li>
600
600
  </ul>
601
-
601
+
602
602
  </div>
603
603
  </div>
604
604
 
package/tests/js/index.js CHANGED
@@ -63,7 +63,7 @@ on(window, 'load', () => setTimeout(() => fastdom.write(() => {
63
63
  ${Object.keys(styles).map(style => `<option value="${style}">${ucfirst(style)}</option>`).join('')}
64
64
  </select>
65
65
  <select class="uk-select uk-form-width-small" style="margin: 20px">
66
- ${Object.keys(variations).map(name => `<option value="${name}">${variations[name]}</option>`).join('')}
66
+ ${Object.keys(variations).map(name => `<option value="${name}">${variations[name]}</option>`).join('')}
67
67
  </select>
68
68
  <label style="margin: 20px">
69
69
  <input type="checkbox" class="uk-checkbox"/>