uikit 3.11.1 → 3.11.2-dev.19d26d0f9

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 (53) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/css/uikit-core-rtl.css +1 -1
  3. package/dist/css/uikit-core-rtl.min.css +1 -1
  4. package/dist/css/uikit-core.css +1 -1
  5. package/dist/css/uikit-core.min.css +1 -1
  6. package/dist/css/uikit-rtl.css +1 -1
  7. package/dist/css/uikit-rtl.min.css +1 -1
  8. package/dist/css/uikit.css +1 -1
  9. package/dist/css/uikit.min.css +1 -1
  10. package/dist/js/components/countdown.js +1 -1
  11. package/dist/js/components/countdown.min.js +1 -1
  12. package/dist/js/components/filter.js +1 -1
  13. package/dist/js/components/filter.min.js +1 -1
  14. package/dist/js/components/lightbox-panel.js +1 -1
  15. package/dist/js/components/lightbox-panel.min.js +1 -1
  16. package/dist/js/components/lightbox.js +1 -1
  17. package/dist/js/components/lightbox.min.js +1 -1
  18. package/dist/js/components/notification.js +1 -1
  19. package/dist/js/components/notification.min.js +1 -1
  20. package/dist/js/components/parallax.js +37 -41
  21. package/dist/js/components/parallax.min.js +1 -1
  22. package/dist/js/components/slider-parallax.js +32 -25
  23. package/dist/js/components/slider-parallax.min.js +1 -1
  24. package/dist/js/components/slider.js +2 -2
  25. package/dist/js/components/slider.min.js +1 -1
  26. package/dist/js/components/slideshow-parallax.js +32 -25
  27. package/dist/js/components/slideshow-parallax.min.js +1 -1
  28. package/dist/js/components/slideshow.js +1 -1
  29. package/dist/js/components/slideshow.min.js +1 -1
  30. package/dist/js/components/sortable.js +2 -3
  31. package/dist/js/components/sortable.min.js +1 -1
  32. package/dist/js/components/tooltip.js +1 -1
  33. package/dist/js/components/tooltip.min.js +1 -1
  34. package/dist/js/components/upload.js +1 -1
  35. package/dist/js/components/upload.min.js +1 -1
  36. package/dist/js/uikit-core.js +111 -66
  37. package/dist/js/uikit-core.min.js +1 -1
  38. package/dist/js/uikit-icons.js +1 -1
  39. package/dist/js/uikit-icons.min.js +1 -1
  40. package/dist/js/uikit.js +174 -134
  41. package/dist/js/uikit.min.js +1 -1
  42. package/package.json +1 -1
  43. package/src/js/components/parallax.js +5 -16
  44. package/src/js/components/slider.js +1 -1
  45. package/src/js/components/sortable.js +1 -2
  46. package/src/js/core/core.js +2 -2
  47. package/src/js/core/height-viewport.js +2 -2
  48. package/src/js/core/sticky.js +54 -41
  49. package/src/js/mixin/parallax.js +32 -21
  50. package/src/js/util/dimensions.js +28 -12
  51. package/src/js/util/fastdom.js +2 -2
  52. package/src/js/util/viewport.js +7 -3
  53. package/tests/sticky.html +39 -24
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "uikit",
3
3
  "title": "UIkit",
4
4
  "description": "UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.",
5
- "version": "3.11.1",
5
+ "version": "3.11.2-dev.19d26d0f9",
6
6
  "main": "dist/js/uikit.js",
7
7
  "style": "dist/css/uikit.css",
8
8
  "sideEffects": [
@@ -28,13 +28,15 @@ export default {
28
28
  },
29
29
 
30
30
  start({start}) {
31
- return parseCalc(start, this.target);
31
+ return toPx(start, 'height', this.target, true);
32
32
  },
33
33
 
34
34
  end({end, viewport}) {
35
- return parseCalc(
35
+ return toPx(
36
36
  end || (viewport = (1 - viewport) * 100) && `${viewport}vh+${viewport}%`,
37
- this.target
37
+ 'height',
38
+ this.target,
39
+ true
38
40
  );
39
41
  }
40
42
 
@@ -77,19 +79,6 @@ export default {
77
79
 
78
80
  };
79
81
 
80
- const calcRe = /-?\d+(?:\.\d+)?(?:v[wh]|%|px)?/g;
81
- function parseCalc(calc, el) {
82
- let match;
83
- let result = 0;
84
- calc = calc.toString().replace(/\s/g, '');
85
- calcRe.lastIndex = 0;
86
- while ((match = calcRe.exec(calc)) !== null) {
87
- result += toPx(match[0], 'height', el, true);
88
- }
89
-
90
- return result;
91
- }
92
-
93
82
  function ease(percent, easing) {
94
83
  return easing >= 0
95
84
  ? Math.pow(percent, easing + 1)
@@ -30,7 +30,7 @@ export default {
30
30
  },
31
31
 
32
32
  finite({finite}) {
33
- return finite || Math.ceil(getWidth(this.list)) < dimensions(this.list).width + getMaxElWidth(this.list) + this.center;
33
+ return finite || Math.ceil(getWidth(this.list)) < Math.floor(dimensions(this.list).width + getMaxElWidth(this.list) + this.center);
34
34
  },
35
35
 
36
36
  maxIndex() {
@@ -218,7 +218,6 @@ export default {
218
218
 
219
219
  off(document, pointerMove, this.move);
220
220
  off(document, pointerUp, this.end);
221
- off(window, 'scroll', this.scroll);
222
221
 
223
222
  if (!this.drag) {
224
223
  return;
@@ -295,7 +294,7 @@ function trackScroll(pos) {
295
294
  trackTimer = setInterval(() => {
296
295
 
297
296
  let {x, y} = pos;
298
- y += window.pageYOffset;
297
+ y += scrollTop(window);
299
298
 
300
299
  const dist = (Date.now() - last) * .3;
301
300
  last = Date.now();
@@ -13,7 +13,7 @@ export default function (UIkit) {
13
13
  return;
14
14
  }
15
15
  pendingResize = true;
16
- fastdom.write(() => pendingResize = false);
16
+ fastdom.read(() => pendingResize = false);
17
17
  UIkit.update(null, 'resize');
18
18
  };
19
19
 
@@ -32,7 +32,7 @@ export default function (UIkit) {
32
32
  return;
33
33
  }
34
34
  pending = true;
35
- fastdom.write(() => pending = false);
35
+ fastdom.read(() => pending = false);
36
36
 
37
37
  UIkit.update(null, e.type);
38
38
 
@@ -1,5 +1,5 @@
1
1
  import FlexBug from '../mixin/flex-bug';
2
- import {boxModelAdjust, css, dimensions, endsWith, height, isNumeric, isString, isVisible, offset, query, toFloat} from 'uikit-util';
2
+ import {boxModelAdjust, css, dimensions, endsWith, height, isNumeric, isString, isVisible, offset, query, toFloat, trigger} from 'uikit-util';
3
3
 
4
4
  export default {
5
5
 
@@ -76,7 +76,7 @@ export default {
76
76
  css(this.$el, {minHeight});
77
77
 
78
78
  if (minHeight !== prev) {
79
- this.$update(this.$el, 'resize');
79
+ trigger(this.$el, 'resize');
80
80
  }
81
81
 
82
82
  if (this.minHeight && toFloat(css(this.$el, 'minHeight')) < this.minHeight) {
@@ -1,6 +1,6 @@
1
1
  import Class from '../mixin/class';
2
2
  import Media from '../mixin/media';
3
- import {$, addClass, after, Animation, assign, css, dimensions, fastdom, height as getHeight, hasClass, isNumeric, isString, isVisible, noop, offset, offsetPosition, parent, query, remove, removeClass, replaceClass, scrollTop, toFloat, toggleClass, toPx, trigger, within} from 'uikit-util';
3
+ import {$, addClass, after, Animation, assign, clamp, css, dimensions, fastdom, height as getHeight, getScrollingElement, hasClass, isNumeric, isString, isVisible, noop, offset, offsetPosition, parent, query, remove, removeClass, replaceClass, scrollTop, toggleClass, toPx, trigger, within} from 'uikit-util';
4
4
 
5
5
  export default {
6
6
 
@@ -38,8 +38,8 @@ export default {
38
38
 
39
39
  computed: {
40
40
 
41
- offset({offset}) {
42
- return toPx(offset);
41
+ offset({offset}, $el) {
42
+ return toPx(offset, 'height', $el);
43
43
  },
44
44
 
45
45
  selTarget({selTarget}, $el) {
@@ -100,7 +100,7 @@ export default {
100
100
 
101
101
  handler() {
102
102
 
103
- if (!(this.targetOffset !== false && location.hash && window.pageYOffset > 0)) {
103
+ if (!(this.targetOffset !== false && location.hash && scrollTop(window) > 0)) {
104
104
  return;
105
105
  }
106
106
 
@@ -146,24 +146,28 @@ export default {
146
146
 
147
147
  height = this.isActive ? height : this.$el.offsetHeight;
148
148
 
149
- if (height + this.offset > getHeight(window)) {
150
- this.inactive = true;
151
- return false;
152
- }
149
+ const overflow = Math.max(0, height + this.offset - getHeight(window));
153
150
 
154
151
  const referenceElement = this.isFixed ? this.placeholder : this.$el;
155
- this.topOffset = offset(referenceElement).top;
156
- this.bottomOffset = this.topOffset + height;
157
- this.offsetParentTop = offset(referenceElement.offsetParent).top;
152
+ const topOffset = offset(referenceElement).top;
153
+ const offsetParentTop = offset(referenceElement.offsetParent).top;
158
154
 
159
- const bottom = parseProp('bottom', this);
155
+ const top = parseProp(this.top, this.$el, topOffset);
156
+ const bottom = parseProp(this.bottom, this.$el, topOffset + height);
160
157
 
161
- this.top = Math.max(toFloat(parseProp('top', this)), this.topOffset) - this.offset;
162
- this.bottom = bottom && bottom - this.$el.offsetHeight;
163
- this.width = dimensions(isVisible(this.widthElement) ? this.widthElement : this.$el).width;
158
+ const start = Math.max(top, topOffset) - this.offset;
159
+ const end = bottom
160
+ ? bottom - this.$el.offsetHeight + overflow - this.offset
161
+ : getScrollingElement(this.$el).scrollHeight - getHeight(window);
164
162
 
165
163
  return {
164
+ start,
165
+ end,
166
+ overflow,
167
+ topOffset,
168
+ offsetParentTop,
166
169
  height,
170
+ width: dimensions(isVisible(this.widthElement) ? this.widthElement : this.$el).width,
167
171
  top: offsetPosition(this.placeholder)[0],
168
172
  margins: css(this.$el, ['marginTop', 'marginBottom', 'marginLeft', 'marginRight'])
169
173
  };
@@ -190,42 +194,48 @@ export default {
190
194
 
191
195
  {
192
196
 
193
- read({scroll = 0}) {
197
+ read({scroll: prevScroll = 0, dir: prevDir = 'down', overflow, overflowScroll = 0, start, end}) {
194
198
 
195
- this.scroll = window.pageYOffset;
199
+ const scroll = scrollTop(window);
200
+ const dir = prevScroll <= scroll ? 'down' : 'up';
196
201
 
197
202
  return {
198
- dir: scroll <= this.scroll ? 'down' : 'up',
199
- scroll: this.scroll
203
+ dir,
204
+ prevDir,
205
+ scroll,
206
+ prevScroll,
207
+ overflowScroll: clamp(
208
+ overflowScroll
209
+ + clamp(scroll, start, end)
210
+ - clamp(prevScroll, start, end),
211
+ 0,
212
+ overflow
213
+ )
200
214
  };
201
215
  },
202
216
 
203
217
  write(data, types) {
204
218
 
205
- const now = Date.now();
206
219
  const isScrollUpdate = types.has('scroll');
207
- const {initTimestamp = 0, dir, lastDir, lastScroll, scroll, top} = data;
220
+ const {initTimestamp = 0, dir, prevDir, scroll, prevScroll = 0, top, start, topOffset, height} = data;
208
221
 
209
- data.lastScroll = scroll;
210
-
211
- if (scroll < 0 || scroll === lastScroll && isScrollUpdate || this.showOnUp && !isScrollUpdate && !this.isFixed) {
222
+ if (scroll < 0 || scroll === prevScroll && isScrollUpdate || this.showOnUp && !isScrollUpdate && !this.isFixed) {
212
223
  return;
213
224
  }
214
225
 
215
- if (now - initTimestamp > 300 || dir !== lastDir) {
226
+ const now = Date.now();
227
+ if (now - initTimestamp > 300 || dir !== prevDir) {
216
228
  data.initScroll = scroll;
217
229
  data.initTimestamp = now;
218
230
  }
219
231
 
220
- data.lastDir = dir;
221
-
222
- if (this.showOnUp && !this.isFixed && Math.abs(data.initScroll - scroll) <= 30 && Math.abs(lastScroll - scroll) <= 10) {
232
+ if (this.showOnUp && !this.isFixed && Math.abs(data.initScroll - scroll) <= 30 && Math.abs(prevScroll - scroll) <= 10) {
223
233
  return;
224
234
  }
225
235
 
226
236
  if (this.inactive
227
- || scroll < this.top
228
- || this.showOnUp && (scroll <= this.top || dir === 'down' && isScrollUpdate || dir === 'up' && !this.isFixed && scroll <= this.bottomOffset)
237
+ || scroll < start
238
+ || this.showOnUp && (scroll <= start || dir === 'down' && isScrollUpdate || dir === 'up' && !this.isFixed && scroll <= topOffset + height)
229
239
  ) {
230
240
 
231
241
  if (!this.isFixed) {
@@ -240,7 +250,7 @@ export default {
240
250
 
241
251
  this.isFixed = false;
242
252
 
243
- if (this.animation && scroll > this.topOffset) {
253
+ if (this.animation && scroll > topOffset) {
244
254
  Animation.cancel(this.$el);
245
255
  Animation.out(this.$el, this.animation).then(() => this.hide(), noop);
246
256
  } else {
@@ -290,23 +300,28 @@ export default {
290
300
 
291
301
  update() {
292
302
 
293
- const active = this.top !== 0 || this.scroll > this.top;
303
+ const {width, scroll = 0, overflow, overflowScroll = 0, start, end, topOffset, height, offsetParentTop} = this._data;
304
+ const active = start !== 0 || scroll > start;
294
305
  let top = Math.max(0, this.offset);
295
306
  let position = 'fixed';
296
307
 
297
- if (isNumeric(this.bottom) && this.scroll > this.bottom - this.offset) {
298
- top = this.bottom - this.offsetParentTop;
308
+ if (scroll > end) {
309
+ top = end + this.offset - offsetParentTop;
299
310
  position = 'absolute';
300
311
  }
301
312
 
313
+ if (overflow) {
314
+ top -= overflowScroll;
315
+ }
316
+
302
317
  css(this.$el, {
303
318
  position,
304
319
  top: `${top}px`,
305
- width: this.width
320
+ width
306
321
  });
307
322
 
308
323
  this.isActive = active;
309
- toggleClass(this.$el, this.clsBelow, this.scroll > this.bottomOffset);
324
+ toggleClass(this.$el, this.clsBelow, scroll > topOffset + height);
310
325
  addClass(this.$el, this.clsFixed);
311
326
 
312
327
  }
@@ -315,12 +330,10 @@ export default {
315
330
 
316
331
  };
317
332
 
318
- function parseProp(prop, {$props, $el, [`${prop}Offset`]: propOffset}) {
319
-
320
- const value = $props[prop];
333
+ function parseProp(value, el, propOffset) {
321
334
 
322
335
  if (!value) {
323
- return;
336
+ return 0;
324
337
  }
325
338
 
326
339
  if (isString(value) && value.match(/^-?\d/)) {
@@ -329,7 +342,7 @@ function parseProp(prop, {$props, $el, [`${prop}Offset`]: propOffset}) {
329
342
 
330
343
  } else {
331
344
 
332
- return offset(value === true ? parent($el) : query(value, $el)).bottom;
345
+ return offset(value === true ? parent(el) : query(value, el)).bottom;
333
346
 
334
347
  }
335
348
  }
@@ -1,6 +1,6 @@
1
1
  import Media from '../mixin/media';
2
2
  import {getMaxPathLength} from '../core/svg';
3
- import {css, Dimensions, each, isNumber, isString, isUndefined, noop, startsWith, toFloat, toPx, ucfirst} from 'uikit-util';
3
+ import {css, Dimensions, each, isNumber, isString, isUndefined, noop, startsWith, toFloat, toPx, trigger, ucfirst} from 'uikit-util';
4
4
 
5
5
  const props = {
6
6
  x: transformFn,
@@ -38,7 +38,7 @@ export default {
38
38
  props(properties, $el) {
39
39
  return keys(props).reduce((result, prop) => {
40
40
  if (!isUndefined(properties[prop])) {
41
- result[prop] = props[prop].call(this, prop, $el, properties[prop].slice());
41
+ result[prop] = props[prop](prop, $el, properties[prop].slice());
42
42
  }
43
43
  return result;
44
44
  }, {});
@@ -46,6 +46,12 @@ export default {
46
46
 
47
47
  },
48
48
 
49
+ events: {
50
+ bgimageload() {
51
+ this.$emit();
52
+ }
53
+ },
54
+
49
55
  methods: {
50
56
 
51
57
  reset() {
@@ -186,15 +192,15 @@ function backgroundFn(prop, el, steps) {
186
192
  const bgPos = css(el, 'backgroundPosition').split(' ')[prop === 'x' ? 0 : 1]; // IE 11 can't read background-position-[x|y]
187
193
 
188
194
  return getCssValue(el, 'backgroundSize', '') === 'cover'
189
- ? backgroundCoverFn.call(this, prop, el, steps, bgPos, attr)
195
+ ? backgroundCoverFn(prop, el, steps, bgPos, attr)
190
196
  : setBackgroundPosFn(prop, steps, bgPos);
191
197
  }
192
198
 
193
199
  function backgroundCoverFn(prop, el, steps, bgPos, attr) {
194
200
 
195
- const image = getBackgroundImage.call(this, el);
201
+ const dimImage = getBackgroundImageDimensions(el);
196
202
 
197
- if (!image.naturalWidth) {
203
+ if (!dimImage.width) {
198
204
  return noop;
199
205
  }
200
206
 
@@ -210,11 +216,6 @@ function backgroundCoverFn(prop, el, steps, bgPos, attr) {
210
216
  height: el.offsetHeight
211
217
  };
212
218
 
213
- const dimImage = {
214
- width: image.naturalWidth,
215
- height: image.naturalHeight
216
- };
217
-
218
219
  const baseDim = Dimensions.cover(dimImage, dimEl);
219
220
  const span = baseDim[attr] - dimEl[attr];
220
221
 
@@ -245,24 +246,34 @@ function setBackgroundPosFn(prop, steps, pos) {
245
246
  };
246
247
  }
247
248
 
248
- function getBackgroundImage(el) {
249
+ const dimensions = {};
250
+ function getBackgroundImageDimensions(el) {
249
251
  const src = css(el, 'backgroundImage').replace(/^none|url\(["']?(.+?)["']?\)$/, '$1');
250
252
 
251
- const data = this._data;
252
-
253
- if (data[src]) {
254
- return data[src];
253
+ if (dimensions[src]) {
254
+ return dimensions[src];
255
255
  }
256
256
 
257
+ const image = new Image();
257
258
  if (src) {
258
- const img = new Image();
259
- img.src = src;
260
- if (!img.naturalWidth) {
261
- img.onload = () => this.$update();
262
- }
259
+ image.src = src;
263
260
 
264
- return data[src] = img;
261
+ if (!image.naturalWidth) {
262
+ image.onload = () => {
263
+ dimensions[src] = toDimensions(image);
264
+ trigger(el, 'bgimageload');
265
+ };
266
+ }
265
267
  }
268
+
269
+ return dimensions[src] = toDimensions(image);
270
+ }
271
+
272
+ function toDimensions(image) {
273
+ return {
274
+ width: image.naturalWidth,
275
+ height: image.naturalHeight
276
+ };
266
277
  }
267
278
 
268
279
  function getStep(steps, percent) {
@@ -1,5 +1,5 @@
1
1
  import {css} from './style';
2
- import {each, endsWith, isDocument, isElement, isNumeric, isUndefined, isWindow, toFloat, toNode, toWindow, ucfirst} from './lang';
2
+ import {each, isDocument, isElement, isString, isUndefined, isWindow, memoize, toFloat, toNode, toWindow, ucfirst} from './lang';
3
3
 
4
4
  const dirs = {
5
5
  width: ['left', 'right'],
@@ -157,19 +157,35 @@ export function flipPosition(pos) {
157
157
  }
158
158
 
159
159
  export function toPx(value, property = 'width', element = window, offsetDim = false) {
160
- return isNumeric(value)
161
- ? +value
162
- : endsWith(value, 'vh')
163
- ? percent(height(toWindow(element)), value)
164
- : endsWith(value, 'vw')
165
- ? percent(width(toWindow(element)), value)
166
- : endsWith(value, '%')
167
- ? percent(offsetDim
168
- ? element[`offset${ucfirst(property)}`]
169
- : dimensions(element)[property], value)
170
- : toFloat(value);
160
+
161
+ if (!isString(value)) {
162
+ return toFloat(value);
163
+ }
164
+
165
+ return parseCalc(value).reduce((result, value) => {
166
+ const unit = parseUnit(value);
167
+ if (unit) {
168
+ value = percent(
169
+ unit === 'vh'
170
+ ? height(toWindow(element))
171
+ : unit === 'vw'
172
+ ? width(toWindow(element))
173
+ : offsetDim
174
+ ? element[`offset${ucfirst(property)}`]
175
+ : dimensions(element)[property],
176
+ value
177
+ );
178
+ }
179
+
180
+ return result + toFloat(value);
181
+ }, 0);
171
182
  }
172
183
 
184
+ const calcRe = /-?\d+(?:\.\d+)?(?:v[wh]|%|px)?/g;
185
+ const parseCalc = memoize(calc => calc.toString().replace(/\s/g, '').match(calcRe) || []);
186
+ const unitRe = /(?:v[hw]|%)$/;
187
+ const parseUnit = memoize(str => (str.match(unitRe) || [])[0]);
188
+
173
189
  function percent(base, value) {
174
190
  return base * toFloat(value) / 100;
175
191
  }
@@ -31,7 +31,7 @@ export const fastdom = {
31
31
 
32
32
  };
33
33
 
34
- function flush(recursion = 1) {
34
+ function flush(recursion) {
35
35
  runTasks(fastdom.reads);
36
36
  runTasks(fastdom.writes.splice(0));
37
37
 
@@ -53,7 +53,7 @@ function scheduleFlush(recursion) {
53
53
  if (recursion && recursion < RECURSION_LIMIT) {
54
54
  Promise.resolve().then(() => flush(recursion));
55
55
  } else {
56
- requestAnimationFrame(() => flush());
56
+ requestAnimationFrame(() => flush(1));
57
57
  }
58
58
 
59
59
  }
@@ -2,7 +2,7 @@ import {css} from './style';
2
2
  import {Promise} from './promise';
3
3
  import {isVisible, parents} from './filter';
4
4
  import {offset, offsetPosition} from './dimensions';
5
- import {clamp, findIndex, intersectRect, isDocument, isWindow, toNode, toWindow} from './lang';
5
+ import {clamp, findIndex, intersectRect, isDocument, isUndefined, isWindow, toNode, toWindow} from './lang';
6
6
 
7
7
  export function isInView(element, offsetTop = 0, offsetLeft = 0) {
8
8
 
@@ -31,7 +31,11 @@ export function scrollTop(element, top) {
31
31
  element = toNode(element);
32
32
  }
33
33
 
34
- element.scrollTop = top;
34
+ if (isUndefined(top)) {
35
+ return element.scrollTop;
36
+ } else {
37
+ element.scrollTop = top;
38
+ }
35
39
  }
36
40
 
37
41
  export function scrollIntoView(element, {offset: offsetBy = 0} = {}) {
@@ -145,7 +149,7 @@ export function getViewportClientHeight(scrollElement) {
145
149
  return (scrollElement === getScrollingElement(scrollElement) ? document.documentElement : scrollElement).clientHeight;
146
150
  }
147
151
 
148
- function getScrollingElement(element) {
152
+ export function getScrollingElement(element) {
149
153
  const {document} = toWindow(element);
150
154
  return document.scrollingElement || document.documentElement;
151
155
  }
package/tests/sticky.html CHANGED
@@ -8,54 +8,69 @@
8
8
  <script src="js/test.js"></script>
9
9
  <style>
10
10
 
11
- #viewport { border: 1px dashed rgba(0,0,0,0.2); }
11
+ .viewport { border: 1px dashed rgba(0,0,0,0.2); }
12
12
 
13
13
  </style>
14
14
  </head>
15
15
 
16
16
  <body>
17
17
 
18
- <div class="uk-container" style="height: 3500px;">
18
+ <div class="uk-container">
19
19
 
20
20
  <h1>Sticky</h1>
21
21
 
22
- <div id="viewport" class="uk-margin">
23
- <div class="uk-grid uk-child-width-1-6" uk-height-viewport="offset-top: true">
24
- <div>
22
+ <div class="uk-grid">
23
+ <div class="uk-width-5-6">
24
+ <div class="viewport uk-margin">
25
+ <div class="uk-grid uk-child-width-1-6" uk-height-viewport="offset-top: true">
26
+ <div>
25
27
 
26
- <div class="uk-card uk-card-primary uk-card-body" uk-sticky="offset: 50; bottom: #viewport">Stick to container; 50px offset</div>
28
+ <div class="uk-card uk-card-primary uk-card-body" uk-sticky="offset: 50; bottom: !.viewport">Stick to container; 50px offset</div>
27
29
 
28
- </div>
29
- <div>
30
+ </div>
31
+ <div>
30
32
 
31
- <div class="uk-card uk-card-primary uk-card-body" uk-sticky="top: 50vh; target-offset: 10">Sticky after 50vh; Scroll up if initially above paragraph below</div>
33
+ <div class="uk-card uk-card-primary uk-card-body" uk-sticky="top: 50vh; target-offset: 10">Sticky after 50vh; Scroll up if initially above paragraph below</div>
32
34
 
33
- </div>
34
- <div>
35
+ </div>
36
+ <div>
35
37
 
36
- <div class="uk-card uk-card-primary uk-card-body" uk-sticky="top: #viewport; animation: uk-animation-slide-top">Stick below container; animation</div>
38
+ <div class="uk-card uk-card-primary uk-card-body" uk-sticky="top: !.viewport; animation: uk-animation-slide-top">Stick below container; animation</div>
37
39
 
38
- </div>
39
- <div>
40
+ </div>
41
+ <div>
40
42
 
41
- <div class="uk-card uk-card-primary uk-card-body" uk-sticky="bottom: #hash">Stick until next paragraph</div>
43
+ <div class="uk-card uk-card-primary uk-card-body" uk-sticky="bottom: #hash">Stick until next paragraph</div>
42
44
 
43
- </div>
44
- <div>
45
+ </div>
46
+ <div>
45
47
 
46
- <div class="uk-card uk-card-primary uk-card-body" uk-sticky="show-on-up: true; animation: uk-animation-slide-top">Sticky on scroll up; animation</div>
48
+ <div class="uk-card uk-card-primary uk-card-body" uk-sticky="show-on-up: true; animation: uk-animation-slide-top">Sticky on scroll up; animation</div>
47
49
 
48
- </div>
49
- <div>
50
+ </div>
51
+ <div>
50
52
 
51
- <div class="uk-card uk-card-primary uk-card-body" uk-sticky="top: 300; animation: uk-animation-slide-top; media: 640">Sticky after 300px scrolling; @media 640px</div>
53
+ <div class="uk-card uk-card-primary uk-card-body" uk-sticky="top: 300; animation: uk-animation-slide-top; media: 640">Sticky after 300px scrolling; @media 640px</div>
52
54
 
55
+ </div>
56
+ </div>
57
+ </div>
58
+
59
+ <p id="hash" class="uk-margin-large">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
60
+ </div>
61
+ <div class="uk-width-1-6">
62
+ <div class="viewport" style="min-height: 200vh;">
63
+ <div>
64
+ <div class="uk-card uk-card-primary uk-card-body" style="height: 120vh" uk-sticky="bottom: !.viewport">
65
+ <p>Oversized Content</p>
66
+
67
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
68
+ </div>
69
+ </div>
53
70
  </div>
54
71
  </div>
55
72
  </div>
56
73
 
57
- <p id="hash" class="uk-margin-large">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
58
-
59
74
  <h2>JavaScript Options</h2>
60
75
 
61
76
  <div class="uk-overflow-auto">
@@ -73,7 +88,7 @@
73
88
  <td><code>top</code></td>
74
89
  <td>Number|Viewport Height|CSS Selector</td>
75
90
  <td>0</td>
76
- <td>The top offset from where the element should be stick.</td>
91
+ <td>The top offset from where the element should stick.</td>
77
92
  </tr>
78
93
  <tr>
79
94
  <td><code>bottom</code></td>