mirror of
https://github.com/webslides/WebSlides.git
synced 2025-09-10 05:00:40 +02:00
Compare commits
220 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9ec4fae96b | ||
|
13cfd525e8 | ||
|
fb5208218f | ||
|
87db22523c | ||
|
d9c2cb44f8 | ||
|
9a2dfe0e52 | ||
|
26716804cb | ||
|
ea0f2cb833 | ||
|
5dd1b9c649 | ||
|
ed93fd8df9 | ||
|
43105bd180 | ||
|
bee1e87c7f | ||
|
e9fa8d2e3a | ||
|
13fe06daa8 | ||
|
eef9d75706 | ||
|
b1e03202e3 | ||
|
3b7203c9ab | ||
|
8912d05d70 | ||
|
8b19bd28f6 | ||
|
71f2fd52b9 | ||
|
fe58531e74 | ||
|
71b08f8d3b | ||
|
e8dc32e274 | ||
|
1610da683e | ||
|
5233851f59 | ||
|
eb58c83d11 | ||
|
253e087c15 | ||
|
ce4b1603d2 | ||
|
514df1b421 | ||
|
eb402a886f | ||
|
03603fa1c8 | ||
|
261259a9d3 | ||
|
37d9b84bff | ||
|
e6de10e449 | ||
|
fc1a733d6f | ||
|
e523998f1e | ||
|
6699407c08 | ||
|
18970a7b7b | ||
|
e39fad9a16 | ||
|
e78e25ddea | ||
|
f4c93e68d3 | ||
|
94e8e22f10 | ||
|
4462883dc0 | ||
|
2c2fd3a0db | ||
|
cfd1f74b9b | ||
|
7bcafd9f7c | ||
|
50cb44c85f | ||
|
eea1b46f02 | ||
|
cf4f1d22b7 | ||
|
9f93263c86 | ||
|
4fb3f14cde | ||
|
31dc31c307 | ||
|
cb60cab236 | ||
|
5226ab189b | ||
|
5456109a97 | ||
|
578a66977a | ||
|
0e0b2b4160 | ||
|
c109276ef6 | ||
|
98886a159f | ||
|
d042984f5d | ||
|
a720b6b5fb | ||
|
8e75227ea0 | ||
|
811007da8d | ||
|
377de1f0be | ||
|
43bc612a5b | ||
|
9256c476b9 | ||
|
654510a374 | ||
|
118417b215 | ||
|
c997ec6cc4 | ||
|
0b4c458203 | ||
|
ea8a839dc8 | ||
|
ab63347ef3 | ||
|
7fda1f4de9 | ||
|
63ac064a25 | ||
|
5b45de0b79 | ||
|
e7329433ff | ||
|
db95f1bf0c | ||
|
2c0f82d942 | ||
|
da61aed18b | ||
|
05db02495c | ||
|
fedad97769 | ||
|
3e64e33ed7 | ||
|
18662f38f6 | ||
|
af13de6696 | ||
|
504ad99df9 | ||
|
6f79bce0de | ||
|
52e9188b55 | ||
|
bad0ef5551 | ||
|
12d7608dbb | ||
|
893229ba1c | ||
|
d34e445e7c | ||
|
2f292cc5ee | ||
|
54589277b7 | ||
|
5160ce05ef | ||
|
810b634477 | ||
|
9c06479d9d | ||
|
0e54ccc4a2 | ||
|
aa71fe97bc | ||
|
8773012e0d | ||
|
dad3957cf3 | ||
|
db177cf405 | ||
|
e447935c3c | ||
|
ac80c7afec | ||
|
86894f0489 | ||
|
eb515bbcb7 | ||
|
aa1afb2927 | ||
|
a2100eabdb | ||
|
b2b761f5b1 | ||
|
caeacda724 | ||
|
ac8ac17490 | ||
|
f525d7ec87 | ||
|
aa15d18dca | ||
|
26281751ec | ||
|
ed9c3142b4 | ||
|
e3b9febbe0 | ||
|
408bd4e269 | ||
|
34495579c0 | ||
|
c04825878d | ||
|
6a61ddbcf4 | ||
|
c5ee83c940 | ||
|
8a9ea037c0 | ||
|
1d8ea0f48f | ||
|
7ff8612c3f | ||
|
226388b209 | ||
|
f92718e381 | ||
|
66a95ea75a | ||
|
3d236c518a | ||
|
0e2a4a9587 | ||
|
891396ef52 | ||
|
d3b7032c48 | ||
|
b1b081038c | ||
|
a5583beec6 | ||
|
f46de277c0 | ||
|
41f93fba25 | ||
|
e91a255560 | ||
|
d997593fd2 | ||
|
8e6b609068 | ||
|
50a1387fe1 | ||
|
73ee831593 | ||
|
dbc06fedbb | ||
|
c82fd6507a | ||
|
2fb8c1e816 | ||
|
7c1f07b575 | ||
|
2e373c1d1c | ||
|
a43b919c05 | ||
|
54facec8e5 | ||
|
d173a1fd54 | ||
|
f0a67fbc53 | ||
|
d150b00014 | ||
|
e3938e9451 | ||
|
fb6fdb1d57 | ||
|
218c67a435 | ||
|
bc3d1a9fa0 | ||
|
65a4a47f22 | ||
|
466b92a7e4 | ||
|
7d0208f046 | ||
|
05b46fc11b | ||
|
fab63a99ca | ||
|
48b40c6ae9 | ||
|
7f3af9672c | ||
|
6e27dc809a | ||
|
db0955305b | ||
|
d2e6f562f2 | ||
|
f954ea2fb3 | ||
|
d1840ec016 | ||
|
1de7249a65 | ||
|
98d6095916 | ||
|
cb622727d6 | ||
|
c0a3d725df | ||
|
0a19f0d813 | ||
|
338b265950 | ||
|
b19e4a4e0d | ||
|
37e8d1ae26 | ||
|
714915002c | ||
|
fed6f1b932 | ||
|
786db33861 | ||
|
c894759d93 | ||
|
7f59470ddd | ||
|
8b8dfb3c16 | ||
|
eb45889266 | ||
|
b6a4ae71b9 | ||
|
ff4029dbef | ||
|
4be762c6c0 | ||
|
c8244e32f5 | ||
|
0d1769d920 | ||
|
bfa6901909 | ||
|
7299f5a6dd | ||
|
71e7913a64 | ||
|
68eae7952a | ||
|
72a73f700e | ||
|
e5ff650e07 | ||
|
98717b15a4 | ||
|
17cb40e21b | ||
|
d69046b670 | ||
|
d04d53a1ec | ||
|
a564e28d9a | ||
|
95157d582a | ||
|
4dde8fe8fb | ||
|
344b018db6 | ||
|
04bb9145a9 | ||
|
5a7c84891a | ||
|
b41cf41ac9 | ||
|
052772be98 | ||
|
34fdc56eac | ||
|
708d5bfda6 | ||
|
89e8ffdd78 | ||
|
a49568a6b0 | ||
|
78ababde67 | ||
|
ee6e0045e5 | ||
|
ebb5e9a4cd | ||
|
79ec99a2f7 | ||
|
eed75b0eb2 | ||
|
0768afe146 | ||
|
4248f08ae8 | ||
|
f36bc93efb | ||
|
ac5427f655 | ||
|
13160c4131 | ||
|
a43a84829a | ||
|
229cdcf6a5 | ||
|
95ce3b9e36 |
10
.babelrc
10
.babelrc
@@ -1,3 +1,11 @@
|
||||
{
|
||||
"presets": ["es2015"]
|
||||
"presets": [
|
||||
["es2015", {"modules": false}]
|
||||
],
|
||||
|
||||
"env": {
|
||||
"test": {
|
||||
"plugins": ["transform-es2015-modules-commonjs"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,15 @@
|
||||
{
|
||||
"env": {
|
||||
"jest/globals": true,
|
||||
"browser": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"jest"
|
||||
],
|
||||
"rules": {
|
||||
"no-cond-assign": 0,
|
||||
"no-console": 2,
|
||||
@@ -106,6 +110,7 @@
|
||||
"space-before-blocks": 2,
|
||||
"space-before-function-paren": [2, "never"],
|
||||
"spaced-comment": [2, "always"],
|
||||
"space-in-parens": [2, "never"],
|
||||
|
||||
// ECMAScript 6
|
||||
// http://eslint.org/docs/rules/#ecmascript-6
|
||||
@@ -128,5 +133,3 @@
|
||||
"yield-star-spacing": [2, "after"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,6 +5,8 @@
|
||||
# Third Party #
|
||||
###############
|
||||
node_modules/
|
||||
coverage
|
||||
.eslintcache
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
@@ -15,3 +17,4 @@ node_modules/
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
webslides.zip
|
||||
|
1
.npmignore
Normal file
1
.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
.babelrc
|
95
.sass-lint.yml
Normal file
95
.sass-lint.yml
Normal file
@@ -0,0 +1,95 @@
|
||||
files:
|
||||
include: 'src/scss/**/*.scss'
|
||||
options:
|
||||
formatter: stylish
|
||||
merge-default-rules: false
|
||||
rules:
|
||||
# Extends
|
||||
extends-before-mixins: 2
|
||||
extends-before-declarations: 2
|
||||
placeholder-in-extend: 2
|
||||
|
||||
# Mixins
|
||||
mixins-before-declarations: 2
|
||||
|
||||
# Line Spacing
|
||||
one-declaration-per-line: 2
|
||||
empty-line-between-blocks: 2
|
||||
single-line-per-selector: 2
|
||||
|
||||
# Disallows
|
||||
no-attribute-selectors: 0
|
||||
no-color-hex: 0
|
||||
no-color-keywords: 2
|
||||
no-color-literals: 2
|
||||
no-combinators: 0
|
||||
no-debug: 2
|
||||
no-disallowed-properties: 0
|
||||
no-duplicate-properties: 2
|
||||
no-empty-rulesets: 2
|
||||
no-extends: 0
|
||||
no-ids: 0
|
||||
no-important: 2
|
||||
no-invalid-hex: 2
|
||||
no-mergeable-selectors: 2
|
||||
no-misspelled-properties: 2
|
||||
no-qualifying-elements: 0
|
||||
no-trailing-whitespace: 2
|
||||
no-trailing-zero: 2
|
||||
no-transition-all: 0
|
||||
no-universal-selectors: 0
|
||||
no-url-domains: 0
|
||||
no-url-protocols: 0
|
||||
no-vendor-prefixes: 2
|
||||
no-warn: 2
|
||||
property-units: 0
|
||||
|
||||
# Nesting
|
||||
declarations-before-nesting: 2
|
||||
force-attribute-nesting: 0
|
||||
force-element-nesting: 0
|
||||
force-pseudo-nesting: 0
|
||||
|
||||
# Name Formats
|
||||
class-name-format: 0
|
||||
function-name-format: 2
|
||||
id-name-format: 0
|
||||
mixin-name-format: 2
|
||||
placeholder-name-format: 2
|
||||
variable-name-format: 2
|
||||
|
||||
# Style Guide
|
||||
attribute-quotes: 2
|
||||
bem-depth: 0
|
||||
border-zero: 2
|
||||
brace-style: 2
|
||||
clean-import-paths: 2
|
||||
empty-args: 2
|
||||
hex-length: 2
|
||||
hex-notation: 2
|
||||
indentation: 2
|
||||
leading-zero: 2
|
||||
max-line-length: 0
|
||||
max-file-line-count: 0
|
||||
nesting-depth: 2
|
||||
property-sort-order: 2
|
||||
pseudo-element: 0
|
||||
quotes: 2
|
||||
shorthand-values: 2
|
||||
url-quotes: 2
|
||||
variable-for-property: 0
|
||||
zero-unit: 2
|
||||
|
||||
# Inner Spacing
|
||||
space-after-comma: 2
|
||||
space-before-colon: 2
|
||||
space-after-colon: 2
|
||||
space-before-brace: 2
|
||||
space-before-bang: 2
|
||||
space-after-bang: 2
|
||||
space-between-parens: 2
|
||||
space-around-operator: 2
|
||||
|
||||
# Final Items
|
||||
trailing-semicolon: 2
|
||||
final-newline: 2
|
3
.travis.yml
Normal file
3
.travis.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "10"
|
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,3 +1,33 @@
|
||||
# 1.5.0 (2017-09-16)
|
||||
|
||||
- [[#96]((https://github.com/webslides/webslides/issues/96))] Using Shift Space now allows to go to previous slide.
|
||||
- [[#97]((https://github.com/webslides/webslides/issues/97))] Fixing CTRL/CMD + F not allowing to search.
|
||||
- Dependencies updated.
|
||||
|
||||
# 1.4.2 (2017-09-12)
|
||||
|
||||
- Fixed `.toc` class. (Regression from Sass)
|
||||
- Fixed baseline being incorrectly included.
|
||||
|
||||
# 1.4.1 (2017-08-18)
|
||||
|
||||
- Fixed longform alignments. (Regression from Sass)
|
||||
- Updated demos to use correct reference.
|
||||
- Added new unsplash to [demo](http://webslides.tv/demos/keynote).
|
||||
|
||||
# 1.4.0 (2017-08-14)
|
||||
|
||||
## Misc
|
||||
|
||||
- [[#52]((https://github.com/webslides/webslides/issues/52))] We've moved to Sass! We've migrated all of our content to sass so you can customise it a bit more easily.
|
||||
Tests! We've added tests with the awesome Jest and Travis to keep it tested.
|
||||
|
||||
## New features
|
||||
|
||||
- [[#73]((https://github.com/webslides/webslides/issues/73))] Slides Index. Press - or click on our slide count to access a fancy new index to quickly navigate to a new slide. Press + or esc to exit or click on one slide to navigate to the slide. You can also disable this feature entirely with an option. Read more
|
||||
- [[#84]((https://github.com/webslides/webslides/issues/84))] Full Screen Mode. Pressing F now toggles full screen mode to remove all the distractions from the browser. Thanks solilokiam!
|
||||
- [[#66]((https://github.com/webslides/webslides/issues/66))] New option to disable scroll to navigate.
|
||||
|
||||
# 1.3.0 (2017-04-20)
|
||||
|
||||
## Misc
|
||||
|
47
README.md
47
README.md
@@ -2,19 +2,36 @@
|
||||
|
||||
[](http://opensource.org/licenses/MIT)
|
||||
[](https://github.com/webslides/webslides/releases/latest)
|
||||
[](https://codecov.io/gh/webslides/WebSlides)
|
||||
[](https://www.paypal.me/jlantunez/8)
|
||||
[](https://twitter.com/webslides)
|
||||
|
||||
Finally, everything you need to make HTML presentations, landings, and longforms in a beautiful way. Just the essentials. A new release (at least) every 8th day of the month — [https://webslides.tv/demos](https://webslides.tv/demos).
|
||||
Finally, everything you need to make HTML presentations, landings, and longforms in a beautiful way. Just a basic knowledge of HTML and CSS is required. Designers, marketers, and journalists can now focus on the content. — [https://webslides.tv/demos](https://webslides.tv/demos).
|
||||
|
||||
* * *
|
||||
### Download
|
||||
Simply choose a demo and customize it in minutes. Latest version: [webslides.tv/webslides-latest.zip](https://webslides.tv/webslides-latest.zip).
|
||||
Simply choose a demo and customize it in seconds. Latest version: [webslides.tv/webslides-latest.zip](https://webslides.tv/webslides-latest.zip).
|
||||
* * *
|
||||
|
||||
|
||||
### Why WebSlides? Productivity
|
||||
This is about telling the story, and sharing it in a beautiful way. Just a basic knowledge of HTML and CSS is required. Designers, marketers, and journalists can now focus on the content.
|
||||
### What's in the download?
|
||||
|
||||
The download includes demos and images (devices and logos).
|
||||
All content is for demo purposes only. Images are property of their respective owners.
|
||||
|
||||
```
|
||||
webslides/
|
||||
├── index.html
|
||||
├── css/
|
||||
│ ├── base.css
|
||||
│ └── colors.css
|
||||
│ └── svg-icons.css (optional)
|
||||
├── js/
|
||||
│ ├── webslides.js
|
||||
│ └── svg-icons.js (optional)
|
||||
└── demos/
|
||||
└── images/
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
@@ -54,25 +71,6 @@ This is about telling the story, and sharing it in a beautiful way. Just a basic
|
||||
<article id="webslides" class="vertical">
|
||||
```
|
||||
|
||||
### What's in the download?
|
||||
|
||||
The download includes demos and images (devices and logos).
|
||||
All content is for demo purposes only. Images are property of their respective owners.
|
||||
|
||||
```
|
||||
webslides/
|
||||
├── index.html
|
||||
├── css/
|
||||
│ ├── base.css
|
||||
│ └── colors.css
|
||||
│ └── svg-icons.css (optional)
|
||||
├── js/
|
||||
│ ├── webslides.js
|
||||
│ └── svg-icons.js (optional)
|
||||
└── demos/
|
||||
└── images/
|
||||
```
|
||||
|
||||
### CSS Syntax (classes)
|
||||
|
||||
- Typography: `.text-landing`, `.text-data`, `.text-intro`...
|
||||
@@ -91,11 +89,10 @@ You can add:
|
||||
- [Animate on scroll](http://michalsnik.github.io/aos/) (Useful for longform articles)
|
||||
- [pt](http://williamngan.github.io/pt/)
|
||||
|
||||
|
||||
### Dive In!
|
||||
|
||||
- Do not miss [our demos](https://webslides.tv/).
|
||||
- Want to get techie? Read [our wiki](wiki):
|
||||
- Want to get techie? Read [our wiki](https://github.com/webslides/WebSlides/wiki):
|
||||
- [FAQ](https://github.com/webslides/WebSlides/wiki)
|
||||
- [Core API](https://github.com/webslides/WebSlides/wiki/Core-API)
|
||||
- [Plugin Docs](https://github.com/webslides/WebSlides/wiki/Plugin-docs)
|
||||
|
@@ -25,10 +25,7 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
@@ -1934,11 +1931,11 @@
|
||||
|
||||
<!-- Required -->
|
||||
<script src="../static/js/webslides.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
window.ws = new WebSlides();
|
||||
</script>
|
||||
|
||||
|
||||
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
|
||||
<script defer src="../static/js/svg-icons.js"></script>
|
||||
|
||||
|
@@ -25,10 +25,7 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/colors.css">
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/svg-icons.css">
|
||||
@@ -2903,7 +2900,7 @@
|
||||
<li><strong class="text-label" title="Website">Website:</strong> <a href="http://www.visitasevilla.es/en">visitasevilla.es</a></li>
|
||||
</ul>
|
||||
<p>
|
||||
There are many reasons to visit Seville. Its Old Town contains three UNESCO World Heritage Sites: the Alcázar palace complex, the Cathedral and the General Archive of the Indies.
|
||||
There are many reasons to visit Seville. Its Old Town contains three UNESCO World Heritage Sites: the Alcázar palace complex, the Cathedral and the General Archive of the Indies.
|
||||
</p>
|
||||
</div>
|
||||
<!-- end .flex-content-->
|
||||
@@ -3139,7 +3136,7 @@
|
||||
|
||||
<!-- Required -->
|
||||
<script src="../static/js/webslides.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
window.ws = new WebSlides();
|
||||
</script>
|
||||
|
@@ -26,10 +26,7 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
|
@@ -3,76 +3,73 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
|
||||
<!-- CLEAN MARKUP = GOOD KARMA.
|
||||
Hi source code lover,
|
||||
|
||||
|
||||
you're a curious person and a fast learner ;)
|
||||
Let's make something beautiful together. Contribute on Github:
|
||||
https://github.com/webslides/webslides
|
||||
|
||||
|
||||
Thanks!
|
||||
-->
|
||||
|
||||
|
||||
<!-- SEO -->
|
||||
<title>WebSlides Demo: Longform Interviews</title>
|
||||
<meta name="description" content="WebSlides is about telling stories. Create longform interviews with ease.">
|
||||
|
||||
|
||||
<!-- URL CANONICAL -->
|
||||
<!-- <link rel="canonical" href="http://your-url.com/permalink"> -->
|
||||
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
|
||||
|
||||
<!-- SOCIAL CARDS (ADD YOUR INFO) -->
|
||||
|
||||
|
||||
<!-- FACEBOOK -->
|
||||
<meta property="og:url" content="http://your-url.com/permalink">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:title" content="WebSlides Demo: Longform Interviews" />
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:description" content="Create longform interviews with ease. Just the essentials.">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:updated_time" content="2017-03-28T12:17:24">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:image" content="../static/images/share-webslides.jpg" >
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:image:width" content="800">
|
||||
<meta property="og:image:height" content="429">
|
||||
|
||||
|
||||
<!-- TWITTER -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:site" content="@webslides">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:creator" content="@jlantunez">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:title" content="WebSlides Demo: Longform Interviews">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:description" content="Create longform interviews with ease. Just the essentials.">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:image" content="../static/images/share-webslides.jpg">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
|
||||
|
||||
<!-- FAVICONS -->
|
||||
<link rel="shortcut icon" sizes="16x16" href="../static/images/favicons/favicon.png">
|
||||
<link rel="shortcut icon" sizes="32x32" href="../static/images/favicons/favicon-32.png">
|
||||
@@ -81,11 +78,11 @@
|
||||
<link rel="apple-touch-icon icon" sizes="152x152" href="../static/images/favicons/favicon-152.png">
|
||||
<link rel="apple-touch-icon icon" sizes="180x180" href="../static/images/favicons/favicon-180.png">
|
||||
<link rel="apple-touch-icon icon" sizes="192x192" href="../static/images/favicons/favicon-192.png">
|
||||
|
||||
|
||||
<!-- Android -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<header role="banner">
|
||||
@@ -112,10 +109,10 @@
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main role="main">
|
||||
<article>
|
||||
|
||||
|
||||
<section class="bg-black">
|
||||
<!-- Overlay/Opacity: [class*="bg-"] > .background.dark or .light -->
|
||||
<span class="background" style="background-image:url('https://source.unsplash.com/E695OZJiju4/1600x800')"></span>
|
||||
@@ -283,11 +280,11 @@
|
||||
</div>
|
||||
<!-- .end .wrap -->
|
||||
</section>
|
||||
|
||||
|
||||
</article>
|
||||
</main>
|
||||
<!--main-->
|
||||
|
||||
|
||||
<footer role="contentinfo">
|
||||
<div class="wrap">
|
||||
<div class="grid">
|
||||
@@ -353,9 +350,9 @@
|
||||
</div>
|
||||
<!-- .end .wrap -->
|
||||
</footer>
|
||||
|
||||
|
||||
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
|
||||
<script defer src="../static/js/svg-icons.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@@ -25,10 +25,7 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
@@ -727,7 +724,7 @@
|
||||
<!-- .end .wrap -->
|
||||
</section>
|
||||
<section class="bg-black aligncenter">
|
||||
<span class="background light" style="background-image:url('https://source.unsplash.com/bopC0sTGu-E/')"></span>
|
||||
<span class="background light" style="background-image:url('https://source.unsplash.com/UxtIESWxLh8/')"></span>
|
||||
<div class="wrap">
|
||||
<h2>Embedding Media</h2>
|
||||
</div>
|
||||
@@ -838,9 +835,9 @@
|
||||
<!-- .end .wrap -->
|
||||
</section>
|
||||
<section class="bg-apple aligncenter">
|
||||
<h2><strong>Thank you!</strong></h2>
|
||||
<h2 class="text-emoji zoomIn">😎</h2>
|
||||
<h3><strong>Thank you!</strong></h2>
|
||||
<p><a href="https://twitter.com/webslides" title="@WebSlides on Twitter">@WebSlides</a></p>
|
||||
<p class="text-symbols">* * *</p>
|
||||
</section>
|
||||
|
||||
</article>
|
||||
@@ -849,7 +846,7 @@
|
||||
|
||||
<!-- Required -->
|
||||
<script src="../static/js/webslides.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
window.ws = new WebSlides();
|
||||
</script>
|
||||
|
@@ -25,10 +25,7 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
@@ -1924,13 +1921,13 @@
|
||||
|
||||
<!-- Required -->
|
||||
<script src="../static/js/webslides.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
window.ws = new WebSlides();
|
||||
</script>
|
||||
|
||||
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
|
||||
<script defer src="../static/js/svg-icons.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -3,76 +3,73 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
|
||||
<!-- CLEAN MARKUP = GOOD KARMA.
|
||||
Hi source code lover,
|
||||
|
||||
|
||||
you're a curious person and a fast learner ;)
|
||||
Let's make something beautiful together. Contribute on Github:
|
||||
https://github.com/webslides/webslides
|
||||
|
||||
|
||||
Thanks!
|
||||
-->
|
||||
|
||||
|
||||
<!-- SEO -->
|
||||
<title>WebSlides Demo: Longforms</title>
|
||||
<meta name="description" content="WebSlides is about telling stories. Create longform articles with ease.">
|
||||
|
||||
|
||||
<!-- URL CANONICAL -->
|
||||
<!-- <link rel="canonical" href="http://your-url.com/permalink"> -->
|
||||
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
|
||||
|
||||
<!-- SOCIAL CARDS (ADD YOUR INFO) -->
|
||||
|
||||
|
||||
<!-- FACEBOOK -->
|
||||
<meta property="og:url" content="https://webslides.tv/demos/why-webslides">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:title" content="WebSlides Demo: Longforms" />
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:description" content="Create longform articles with ease. Just the essentials.">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:updated_time" content="2017-03-28T18:24:48">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:image" content="../static/images/share-webslides.jpg" >
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:image:width" content="800">
|
||||
<meta property="og:image:height" content="429">
|
||||
|
||||
|
||||
<!-- TWITTER -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:site" content="@webslides">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:creator" content="@jlantunez">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:title" content="WebSlides Demo: Longforms">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:description" content="Create longform articles with ease. Just the essentials.">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:image" content="../static/images/share-webslides.jpg">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
|
||||
|
||||
<!-- FAVICONS -->
|
||||
<link rel="shortcut icon" sizes="16x16" href="../static/images/favicons/favicon.png">
|
||||
<link rel="shortcut icon" sizes="32x32" href="../static/images/favicons/favicon-32.png">
|
||||
@@ -81,11 +78,11 @@
|
||||
<link rel="apple-touch-icon icon" sizes="152x152" href="../static/images/favicons/favicon-152.png">
|
||||
<link rel="apple-touch-icon icon" sizes="180x180" href="../static/images/favicons/favicon-180.png">
|
||||
<link rel="apple-touch-icon icon" sizes="192x192" href="../static/images/favicons/favicon-192.png">
|
||||
|
||||
|
||||
<!-- Android -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<header role="banner">
|
||||
@@ -340,11 +337,11 @@
|
||||
</div>
|
||||
<!-- .end .wrap -->
|
||||
</section>
|
||||
|
||||
|
||||
</article>
|
||||
</main>
|
||||
<!--main-->
|
||||
|
||||
|
||||
<footer role="contentinfo">
|
||||
<div class="wrap">
|
||||
<div class="grid">
|
||||
@@ -410,9 +407,9 @@
|
||||
</div>
|
||||
<!-- .end .wrap -->
|
||||
</footer>
|
||||
|
||||
|
||||
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
|
||||
<script defer src="../static/js/svg-icons.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@@ -3,72 +3,69 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
|
||||
<!-- CLEAN MARKUP = GOOD KARMA.
|
||||
Hi source code lover,
|
||||
|
||||
|
||||
you're a curious person and a fast learner ;)
|
||||
Let's make something beautiful together. Contribute on Github:
|
||||
https://github.com/webslides/webslides
|
||||
|
||||
|
||||
Thanks!
|
||||
-->
|
||||
|
||||
|
||||
<!-- SEO -->
|
||||
<title>WebSlides Tutorial: Videos, Images, and Maps</title>
|
||||
<meta name="description" content="How to embed images, videos, and maps in your presentation.">
|
||||
|
||||
|
||||
<!-- URL CANONICAL -->
|
||||
<!-- <link rel="canonical" href="http://your-url.com/permalink"> -->
|
||||
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/colors.css">
|
||||
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/svg-icons.css">
|
||||
|
||||
|
||||
<!-- SOCIAL CARDS (ADD YOUR INFO) -->
|
||||
|
||||
|
||||
<!-- FACEBOOK -->
|
||||
<meta property="og:url" content="/" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:title" content="WebSlides Tutorial: Media" />
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:description" content="How to embed images, videos, and maps in your presentation.">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:updated_time" content="2017-01-04T17:25:31">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:image" content="../static/images/share-webslides.jpg" >
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
|
||||
|
||||
<!-- TWITTER -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:site" content="@webslides">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:creator" content="@jlantunez">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:title" content="WebSlides Tutorial: Media">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:description" content="How to embed images, videos, and maps in your presentation.">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:image" content="../static/images/share-webslides.jpg">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
|
||||
|
||||
<!-- FAVICONS -->
|
||||
<link rel="shortcut icon" sizes="16x16" href="../static/images/favicons/favicon.png">
|
||||
<link rel="shortcut icon" sizes="32x32" href="../static/images/favicons/favicon-32.png">
|
||||
@@ -77,11 +74,11 @@
|
||||
<link rel="apple-touch-icon icon" sizes="152x152" href="../static/images/favicons/favicon-152.png">
|
||||
<link rel="apple-touch-icon icon" sizes="180x180" href="../static/images/favicons/favicon-180.png">
|
||||
<link rel="apple-touch-icon icon" sizes="192x192" href="../static/images/favicons/favicon-192.png">
|
||||
|
||||
|
||||
<!-- Android -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<header role="banner">
|
||||
@@ -108,16 +105,16 @@
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main role="main">
|
||||
<article id="webslides">
|
||||
|
||||
|
||||
<!-- Quick Guide
|
||||
- Each parent <section> in the <article id="webslides"> element is an individual slide.
|
||||
- Vertical sliding = <article id="webslides" class="vertical">
|
||||
- <div class="wrap"> = container 90% / <div class="wrap size-50"> = 45%;
|
||||
-->
|
||||
|
||||
|
||||
<section class="bg-black-blue aligncenter">
|
||||
<span class="background dark" style="background-image:url('https://source.unsplash.com/Zq_K89I9E-8/)"></span>
|
||||
<!--.wrap = container (width: 90%) -->
|
||||
@@ -192,7 +189,6 @@
|
||||
<!-- .end .wrap -->
|
||||
</section>
|
||||
<section>
|
||||
<span class="background-bottom" style="background-image:url('https://source.unsplash.com/GQD3Av_9A88/1600x800)"></span>
|
||||
<div class="wrap aligncenter">
|
||||
<h3>
|
||||
<svg class="fa-camera">
|
||||
@@ -724,7 +720,7 @@
|
||||
<div class="grid">
|
||||
<div class="column">
|
||||
<pre><div class="embed">
|
||||
<strong><div data-youtube data-youtube-id="CQY3KUR3VzM" data-autoplay data-loop>
|
||||
<strong><div data-youtube data-youtube-id="CQY3KUR3VzM" data-autoplay data-loop>
|
||||
</div></strong>
|
||||
</div></pre>
|
||||
<p>autoplay + loop</p>
|
||||
@@ -732,7 +728,7 @@
|
||||
<!-- .end .column -->
|
||||
<div class="column">
|
||||
<pre><div class="embed">
|
||||
<strong><div data-youtube data-youtube-id="CQY3KUR3VzM" data-autoplay data-mute data-no-controls>
|
||||
<strong><div data-youtube data-youtube-id="CQY3KUR3VzM" data-autoplay data-mute data-no-controls>
|
||||
</div></strong>
|
||||
</div></pre>
|
||||
<p>autoplay + mute + no controls.</p>
|
||||
@@ -749,7 +745,7 @@
|
||||
<h3>YouTube API</h3>
|
||||
<p><code>autoplay + loop</code></p>
|
||||
<pre><div class="embed">
|
||||
<div data-youtube data-youtube-id="_m67JbGjWnc" <strong>data-autoplay data-loop</strong>>
|
||||
<div data-youtube data-youtube-id="_m67JbGjWnc" <strong>data-autoplay data-loop</strong>>
|
||||
</div>
|
||||
</div></pre>
|
||||
</div>
|
||||
@@ -876,7 +872,7 @@
|
||||
<li><strong class="text-label" title="Website">Website:</strong> <a href="http://www.visitasevilla.es/en">visitasevilla.es</a></li>
|
||||
</ul>
|
||||
<p>
|
||||
There are many reasons to visit Seville. Its Old Town contains three UNESCO World Heritage Sites: the Alcazar palace complex, the Cathedral and the General Archive of the Indies.
|
||||
There are many reasons to visit Seville. Its Old Town contains three UNESCO World Heritage Sites: the Alcazar palace complex, the Cathedral and the General Archive of the Indies.
|
||||
</p>
|
||||
</div>
|
||||
<!-- end .flex-content-->
|
||||
@@ -887,7 +883,7 @@
|
||||
</section>
|
||||
<section class="fullscreen">
|
||||
<div class="embed">
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3170.254536199183!2d-5.994303837186783!3d37.38381233311839!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0xbaa976bfaec1fe87!2sReal+Alc%C3%A1zar+de+Sevilla!5e0!3m2!1ses!2ses!4v1489408674667" width="800" height="600" allowfullscreen></iframe>
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3170.254536199183!2d-5.994303837186783!3d37.38381233311839!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0xbaa976bfaec1fe87!2sReal+Alc%C3%A1zar+de+Sevilla!5e0!3m2!1ses!2ses!4v1489408674667" width="800" height="600" allowfullscreen></iframe>
|
||||
</div>
|
||||
<!-- .end .embed -->
|
||||
</section>
|
||||
@@ -932,20 +928,20 @@
|
||||
<h2 class="text-emoji zoomIn"><strong><a href="https://webslides.tv" title="WebSlides">😎</a></strong></h2>
|
||||
<h3><a href="https://twitter.com/webslides" title="WebSlides on Twitter">@WebSlides</a></h3>
|
||||
</section>
|
||||
|
||||
|
||||
</article>
|
||||
</main>
|
||||
<!--main-->
|
||||
<!-- Required -->
|
||||
|
||||
|
||||
<script src="../static/js/webslides.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
window.ws = new WebSlides();
|
||||
</script>
|
||||
|
||||
|
||||
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
|
||||
<script defer src="../static/js/svg-icons.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@@ -3,47 +3,44 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
|
||||
<!-- CLEAN MARKUP = GOOD KARMA.
|
||||
Hi source code lover,
|
||||
|
||||
|
||||
you're a curious person and a fast learner ;)
|
||||
Let's make something beautiful together. Contribute on Github:
|
||||
https://github.com/webslides/webslides
|
||||
|
||||
|
||||
Thanks!
|
||||
-->
|
||||
|
||||
|
||||
<!-- SEO -->
|
||||
<title>Netflix's Culture · WebSlides</title>
|
||||
<meta name="description" content="Patty McCord wrote the document called 'Netflix Culture: Freedom & Responsibility'.It's one of the most important documents ever to come out of Silicon Valley.">
|
||||
|
||||
|
||||
<!-- URL CANONICAL -->
|
||||
<!-- <link rel="canonical" href="http://your-url.com/permalink"> -->
|
||||
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
|
||||
|
||||
<!-- SOCIAL CARDS (ADD YOUR INFO) -->
|
||||
|
||||
|
||||
<!-- FACEBOOK -->
|
||||
<!-- EDIT -->
|
||||
<meta property="og:url" content="http://your-url.com/permalink">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:title" content="WebSlides: Netflix's Culture" />
|
||||
<meta property="og:description" content="Patty McCord created Netflix's culture. This is a homage.">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta property="og:updated_time" content="2017-04-16T16:24:56">
|
||||
<!-- EDIT -->
|
||||
@@ -51,11 +48,11 @@
|
||||
<!-- EDIT -->
|
||||
<meta property="og:image:width" content="800">
|
||||
<meta property="og:image:height" content="429">
|
||||
|
||||
|
||||
<!-- TWITTER -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:site" content="@webslides">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:creator" content="@jlantunez">
|
||||
<!-- EDIT -->
|
||||
@@ -64,9 +61,9 @@
|
||||
<meta name="twitter:description" content="Patty McCord created Netflix's culture. This is a homage.">
|
||||
<!-- EDIT -->
|
||||
<meta name="twitter:image" content="../static/images/share-webslides.jpg">
|
||||
|
||||
|
||||
<!-- EDIT -->
|
||||
|
||||
|
||||
<!-- FAVICONS -->
|
||||
<link rel="shortcut icon" sizes="16x16" href="../static/images/favicons/favicon.png">
|
||||
<link rel="shortcut icon" sizes="32x32" href="../static/images/favicons/favicon-32.png">
|
||||
@@ -75,16 +72,16 @@
|
||||
<link rel="apple-touch-icon icon" sizes="152x152" href="../static/images/favicons/favicon-152.png">
|
||||
<link rel="apple-touch-icon icon" sizes="180x180" href="../static/images/favicons/favicon-180.png">
|
||||
<link rel="apple-touch-icon icon" sizes="192x192" href="../static/images/favicons/favicon-192.png">
|
||||
|
||||
|
||||
<!-- Android -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="theme-color" content="#333333">
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<header role="banner">
|
||||
<nav role="navigation">
|
||||
<p class="logo"><a href="https://webslides.tv" title="WebSlides">WebSlides</a></p>
|
||||
<p class="logo"><a href="../index.html" title="WebSlides">WebSlides</a></p>
|
||||
<ul>
|
||||
<li class="github">
|
||||
<a rel="external" href="https://github.com/webslides/webslides" title="Github">
|
||||
@@ -106,16 +103,16 @@
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main role="main">
|
||||
<article id="webslides">
|
||||
|
||||
|
||||
<!-- Quick Guide
|
||||
- Each parent <section> in the <article id="webslides"> element is an individual slide.
|
||||
- Vertical sliding = <article id="webslides" class="vertical">
|
||||
- <div class="wrap"> = container 90% / <div class="wrap size-50"> = 45%;
|
||||
-->
|
||||
|
||||
|
||||
<section class="bg-red">
|
||||
<span class="background dark" style="background-image:url('https://source.unsplash.com/R1J6Z1cnJZc/1600x800')"></span>
|
||||
<!--.wrap = container (width: 90%) -->
|
||||
@@ -365,11 +362,11 @@
|
||||
</div>
|
||||
<!-- .end .wrap -->
|
||||
</section>
|
||||
|
||||
|
||||
</article>
|
||||
</main>
|
||||
<!--main-->
|
||||
|
||||
|
||||
<footer>
|
||||
<div class="wrap">
|
||||
<p>
|
||||
@@ -377,15 +374,15 @@
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
<!-- Required -->
|
||||
<script src="../static/js/webslides.js"></script>
|
||||
<script>
|
||||
window.ws = new WebSlides();
|
||||
</script> <!-- Autoslide? window.ws = new WebSlides({ autoslide: 8000 }); -->
|
||||
|
||||
|
||||
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
|
||||
<script defer src="../static/js/svg-icons.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@@ -25,10 +25,7 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
@@ -1865,7 +1862,7 @@
|
||||
|
||||
<!-- Required -->
|
||||
<script src="../static/js/webslides.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
window.ws = new WebSlides();
|
||||
</script>
|
||||
|
@@ -25,10 +25,7 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/colors.css">
|
||||
<link rel="stylesheet" type='text/css' media='all' href="../static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../static/css/svg-icons.css">
|
||||
@@ -69,7 +66,7 @@
|
||||
<body>
|
||||
<header role="banner">
|
||||
<nav role="navigation">
|
||||
<p class="logo"><a href="https://webslides.tv" title="WebSlides">WebSlides</a></p>
|
||||
<p class="logo"><a href="../index.html" title="WebSlides">WebSlides</a></p>
|
||||
<ul>
|
||||
<li class="github">
|
||||
<a rel="external" href="https://github.com/webslides/webslides" title="Github">
|
||||
@@ -341,7 +338,7 @@
|
||||
|
||||
<!-- Required -->
|
||||
<script src="../static/js/webslides.js"></script>
|
||||
|
||||
|
||||
<!-- Autoslide 5 seconds. If you don't want autoslide, remove: {autoslide: 5000} -->
|
||||
<script>
|
||||
window.ws = new WebSlides({ autoslide: 5000 });
|
||||
|
17
index.html
17
index.html
@@ -25,11 +25,8 @@
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,700,700i%7CMaitree:200,300,400,600,700&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<!-- CSS Base -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="static/css/base.css">
|
||||
|
||||
<!-- CSS Colors -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="static/css/colors.css">
|
||||
<!-- CSS WebSlides -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="static/css/webslides.css">
|
||||
|
||||
<!-- Optional - CSS SVG Icons (Font Awesome) -->
|
||||
<link rel="stylesheet" type='text/css' media='all' href="static/css/svg-icons.css">
|
||||
@@ -297,11 +294,11 @@
|
||||
</svg>
|
||||
<strong>Guides</strong>
|
||||
</h4>
|
||||
<p>If you need help, here's just three tutorials. Just a basic knowledge of HTML is required:</p>
|
||||
<p>If you need help, here's just some tutorials. Just a basic knowledge of HTML is required:</p>
|
||||
<ul class="description">
|
||||
<li><a href="demos/components.html" title="WebSlides Components">WebSlides Components</a>.</li>
|
||||
<li><a href="demos/classes.html" title="WebSlides Classes">WebSlides Classes</a>.</li>
|
||||
<li><a href="demos/media.html" title="WebSlides Media">WebSlides Media: images, videos...</a></li>
|
||||
<li><a href="/demos/components.html" title="WebSlides Components">Components</a> · <a href="/demos/classes.html" title="WebSlides Classes">Classes</a>.</li>
|
||||
<li><a href="https://codepen.io/webslides" title="WebSlides on Codepen">WebSlides on Codepen</a>.</li>
|
||||
<li><a href="/demos/media.html" title="WebSlides Media">WebSlides Media: images, videos...</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="column">
|
||||
@@ -360,7 +357,7 @@
|
||||
</svg>
|
||||
</a>
|
||||
</h2>
|
||||
<p>People share content that makes them feel inspired. WebSlides is a very effective way to engage young audiences, customers, and teams.</p>
|
||||
<p>People share content that makes them feel inspired. WebSlides is a very effective way to engage young audiences, customers, and teams.</p>
|
||||
<p>Best,<br> <a href="https://twitter.com/jlantunez">@jlantunez</a>, <a href="https://twitter.com/belelros">@belelros</a>, and <a href="https://twitter.com/luissacristan">@luissacristan</a>.</p>
|
||||
</div>
|
||||
<!-- .end .content-right -->
|
||||
|
14398
package-lock.json
generated
Normal file
14398
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
94
package.json
94
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "webslides",
|
||||
"version": "1.3.2",
|
||||
"version": "1.5.0",
|
||||
"description": "Making HTML presentations easy",
|
||||
"main": "static/js/webslides.js",
|
||||
"repository": {
|
||||
@@ -19,7 +19,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Antonio Laguna",
|
||||
"email": "a.laguna@funcion13.com"
|
||||
"email": "anlagmat@gmail.com"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
@@ -28,53 +28,65 @@
|
||||
},
|
||||
"homepage": "https://github.com/webslides/webslides#readme",
|
||||
"devDependencies": {
|
||||
"ava": "^0.19.1",
|
||||
"babel-cli": "^6.24.1",
|
||||
"babel-core": "^6.24.1",
|
||||
"babel-loader": "^6.4.1",
|
||||
"babel-preset-env": "^1.4.0",
|
||||
"archiver": "^2.0.3",
|
||||
"autoprefixer": "^7.1.4",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-jest": "^22.0.4",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-preset-env": "^1.6.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"browser-env": "^2.0.30",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-loader": "^1.7.1",
|
||||
"npm-run-all": "^4.0.2",
|
||||
"rimraf": "^2.6.1",
|
||||
"codecov": "^3.0.0",
|
||||
"css-loader": "^0.28.7",
|
||||
"eslint": "^4.7.0",
|
||||
"eslint-loader": "^1.9.0",
|
||||
"eslint-plugin-jest": "^21.1.0",
|
||||
"extract-text-webpack-plugin": "^3.0.0",
|
||||
"jest": "^22.0.4",
|
||||
"node-sass": "4.13.1",
|
||||
"npm-run-all": "^4.1.1",
|
||||
"postcss-loader": "^2.0.6",
|
||||
"pre-commit": "^1.2.2",
|
||||
"rimraf": "^2.6.2",
|
||||
"sass-lint": "^1.11.1",
|
||||
"sass-loader": "^6.0.6",
|
||||
"simulant": "^0.2.2",
|
||||
"smart-banner-webpack-plugin": "^3.0.1",
|
||||
"webpack": "^2.4.1",
|
||||
"webpack-dev-server": "^2.4.2"
|
||||
"style-loader": "^0.19.1",
|
||||
"webpack": "^3.6.0",
|
||||
"webpack-dev-server": "^2.8.2"
|
||||
},
|
||||
"scripts": {
|
||||
"prebuild": "rimraf static/js/webslide*",
|
||||
"build": "npm-run-all --parallel build:*",
|
||||
"build:main": "webpack",
|
||||
"build:main.min": "webpack --output-filename [name].min.js -p",
|
||||
"build": "npm-run-all -s lint build:*",
|
||||
"build:min": "webpack --output-filename [name].min.js -p",
|
||||
"build:normal": "webpack",
|
||||
"lint": "npm-run-all -p lint:*",
|
||||
"lint:js": "eslint ./src/js --cache --ignore-pattern .gitignore",
|
||||
"lint:tests": "eslint ./test --cache --ignore-pattern .gitignore",
|
||||
"lint:css": "sass-lint -v -f stylish",
|
||||
"dev": "webpack-dev-server",
|
||||
"test": "ava test/*.js"
|
||||
"test": "jest && codecov",
|
||||
"preversion": "npm jest",
|
||||
"postversion": "npm run build && git add -A static && node ./zip-release.js && git push && git push --tags"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
[
|
||||
"es2015",
|
||||
{
|
||||
"modules": false
|
||||
},
|
||||
"@ava/stage-4",
|
||||
"@ava/transform-test-files"
|
||||
]
|
||||
"release": {
|
||||
"files": [
|
||||
"demos/**/**",
|
||||
"static/**/**",
|
||||
"*.html",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
]
|
||||
},
|
||||
"ava": {
|
||||
"babel": {
|
||||
"presets": [
|
||||
"es2015",
|
||||
"stage-0",
|
||||
"react"
|
||||
]
|
||||
},
|
||||
"require": [
|
||||
"babel-register",
|
||||
"./test/helpers/setup-browser-env.js"
|
||||
]
|
||||
"jest": {
|
||||
"collectCoverage": true,
|
||||
"testURL": "http://localhost/"
|
||||
},
|
||||
"pre-commit": [
|
||||
"lint"
|
||||
],
|
||||
"dependencies": {
|
||||
"request": "^2.83.0"
|
||||
}
|
||||
}
|
||||
|
7
postcss.config.js
Normal file
7
postcss.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('autoprefixer')({
|
||||
browsers: ['last 2 versions'],
|
||||
})
|
||||
]
|
||||
};
|
@@ -1,3 +1,4 @@
|
||||
import WebSlides from './modules/webslides';
|
||||
require('../scss/full.scss');
|
||||
|
||||
window.WebSlides = WebSlides;
|
||||
|
@@ -8,8 +8,9 @@ const CLASSES = {
|
||||
const Events = {
|
||||
ENTER: 'dom:enter',
|
||||
LEAVE: 'dom:leave',
|
||||
DISABLE: 'slide:disable',
|
||||
ENABLE: 'slide:enable',
|
||||
DISABLE: 'slide:disable'
|
||||
SHOW: 'slide:show'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,7 @@ class Slide {
|
||||
*/
|
||||
this.i = i;
|
||||
|
||||
this.el.id = `section-${(i + 1)}`;
|
||||
this.el.id = this.el.id ? this.el.id : `section-${(i + 1)}`;
|
||||
this.el.classList.add(CLASSES.SLIDE);
|
||||
|
||||
// Hide slides by default
|
||||
@@ -57,6 +58,7 @@ class Slide {
|
||||
show() {
|
||||
DOM.show(this.el);
|
||||
this.el.classList.add(CLASSES.CURRENT);
|
||||
this.fire_(Events.SHOW);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -5,7 +5,8 @@ import scrollTo from '../utils/scroll-to';
|
||||
|
||||
const CLASSES = {
|
||||
VERTICAL: 'vertical',
|
||||
READY: 'ws-ready'
|
||||
READY: 'ws-ready',
|
||||
DISABLED: 'disabled'
|
||||
};
|
||||
|
||||
// Default plugins
|
||||
@@ -19,7 +20,8 @@ const PLUGINS = {
|
||||
'scroll': Plugins.Scroll,
|
||||
'touch': Plugins.Touch,
|
||||
'video': Plugins.Video,
|
||||
'youtube': Plugins.YouTube
|
||||
'youtube': Plugins.YouTube,
|
||||
'zoom': Plugins.Zoom
|
||||
};
|
||||
|
||||
|
||||
@@ -36,18 +38,23 @@ export default class WebSlides {
|
||||
* @param {boolean} loop Whether to go to first slide from last one or not.
|
||||
* @param {number} minWheelDelta Controls the amount of needed scroll to
|
||||
* trigger navigation.
|
||||
* @param {boolean} navigateOnScroll Whether scroll can trigger navigation or
|
||||
* not.
|
||||
* @param {number} scrollWait Controls the amount of time to wait till
|
||||
* navigation can occur again with scroll.
|
||||
* @param {number} slideOffset Controls the amount of needed touch delta to
|
||||
* trigger navigation.
|
||||
* @param {boolean} showIndex Controls if the index can be shown.
|
||||
*/
|
||||
constructor({
|
||||
autoslide = false,
|
||||
changeOnClick = false,
|
||||
loop = true,
|
||||
minWheelDelta = 40,
|
||||
navigateOnScroll = true,
|
||||
scrollWait = 450,
|
||||
slideOffset = 50
|
||||
slideOffset = 50,
|
||||
showIndex = true
|
||||
} = {}) {
|
||||
/**
|
||||
* WebSlide element.
|
||||
@@ -106,8 +113,10 @@ export default class WebSlides {
|
||||
changeOnClick,
|
||||
loop,
|
||||
minWheelDelta,
|
||||
navigateOnScroll,
|
||||
scrollWait,
|
||||
slideOffset
|
||||
slideOffset,
|
||||
showIndex
|
||||
};
|
||||
/**
|
||||
* Initialisation flag.
|
||||
@@ -352,7 +361,7 @@ export default class WebSlides {
|
||||
* @private
|
||||
*/
|
||||
isValidIndexSlide_(i) {
|
||||
return i >= 0 && i < this.maxSlide_;
|
||||
return typeof i === 'number' && i >= 0 && i < this.maxSlide_;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,6 +382,7 @@ export default class WebSlides {
|
||||
// Keeping the order
|
||||
if (slideNumber !== 0) {
|
||||
let i = 0;
|
||||
|
||||
while(i < slideNumber) {
|
||||
this.slides[i].moveAfterLast();
|
||||
i++;
|
||||
@@ -382,6 +392,75 @@ export default class WebSlides {
|
||||
this.goToSlide(slideNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles zoom
|
||||
*/
|
||||
toggleZoom() {
|
||||
if (this.options.showIndex) {
|
||||
this.plugins.zoom.toggleZoom();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the webslides element adding a class "disabled"
|
||||
*/
|
||||
disable() {
|
||||
this.el.classList.add(CLASSES.DISABLED);
|
||||
|
||||
if (this.plugins.autoslide &&
|
||||
this.plugins.autoslide.time !== false) {
|
||||
this.plugins.autoslide.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the webslides element removing a class "disabled"
|
||||
*/
|
||||
enable() {
|
||||
this.el.classList.remove(CLASSES.DISABLED);
|
||||
|
||||
if (this.plugins.autoslide &&
|
||||
this.plugins.autoslide.time !== false) {
|
||||
this.plugins.autoslide.play();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if it is disabled
|
||||
* @return {boolean}
|
||||
*/
|
||||
isDisabled() {
|
||||
return this.el.classList.contains(CLASSES.DISABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the browser into fullscreen
|
||||
*/
|
||||
fullscreen() {
|
||||
const el = document.documentElement;
|
||||
const isFullscreen = document.fullscreen
|
||||
|| document.webkitIsFullScreen
|
||||
|| document.mozFullScreen
|
||||
|| document.msFullScreenElement;
|
||||
|
||||
if (!isFullscreen) {
|
||||
/* istanbul ignore next hard to test prefixes */
|
||||
const requestFullscreen = el.requestFullscreen
|
||||
|| el.webkitRequestFullScreen
|
||||
|| el.mozRequestFullScreen
|
||||
|| el.msRequestFullscreen;
|
||||
requestFullscreen.call(el);
|
||||
} else {
|
||||
/* istanbul ignore next hard to test prefixes */
|
||||
const cancelFullscreen = document.exitFullScreen
|
||||
|| document.webkitCancelFullScreen
|
||||
|| document.mozCancelFullScreen
|
||||
|| document.msExitFullscreen;
|
||||
|
||||
cancelFullscreen.call(document);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a plugin to be loaded when the instance is created. It allows
|
||||
* (on purpose) to replace default plugins.
|
||||
|
@@ -29,15 +29,21 @@ export default class Keyboard {
|
||||
let method;
|
||||
let argument;
|
||||
|
||||
if (DOM.isFocusableElement()) {
|
||||
if (DOM.isFocusableElement() || this.ws_.isDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event.which) {
|
||||
case Keys.AV_PAGE:
|
||||
case Keys.SPACE:
|
||||
method = this.ws_.goNext;
|
||||
break;
|
||||
case Keys.SPACE:
|
||||
if (event.shiftKey) {
|
||||
method = this.ws_.goPrev;
|
||||
} else {
|
||||
method = this.ws_.goNext;
|
||||
}
|
||||
break;
|
||||
case Keys.RE_PAGE:
|
||||
method = this.ws_.goPrev;
|
||||
break;
|
||||
@@ -60,11 +66,19 @@ export default class Keyboard {
|
||||
break;
|
||||
case Keys.RIGHT:
|
||||
method = !this.ws_.isVertical ? this.ws_.goNext : null;
|
||||
break;
|
||||
case Keys.F:
|
||||
if (!event.metaKey && ! event.ctrlKey) {
|
||||
method = this.ws_.fullscreen;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (method) {
|
||||
method.call(this.ws_, argument);
|
||||
// Prevents Firefox key events.
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -48,7 +48,7 @@ export default class Navigation {
|
||||
* Counter Element.
|
||||
* @type {Element}
|
||||
*/
|
||||
this.counter = DOM.createNode('span', ELEMENT_ID.COUNTER);
|
||||
this.counter = Navigation.createCounter(ELEMENT_ID.COUNTER, wsInstance);
|
||||
/**
|
||||
* @type {WebSlides}
|
||||
* @private
|
||||
@@ -60,6 +60,9 @@ export default class Navigation {
|
||||
this.el.appendChild(this.counter);
|
||||
|
||||
this.ws_.el.appendChild(this.el);
|
||||
this.slides = Array.prototype.slice.call(
|
||||
document.querySelectorAll('#webslides section')).map(s => s.id);
|
||||
|
||||
this.bindEvents_();
|
||||
}
|
||||
|
||||
@@ -72,6 +75,30 @@ export default class Navigation {
|
||||
'ws:slide-change', this.onSlideChanged_.bind(this));
|
||||
this.next.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
this.prev.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
this.counter.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
document.body.addEventListener('click', this.onBodyClicked_.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whenever the body is clicked, check if the element has [data-slide] attr
|
||||
* and if so, navigate to it.
|
||||
* @param {MouseEvent} event Click event
|
||||
*/
|
||||
onBodyClicked_(event) {
|
||||
const matches = document.body.matches || document.body.msMatchesSelector;
|
||||
let el;
|
||||
|
||||
if (matches.call(event.target, '[data-slide]')) {
|
||||
el = event.target;
|
||||
} else if (matches.call(event.target, '[data-slide] *')) {
|
||||
el = event.target.querySelector('[data-slide]');
|
||||
}
|
||||
|
||||
if (el) {
|
||||
event.preventDefault();
|
||||
const i = this.slides.indexOf(el.dataset.slide);
|
||||
this.ws_.goToSlide(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +107,11 @@ export default class Navigation {
|
||||
* @param {string|number} max Max slide number.
|
||||
*/
|
||||
updateCounter(current, max) {
|
||||
this.counter.textContent = `${current} / ${max}`;
|
||||
if (this.ws_.options.showIndex) {
|
||||
this.counter.childNodes[0].textContent = `${current} / ${max}`;
|
||||
} else {
|
||||
this.counter.textContent = `${current} / ${max}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,6 +128,24 @@ export default class Navigation {
|
||||
return arrow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the navigation counter.
|
||||
* @param {!String} id Desired ID for the counter.
|
||||
* @param {WebSlides} ws_ WebSlides object.
|
||||
* @return {Element} The arrow element.
|
||||
*/
|
||||
static createCounter(id, ws_) {
|
||||
const counter = DOM.createNode('span', id);
|
||||
if (ws_.options.showIndex) {
|
||||
const link = document.createElement('a');
|
||||
link.href = '#';
|
||||
link.title = 'View all slides';
|
||||
counter.appendChild(link);
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Slide Change event handler. Will update the text on the navigation.
|
||||
* @param {CustomEvent} event
|
||||
@@ -115,8 +164,10 @@ export default class Navigation {
|
||||
event.preventDefault();
|
||||
if (event.target === this.next) {
|
||||
this.ws_.goNext();
|
||||
} else {
|
||||
} else if (event.target === this.prev) {
|
||||
this.ws_.goPrev();
|
||||
} else {
|
||||
this.ws_.toggleZoom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import Scroll from './scroll';
|
||||
import Touch from './touch';
|
||||
import Video from './video';
|
||||
import YouTube from './youtube';
|
||||
import Zoom from './zoom';
|
||||
|
||||
export default {
|
||||
AutoSlide,
|
||||
@@ -19,5 +20,6 @@ export default {
|
||||
Scroll,
|
||||
Touch,
|
||||
Video,
|
||||
YouTube
|
||||
YouTube,
|
||||
Zoom
|
||||
};
|
||||
|
@@ -40,6 +40,11 @@ export default class Scroll {
|
||||
*/
|
||||
this.timeout_ = null;
|
||||
|
||||
// Disabling from option
|
||||
if (!this.ws_.options.navigateOnScroll) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MobileDetector.isAny()) {
|
||||
this.scrollContainer_.addEventListener(
|
||||
'wheel', this.onMouseWheel_.bind(this));
|
||||
@@ -71,11 +76,17 @@ export default class Scroll {
|
||||
* @private
|
||||
*/
|
||||
onMouseWheel_(event) {
|
||||
if (this.ws_.isDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.ws_.isMoving || this.timeout_) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
// Firefox uses lines instead of pixels for delta
|
||||
const linesToPx = event.deltaMode * this.ws_.options.minWheelDelta;
|
||||
const {deltaY: wheelDeltaY, deltaX: wheelDeltaX} = event;
|
||||
const isVertical = this.ws_.isVertical;
|
||||
const isHorizontalMovement = Math.abs(wheelDeltaX) > Math.abs(wheelDeltaY);
|
||||
@@ -94,8 +105,8 @@ export default class Scroll {
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.abs(wheelDeltaY) >= this.ws_.options.minWheelDelta ||
|
||||
Math.abs(wheelDeltaX) >= this.ws_.options.minWheelDelta) {
|
||||
if (Math.abs(wheelDeltaY + linesToPx) >= this.ws_.options.minWheelDelta ||
|
||||
Math.abs(wheelDeltaX + linesToPx) >= this.ws_.options.minWheelDelta) {
|
||||
if ((isHorizontalMovement && this.isGoingLeft_) ||
|
||||
(!isHorizontalMovement && this.isGoingUp_)) {
|
||||
this.ws_.goPrev();
|
||||
|
@@ -63,6 +63,27 @@ export default class Touch {
|
||||
*/
|
||||
this.isEnabled = false;
|
||||
|
||||
/**
|
||||
* Whether is a gesture or not.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.isGesture = false;
|
||||
|
||||
/**
|
||||
* Stores start touch event (x, y).
|
||||
* @type {array}
|
||||
* @private
|
||||
*/
|
||||
this.startTouches = [];
|
||||
|
||||
/**
|
||||
* Stores end touch event (x, y).
|
||||
* @type {array}
|
||||
* @private
|
||||
*/
|
||||
this.endTouches = [];
|
||||
|
||||
let events;
|
||||
|
||||
if (MobileDetector.isAny()) {
|
||||
@@ -87,12 +108,22 @@ export default class Touch {
|
||||
* @private
|
||||
*/
|
||||
onStart_(event) {
|
||||
if (this.ws_.isDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const info = Touch.normalizeEventInfo(event);
|
||||
|
||||
this.startX_ = info.x;
|
||||
this.startY_ = info.y;
|
||||
this.endX_ = info.x;
|
||||
this.endY_ = info.y;
|
||||
if (event.touches.length === 1) {
|
||||
this.startX_ = info.x;
|
||||
this.startY_ = info.y;
|
||||
this.endX_ = info.x;
|
||||
this.endY_ = info.y;
|
||||
} else if (event.touches.length > 1) {
|
||||
this.startTouches = Touch.getTouchCoordinates(event);
|
||||
this.endTouches = this.startTouches;
|
||||
this.isGesture = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,10 +132,18 @@ export default class Touch {
|
||||
* @private
|
||||
*/
|
||||
onMove_(event) {
|
||||
if (this.ws_.isDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const info = Touch.normalizeEventInfo(event);
|
||||
|
||||
this.endX_ = info.x;
|
||||
this.endY_ = info.y;
|
||||
if (this.isGesture) {
|
||||
this.endTouches = Touch.getTouchCoordinates(event);
|
||||
} else {
|
||||
this.endX_ = info.x;
|
||||
this.endY_ = info.y;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,19 +151,57 @@ export default class Touch {
|
||||
* @private
|
||||
*/
|
||||
onStop_() {
|
||||
const diffX = this.startX_ - this.endX_;
|
||||
const diffY = this.startY_ - this.endY_;
|
||||
if (this.ws_.isDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// It's an horizontal drag
|
||||
if (Math.abs(diffX) > Math.abs(diffY)) {
|
||||
if (diffX < -this.ws_.options.slideOffset) {
|
||||
this.ws_.goPrev();
|
||||
} else if(diffX > this.ws_.options.slideOffset) {
|
||||
this.ws_.goNext();
|
||||
if (this.isGesture) {
|
||||
const startDistance = Math.sqrt(
|
||||
Math.pow(this.startTouches[0].x - this.startTouches[1].x, 2) +
|
||||
Math.pow(this.startTouches[0].y - this.startTouches[1].y, 2)
|
||||
);
|
||||
const endDistance = Math.sqrt(
|
||||
Math.pow(this.endTouches[0].x - this.endTouches[1].x, 2) +
|
||||
Math.pow(this.endTouches[0].y - this.endTouches[1].y, 2)
|
||||
);
|
||||
if (startDistance > endDistance) {
|
||||
// Pinch gesture
|
||||
this.ws_.toggleZoom();
|
||||
}
|
||||
this.isGesture = false;
|
||||
} else {
|
||||
const diffX = this.startX_ - this.endX_;
|
||||
const diffY = this.startY_ - this.endY_;
|
||||
|
||||
// It's an horizontal drag
|
||||
if (Math.abs(diffX) > Math.abs(diffY)) {
|
||||
if (diffX < -this.ws_.options.slideOffset) {
|
||||
this.ws_.goPrev();
|
||||
} else if(diffX > this.ws_.options.slideOffset) {
|
||||
this.ws_.goNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get X,Y coordinates from touch pointers.
|
||||
* @param {Event} event
|
||||
* @return {Object}
|
||||
*/
|
||||
static getTouchCoordinates(event) {
|
||||
return [
|
||||
{
|
||||
x: event.touches[0].clientX,
|
||||
y: event.touches[0].clientY
|
||||
},
|
||||
{
|
||||
x: event.touches[1].clientX,
|
||||
y: event.touches[1].clientY
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes an event to deal with differences between PointerEvent and
|
||||
* TouchEvent.
|
||||
|
196
src/js/plugins/zoom.js
Normal file
196
src/js/plugins/zoom.js
Normal file
@@ -0,0 +1,196 @@
|
||||
import DOM from '../utils/dom';
|
||||
import Keys from '../utils/keys';
|
||||
import scrollTo from '../utils/scroll-to';
|
||||
import Slide from '../modules/slide';
|
||||
|
||||
const CLASSES = {
|
||||
ZOOM: 'grid',
|
||||
DIV: 'column',
|
||||
WRAP: 'wrap-zoom',
|
||||
WRAP_CONTAINER: 'wrap',
|
||||
CURRENT: 'current',
|
||||
SLIDE: 'slide',
|
||||
ZOOM_ENABLED: 'ws-ready-zoom'
|
||||
};
|
||||
|
||||
const ID = 'webslides-zoomed';
|
||||
|
||||
/**
|
||||
* Zoom plugin.
|
||||
*/
|
||||
export default class Zoom {
|
||||
/**
|
||||
* @param {WebSlides} wsInstance The WebSlides instance
|
||||
* @constructor
|
||||
*/
|
||||
constructor(wsInstance) {
|
||||
/**
|
||||
* @type {WebSlides}
|
||||
* @private
|
||||
*/
|
||||
this.ws_ = wsInstance;
|
||||
|
||||
/**
|
||||
* @type {WebSlides}
|
||||
* @private
|
||||
*/
|
||||
this.zws_ = {};
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.isZoomed_ = false;
|
||||
|
||||
this.preBuildZoom_();
|
||||
document.body.addEventListener('keydown', this.onKeyDown.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* On key down handler. Will decide if Zoom in or out
|
||||
* @param {Event} event Key down event.
|
||||
*/
|
||||
onKeyDown(event) {
|
||||
if (!this.isZoomed_ && Keys.MINUS.some(key => key === event.which)) {
|
||||
this.zoomIn();
|
||||
} else if (this.isZoomed_ &&
|
||||
(Keys.PLUS.some(key => key === event.which) ||
|
||||
event.which === Keys.ESCAPE)) {
|
||||
this.zoomOut();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare zoom structure, scales the slides and uses a grid layout
|
||||
* to show them.
|
||||
*/
|
||||
preBuildZoom_() {
|
||||
// Clone #webslides element
|
||||
this.zws_.el = this.ws_.el.cloneNode();
|
||||
this.zws_.el.id = ID;
|
||||
this.zws_.wrap = DOM.createNode('div');
|
||||
this.zws_.wrap.className = CLASSES.WRAP_CONTAINER;
|
||||
this.zws_.el.appendChild(this.zws_.wrap);
|
||||
this.zws_.grid = DOM.createNode('div');
|
||||
this.zws_.grid.className = CLASSES.ZOOM;
|
||||
this.zws_.wrap.appendChild(this.zws_.grid);
|
||||
|
||||
this.zws_.el.addEventListener('click', () => this.toggleZoom());
|
||||
|
||||
// Clone the slides
|
||||
this.zws_.slides = [].map.call(this.ws_.slides,
|
||||
(slide, i) => {
|
||||
const s_ = slide.el.cloneNode(true);
|
||||
this.zws_.grid.appendChild(s_);
|
||||
return new Slide(s_, i);
|
||||
});
|
||||
|
||||
this.disable();
|
||||
DOM.after(this.zws_.el, this.ws_.el);
|
||||
|
||||
// Creates the container for each slide
|
||||
this.zws_.slides.forEach(elem => this.createSlideBlock_(elem));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a block structure around the slide.
|
||||
* @param {Element} elem slide element.
|
||||
*/
|
||||
createSlideBlock_(elem) {
|
||||
// Wraps the slide around a container
|
||||
const wrap = DOM.wrap(elem.el, 'div');
|
||||
wrap.className = CLASSES.WRAP;
|
||||
wrap.setAttribute('id', `zoomed-${elem.el.getAttribute('id')}`);
|
||||
|
||||
// Slide container, need due to flexbox styles
|
||||
const div = DOM.wrap(wrap, 'div');
|
||||
div.className = CLASSES.DIV;
|
||||
|
||||
// Adding some layer for controlling click events
|
||||
const divLayer = DOM.createNode('div');
|
||||
divLayer.className = 'zoom-layer';
|
||||
divLayer.addEventListener('click', e => {
|
||||
e.stopPropagation();
|
||||
this.zoomOut();
|
||||
this.ws_.goToSlide(elem.i);
|
||||
});
|
||||
wrap.appendChild(divLayer);
|
||||
|
||||
// Slide number
|
||||
const slideNumber = DOM.createNode('p', '', `${elem.i + 1}`);
|
||||
slideNumber.className = 'text-slide-number';
|
||||
div.appendChild(slideNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles zoom.
|
||||
*/
|
||||
toggleZoom() {
|
||||
if (this.isZoomed_) {
|
||||
this.zoomOut();
|
||||
} else {
|
||||
this.zoomIn();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom In the slider, scales the slides and uses a grid layout to show them.
|
||||
*/
|
||||
zoomIn() {
|
||||
if (!this.ws_.options.showIndex) return;
|
||||
this.enable();
|
||||
const currentId = this.ws_.currentSlide_.el.id;
|
||||
const zoomedCurrent = this.zws_.el
|
||||
.querySelector(`.${CLASSES.WRAP}.${CLASSES.CURRENT}`);
|
||||
|
||||
if (zoomedCurrent) {
|
||||
zoomedCurrent.classList.remove(CLASSES.CURRENT);
|
||||
}
|
||||
|
||||
const actualCurrent = this.zws_.el
|
||||
.querySelector(`#zoomed-${currentId}`);
|
||||
actualCurrent.classList.add(CLASSES.CURRENT);
|
||||
|
||||
this.isZoomed_ = true;
|
||||
document.documentElement.classList.add(CLASSES.ZOOM_ENABLED);
|
||||
|
||||
setTimeout(() => {
|
||||
this.ws_.disable();
|
||||
this.zws_.el.classList.add('in');
|
||||
const wrapCSS = window.getComputedStyle(this.zws_.grid);
|
||||
const scrollingElement = document.body;
|
||||
|
||||
scrollTo(actualCurrent.parentNode.offsetTop
|
||||
+ DOM.parseSize(wrapCSS.paddingTop), 50, () => {}, scrollingElement);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom Out the slider, remove scale from the slides.
|
||||
*/
|
||||
zoomOut() {
|
||||
if (!this.ws_.options.showIndex) return;
|
||||
this.zws_.el.classList.remove('in');
|
||||
|
||||
setTimeout(() => {
|
||||
this.ws_.enable();
|
||||
this.disable();
|
||||
this.isZoomed_ = false;
|
||||
document.documentElement.classList.remove(CLASSES.ZOOM_ENABLED);
|
||||
}, 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the zoom container
|
||||
*/
|
||||
disable() {
|
||||
this.zws_.el.classList.add('disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the zoom container
|
||||
*/
|
||||
enable() {
|
||||
this.zws_.el.classList.remove('disabled');
|
||||
}
|
||||
}
|
@@ -15,6 +15,7 @@ function canIuseNativeCustom() {
|
||||
return 't' === p.type && 'b' === p.detail.a;
|
||||
} catch (e) { }
|
||||
|
||||
/* istanbul ignore next: hard to reproduce on test environment */
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -25,6 +26,7 @@ function canIuseNativeCustom() {
|
||||
* @return {Event}
|
||||
* @constructor
|
||||
*/
|
||||
/* istanbul ignore next: hard to reproduce on test environment */
|
||||
const IECustomEvent = function CustomEvent(type, params) {
|
||||
const e = document.createEvent('CustomEvent');
|
||||
|
||||
@@ -37,6 +39,7 @@ const IECustomEvent = function CustomEvent(type, params) {
|
||||
return e;
|
||||
};
|
||||
|
||||
/* istanbul ignore next: hard to reproduce on test environment */
|
||||
const WSCustomEvent = canIuseNativeCustom() ? NativeCustomEvent : IECustomEvent;
|
||||
|
||||
export default WSCustomEvent;
|
||||
|
@@ -18,7 +18,9 @@ export default class DOM {
|
||||
*/
|
||||
static createNode(tag, id = '', text = '') {
|
||||
const node = document.createElement(tag);
|
||||
node.id = id;
|
||||
if (id) {
|
||||
node.id = id;
|
||||
}
|
||||
|
||||
if (text) {
|
||||
node.textContent = text;
|
||||
@@ -46,14 +48,17 @@ export default class DOM {
|
||||
|
||||
/**
|
||||
* Gets the prefixed transitionend event.
|
||||
* @param {?Element} optEl Element to check
|
||||
* @return {string}
|
||||
*/
|
||||
static getTransitionEvent() {
|
||||
if (transitionEvent) {
|
||||
static getTransitionEvent(optEl) {
|
||||
if (transitionEvent && !optEl) {
|
||||
return transitionEvent;
|
||||
}
|
||||
|
||||
const el = document.createElement('ws');
|
||||
transitionEvent = '';
|
||||
|
||||
const el = optEl || document.createElement('ws');
|
||||
const transitions = {
|
||||
'transition': 'transitionend',
|
||||
'OTransition': 'oTransitionEnd',
|
||||
@@ -76,14 +81,17 @@ export default class DOM {
|
||||
|
||||
/**
|
||||
* Gets the prefixed animation end event.
|
||||
* @param {?Element} optEl Element to check
|
||||
* @return {string}
|
||||
*/
|
||||
static getAnimationEvent() {
|
||||
if (animationEvent) {
|
||||
static getAnimationEvent(optEl) {
|
||||
if (animationEvent && !optEl) {
|
||||
return animationEvent;
|
||||
}
|
||||
|
||||
const el = document.createElement('ws');
|
||||
animationEvent = 'animationend';
|
||||
|
||||
const el = optEl || document.createElement('ws');
|
||||
const animations = {
|
||||
'animation': 'animationend',
|
||||
'OAnimation': 'oAnimationEnd',
|
||||
@@ -93,11 +101,12 @@ export default class DOM {
|
||||
const animationNames = Object.keys(animations);
|
||||
|
||||
for (let i = 0, length = animationNames.length;
|
||||
i < length && !animationEvent; i++) {
|
||||
i < length; i++) {
|
||||
const animationName = animationNames[i];
|
||||
|
||||
if (typeof el.style[animationName] !== 'undefined') {
|
||||
animationEvent = animations[animationName];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +130,15 @@ export default class DOM {
|
||||
el.style.display = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the element is visible.
|
||||
* @param {Element} el Element to check.
|
||||
* @return {boolean}
|
||||
*/
|
||||
static isVisible(el) {
|
||||
return (el.offsetParent !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a custom event on the given target.
|
||||
* @param {Element} target The target of the event.
|
||||
@@ -130,7 +148,8 @@ export default class DOM {
|
||||
*/
|
||||
static fireEvent(target, eventType, eventInfo = {}) {
|
||||
const event = new WSCustomEvent(eventType, {
|
||||
detail: eventInfo
|
||||
detail: eventInfo,
|
||||
bubbles: true
|
||||
});
|
||||
|
||||
target.dispatchEvent(event);
|
||||
@@ -155,14 +174,52 @@ export default class DOM {
|
||||
let result = false;
|
||||
|
||||
if (document.activeElement) {
|
||||
const isContentEditable = document.activeElement
|
||||
.contentEditable !== 'inherit';
|
||||
const isContentEditable =
|
||||
document.activeElement.contentEditable !== 'inherit' &&
|
||||
document.activeElement.contentEditable !== undefined;
|
||||
const isInput = ['INPUT', 'SELECT', 'OPTION', 'TEXTAREA']
|
||||
.indexOf(document.activeElement.tagName) > -1;
|
||||
|
||||
result = isInput || isContentEditable;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the integer value of a style property.
|
||||
* @param {string} prop CSS property value.
|
||||
* @return {Number} The property without the units.
|
||||
*/
|
||||
static parseSize(prop) {
|
||||
return Number(prop.replace(/[^\d\.]/g, ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a HTML structure around an element.
|
||||
* @param {Element} elem the element to be wrapped.
|
||||
* @param {string} tag the new element tag.
|
||||
* @return {Element} the new element.
|
||||
*/
|
||||
static wrap(elem, tag) {
|
||||
const wrap = document.createElement(tag);
|
||||
elem.parentElement.insertBefore(wrap, elem);
|
||||
wrap.appendChild(elem);
|
||||
|
||||
return wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts and element after another element.
|
||||
* @param {Element} elem the element to be inserted.
|
||||
* @param {Element} target the element to be inserted after.
|
||||
*/
|
||||
static after(elem, target) {
|
||||
const parent = target.parentNode;
|
||||
|
||||
if (parent.lastChild === target) {
|
||||
parent.appendChild(elem);
|
||||
} else {
|
||||
parent.insertBefore(elem, target.nextSibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,13 +7,4 @@ function swing(p) {
|
||||
return 0.5 - Math.cos(p * Math.PI) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear easing function.
|
||||
* @param {number} p The percentage of time that has passed.
|
||||
* @return {number}
|
||||
*/
|
||||
function linear(p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
export default {swing, linear};
|
||||
export default {swing};
|
||||
|
@@ -8,7 +8,11 @@ const Keys = {
|
||||
LEFT: 37,
|
||||
UP: 38,
|
||||
RIGHT: 39,
|
||||
DOWN: 40
|
||||
DOWN: 40,
|
||||
PLUS: [107, 171, 187],
|
||||
MINUS: [109, 173, 189],
|
||||
ESCAPE: 27,
|
||||
F: 70
|
||||
};
|
||||
|
||||
export default Keys;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import Easings from './easing';
|
||||
|
||||
const SCROLLABLE_CONTAINER = document.getElementById('webslides');
|
||||
let SCROLLABLE_CONTAINER = document.getElementById('webslides');
|
||||
|
||||
/**
|
||||
* Smoothly scrolls to a given Y position using Easing.Swing. It'll run a
|
||||
@@ -8,8 +8,13 @@ const SCROLLABLE_CONTAINER = document.getElementById('webslides');
|
||||
* @param {number} y Offset of the page to scroll to.
|
||||
* @param {number} duration Duration of the animation. 500ms by default.
|
||||
* @param {function} cb Callback function to call upon completion.
|
||||
* @param {HTMLElement} container The HTML element where to scroll
|
||||
*/
|
||||
export default function scrollTo(y, duration = 500, cb = () => {}) {
|
||||
export default function scrollTo(
|
||||
y, duration = 500, cb = () => {}, container = null) {
|
||||
SCROLLABLE_CONTAINER = container ?
|
||||
container : document.getElementById('webslides');
|
||||
|
||||
const delta = y - SCROLLABLE_CONTAINER.scrollTop;
|
||||
const startLocation = SCROLLABLE_CONTAINER.scrollTop;
|
||||
const increment = 16;
|
||||
|
198
src/scss/_base.scss
Normal file
198
src/scss/_base.scss
Normal file
@@ -0,0 +1,198 @@
|
||||
// sass-lint:disable no-vendor-prefixes
|
||||
|
||||
/*=========================================
|
||||
1. Base --> Baseline: 8px = .8rem
|
||||
=========================================== */
|
||||
|
||||
/* -- Disable elastic scrolling/bounce:
|
||||
webslides.js will add .ws-ready automatically. Don't worry :) -- */
|
||||
|
||||
.ws-ready {
|
||||
&,
|
||||
body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.ws-ready-zoom {
|
||||
overflow: visible;
|
||||
|
||||
body {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#webslides {
|
||||
-ms-overflow-style: none;
|
||||
-webkit-overflow-scrolling: touch; // sass-lint:disable-line no-misspelled-properties
|
||||
height: 100vh;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
li li {
|
||||
margin-left: 1.6rem;
|
||||
}
|
||||
|
||||
a,
|
||||
a:active,
|
||||
a:focus,
|
||||
a:visited,
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
button {
|
||||
text-decoration: none;
|
||||
transition: all .3s ease-out;
|
||||
}
|
||||
|
||||
p a:active {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
nav a[rel='external'] em,
|
||||
.hidden {
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
position: relative;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
bottom: 1.6rem;
|
||||
content: '';
|
||||
max-width: 300px;
|
||||
position: absolute;
|
||||
top: 80%;
|
||||
width: 50%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&:after {
|
||||
right: 2.4rem;
|
||||
transform: rotate(3deg);
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: 2.4rem;
|
||||
transform: rotate(-3deg);
|
||||
}
|
||||
}
|
||||
|
||||
/*=== 1.1 WRAP/CONTAINER === */
|
||||
.wrap,
|
||||
header nav,
|
||||
footer nav {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
.frame,
|
||||
.shadow {
|
||||
padding: 2.4rem;
|
||||
}
|
||||
|
||||
.radius {
|
||||
border-radius: .4rem;
|
||||
}
|
||||
|
||||
.alignright {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.alignleft {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.aligncenter {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img.aligncenter,
|
||||
figure.aligncenter {
|
||||
display: block;
|
||||
margin-bottom: .8rem;
|
||||
margin-top: .8rem;
|
||||
}
|
||||
|
||||
img.alignleft,
|
||||
figure.alignleft,
|
||||
img.alignright,
|
||||
figure.alignright,
|
||||
img.aligncenter,
|
||||
figure.aligncenter {
|
||||
margin-bottom: 3.2rem;
|
||||
margin-top: 3.2rem;
|
||||
}
|
||||
|
||||
img.alignright,
|
||||
svg.alignright,
|
||||
figure.alignright {
|
||||
margin: .8rem 0 .8rem 2.4rem;
|
||||
}
|
||||
|
||||
img.alignleft,
|
||||
svg.alignleft,
|
||||
figure.alignleft {
|
||||
margin: .8rem 2.4rem .8rem 0;
|
||||
}
|
||||
|
||||
$sizes: 80, 70, 60, 50, 40, 30, 20;
|
||||
|
||||
/*=== div.size-60, img.size-50, h1.size-40, p.size-30... === */
|
||||
@media (min-width: 1024px) {
|
||||
@each $size in $sizes {
|
||||
.size-#{$size} {
|
||||
width: $size * 1%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pre,
|
||||
code {
|
||||
font-family: 'Cousine', monospace;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 1.6rem;
|
||||
line-height: 2.4rem;
|
||||
overflow: auto;
|
||||
padding: 2.4rem;
|
||||
text-align: left;
|
||||
white-space: pre-wrap;
|
||||
width: 100%;
|
||||
word-wrap: break-word;
|
||||
|
||||
& + p {
|
||||
margin-top: 3.2rem;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
padding: .4rem;
|
||||
}
|
817
src/scss/_color.scss
Normal file
817
src/scss/_color.scss
Normal file
@@ -0,0 +1,817 @@
|
||||
// sass-lint:disable no-color-literals
|
||||
// sass-lint:disable no-vendor-prefixes
|
||||
|
||||
/*=========================================
|
||||
19. Colors
|
||||
=========================================== */
|
||||
|
||||
/* -- Disable elastic scrolling/bounce:
|
||||
webslides.js will add .ws-ready automatically. Don't worry :) -- */
|
||||
|
||||
body {
|
||||
background-color: $body-bg;
|
||||
color: $body-color;
|
||||
}
|
||||
|
||||
:focus {
|
||||
box-shadow: $focus-box-shadow;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
[class*='bg-'] a,
|
||||
[class*='bg-gradient-'] a {
|
||||
color: $spindle;
|
||||
}
|
||||
|
||||
.bg-brown a {
|
||||
color: $link-color-secondary;
|
||||
}
|
||||
|
||||
a,
|
||||
.bg-white a,
|
||||
.bg-light a,
|
||||
.bg-gradient-white a {
|
||||
color: $link-color;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: $link-hover;
|
||||
}
|
||||
|
||||
.flexblock li>a,
|
||||
[class*='bg-'] li>a,
|
||||
[class*='bg-gradient-'] li>a,
|
||||
article header a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
hr {
|
||||
background: $hr-bg;
|
||||
}
|
||||
|
||||
hr:after {
|
||||
background-color: rgba($white, .8);
|
||||
color: $body-color;
|
||||
}
|
||||
|
||||
abbr,
|
||||
acronym {
|
||||
border-bottom: 1px dotted $body-bg;
|
||||
}
|
||||
|
||||
mark,
|
||||
ins {
|
||||
background-color: rgba($pattens-blue, .8);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background-color: rgba($pattens-blue, .8);
|
||||
}
|
||||
|
||||
::-webkit-selection {
|
||||
background-color: rgba($pattens-blue, .8);
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: rgba($pattens-blue, .8);
|
||||
}
|
||||
|
||||
pre {
|
||||
background: $white;
|
||||
border: 1px solid rgba($stratos, .1);
|
||||
box-shadow: 0 8px 16px rgba($stratos, .04), 0 4px 16px rgba($black, .08);
|
||||
}
|
||||
|
||||
pre:hover {
|
||||
box-shadow: 0 8px 16px rgba(0, 40, 160, .08), 0 8px 24px rgba($black, .08);
|
||||
}
|
||||
|
||||
code,
|
||||
[class*='bg-'] pre {
|
||||
background-color: rgba($white, .09);
|
||||
}
|
||||
|
||||
.bg-white code {
|
||||
background: rgba($stratos, .03);
|
||||
}
|
||||
|
||||
/*================================================
|
||||
Slides - Backgrounds <section class="bg-primary">
|
||||
================================================== */
|
||||
|
||||
/*3 Corp Colors*/
|
||||
@each $name, $color in $bg-colors {
|
||||
.bg-#{$name} {
|
||||
background-color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
[class*='bg-'] .bg-white {
|
||||
color: $body-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* BG Apple Keynote*/
|
||||
.bg-apple {
|
||||
background: linear-gradient(to bottom, $black 0%, #1a2028 50%, #293845 100%);
|
||||
}
|
||||
|
||||
/*Font Color*/
|
||||
.bg-trans-dark,
|
||||
.bg-trans-gradient,
|
||||
.bg-primary,
|
||||
.bg-secondary,
|
||||
.bg-blue,
|
||||
.bg-green,
|
||||
.bg-purple,
|
||||
.bg-red,
|
||||
.bg-facebook,
|
||||
.bg-apple,
|
||||
[class*='bg-black'],
|
||||
[class*='bg-gradient-'] {
|
||||
color: $white;
|
||||
text-shadow: 0 1px 0 #013;
|
||||
}
|
||||
|
||||
.bg-light p {
|
||||
color: #456;
|
||||
}
|
||||
|
||||
.bg-brown p {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/*Transparent/Opacity*/
|
||||
.bg-trans-dark {
|
||||
background: rgba($black, .8);
|
||||
}
|
||||
|
||||
.bg-trans-light {
|
||||
background: rgba($black, .2);
|
||||
}
|
||||
|
||||
/*Covers/Longforms...*/
|
||||
.bg-trans-gradient {
|
||||
background: linear-gradient(to top, rgba($black, .8) 0%, rgba($black, 0) 100%);
|
||||
}
|
||||
|
||||
/*Horizontal Gradient*/
|
||||
.bg-gradient-h {
|
||||
background: linear-gradient(134deg, #32b 0, #62b 100%);
|
||||
}
|
||||
|
||||
/*Vertical Gradient*/
|
||||
.bg-gradient-v {
|
||||
background: linear-gradient(to top, #62b 0%, #32b 100%);
|
||||
}
|
||||
|
||||
/*Radial Gradient*/
|
||||
.bg-gradient-r {
|
||||
background: radial-gradient(ellipse at center, #62b 0%, #32b 100%);
|
||||
}
|
||||
|
||||
/*White Gradient (vertical)*/
|
||||
.bg-gradient-white {
|
||||
background: linear-gradient(180deg, #f2f4f6 0, $white 100%);
|
||||
color: $body-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*Gray Gradient (horizontal)*/
|
||||
.bg-gradient-gray {
|
||||
background: linear-gradient(90deg, #f7f9fb 0, #dee2e6 100%);
|
||||
color: $body-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*Border/Frame*/
|
||||
.frame {
|
||||
border: .8rem solid $white;
|
||||
}
|
||||
|
||||
[class*='background'].frame {
|
||||
border-width: .2rem;
|
||||
}
|
||||
|
||||
/*Layer/Box Shadow*/
|
||||
.shadow,
|
||||
.pre {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.shadow:before,
|
||||
.shadow:after {
|
||||
box-shadow: 0 16px 24px rgba($stratos, .3);
|
||||
}
|
||||
|
||||
/*============================
|
||||
TYPOGRAPHY
|
||||
============================== */
|
||||
|
||||
/* -- Horizontal separator -- */
|
||||
.text-separator:before {
|
||||
background-color: rgba(170, 0, 0, .8);
|
||||
}
|
||||
|
||||
/* -- Pull Quote (Right/Left) -- */
|
||||
[class*='text-pull-'] {
|
||||
border-top: 4px solid rgba($black, .5);
|
||||
}
|
||||
|
||||
img[class*='text-pull-'],
|
||||
figure[class*='text-pull-'] {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
/* -- Context -- */
|
||||
[class*='bg-'] .text-context:before {
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.text-context:before,
|
||||
.bg-white .text-context:before {
|
||||
background-color: rgba($stratos, .2);
|
||||
}
|
||||
|
||||
/* -- Text shadow -- */
|
||||
.text-shadow {
|
||||
text-shadow: 0 0 40px rgba($black, .5);
|
||||
}
|
||||
|
||||
/* -- time, ampersands, prepositions (for, of...), symbols...
|
||||
[class*='card-'] time,
|
||||
h1 span {
|
||||
color: #abd;
|
||||
}
|
||||
|
||||
/* -- <pre> comment -- */
|
||||
.code-comment {
|
||||
color: rgba(70, 170, 130, .9);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Header/Nav
|
||||
=========================================== */
|
||||
header[role='banner'] {
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.logo a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
nav[role='navigation'] li {
|
||||
&.active a {
|
||||
background-color: #555;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
a {
|
||||
background-color: rgba(50, 50, 50, .9);
|
||||
color: $white;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(50, 50, 50, .7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $name, $color in $social-nav {
|
||||
nav li.#{$name} a:hover {
|
||||
background-color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
/*===================================================
|
||||
.flexblock li hover/active
|
||||
===================================================== */
|
||||
.flexblock li.active a,
|
||||
.metrics li:hover,
|
||||
.specs li:hover,
|
||||
.reasons li:hover {
|
||||
background-color: rgba($stratos, .03);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Features & Clients List
|
||||
=========================================== */
|
||||
.features li,
|
||||
.clients li {
|
||||
background-color: rgba($white, .9);
|
||||
}
|
||||
|
||||
[class*='bg-'] .features li,
|
||||
[class*='bg-'] .clients li {
|
||||
background-color: rgba($white, .1);
|
||||
}
|
||||
|
||||
.features li:hover,
|
||||
.clients li:hover {
|
||||
box-shadow: 0 8px 16px rgba($stratos, .02), 0 4px 16px rgba($black, .08);
|
||||
}
|
||||
|
||||
/*============================
|
||||
.flexblock with border
|
||||
============================== */
|
||||
.border {
|
||||
border-bottom: 1px solid rgba($stratos, .1);
|
||||
border-right: 1px solid rgba($stratos, .1);
|
||||
}
|
||||
|
||||
.border li {
|
||||
border-left: 1px solid rgba($stratos, .1);
|
||||
border-top: 1px solid rgba($stratos, .1);
|
||||
}
|
||||
|
||||
.flexblock.border li li {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/*===========================================
|
||||
flexblock.steps
|
||||
============================================= */
|
||||
.steps li:nth-child(1) {
|
||||
background-color: #e8eef7;
|
||||
}
|
||||
|
||||
.steps li:nth-child(2) {
|
||||
background-color: #dde5f3;
|
||||
}
|
||||
|
||||
.steps li:nth-child(3) {
|
||||
background-color: #cdd8ec;
|
||||
}
|
||||
|
||||
.steps li:nth-child(4) {
|
||||
background-color: #bbcdec;
|
||||
}
|
||||
|
||||
.process {
|
||||
border-bottom: 15px solid transparent;
|
||||
border-top: 15px solid transparent;
|
||||
}
|
||||
|
||||
.steps li:hover,
|
||||
.steps.blink li:hover>a {
|
||||
background-color: #b8cef7;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.process.step-2 {
|
||||
border-left-color: #e8eef7;
|
||||
}
|
||||
|
||||
.process.step-3 {
|
||||
border-left-color: #dde5f3;
|
||||
}
|
||||
|
||||
.process.step-4 {
|
||||
border-left-color: #cdd8ec;
|
||||
}
|
||||
|
||||
.steps li:hover + li [class*='step-'] {
|
||||
border-left-color: #b8cef7;
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================
|
||||
Items: You can use for settings, drag&drop, close/delete...
|
||||
=========================================================== */
|
||||
.specs li:after {
|
||||
background: linear-gradient(to right, rgba($stratos, 0) 0%, rgba($stratos, .2) 50%, rgba($stratos, 0) 100%);
|
||||
}
|
||||
|
||||
.specs li:last-child:after {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/*=========================================================
|
||||
Why/Steps/Motivation/Reasons - Decimal/Numbers
|
||||
=========================================================== */
|
||||
.reasons li:after {
|
||||
background: linear-gradient(to right, rgba($stratos, 0) 0%, rgba($stratos, .2) 50%, rgba($stratos, 0) 100%);
|
||||
}
|
||||
|
||||
.reasons li:last-child:after {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Overlays
|
||||
=========================================== */
|
||||
.overlay {
|
||||
background-color: rgba($black, .2);
|
||||
}
|
||||
|
||||
li:hover .overlay {
|
||||
background-color: rgba($black, .1);
|
||||
}
|
||||
|
||||
.overlay,
|
||||
.overlay a {
|
||||
color: $white;
|
||||
text-shadow: 0 1px 0 #111;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Gallery li+.overlay+image
|
||||
=========================================== */
|
||||
.gallery li {
|
||||
background-color: rgba($stratos, .06);
|
||||
box-shadow: 0 1px 1px rgba($black, .2), 0 4px 8px rgba($black, .03);
|
||||
}
|
||||
|
||||
.gallery li figcaption {
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.flexblock.gallery li:hover {
|
||||
box-shadow: 0 1px 1px rgba($black, .2), 0 4px 8px rgba($black, .08);
|
||||
}
|
||||
|
||||
.gallery li footer {
|
||||
border-top: 1px solid rgba($stratos, .1);
|
||||
}
|
||||
|
||||
.gallery li a {
|
||||
color: $body-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.flesblock.gallery li a footer {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
/*Arrow */
|
||||
.gallery li figcaption:before {
|
||||
border: .8rem solid $black;
|
||||
border-color: transparent transparent $white $white;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Plans / Pricing
|
||||
=========================================== */
|
||||
.plans>li div,
|
||||
.flexblock.plans li:hover div {
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.plans>li:hover,
|
||||
.plans>li:nth-child(2) {
|
||||
box-shadow: 0 1px 1px rgba($black, .1), 0 8px 16px rgba($black, .1);
|
||||
}
|
||||
|
||||
.plans:hover li:nth-child(2):not(:hover) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.plans li h2 {
|
||||
background-color: rgba($stratos, .5);
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.plans ul li {
|
||||
border-bottom: 1px solid rgba($stratos, .1);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.plans > li > a {
|
||||
color: $body-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*============================
|
||||
Activity/CV/Timeline/News
|
||||
============================== */
|
||||
.activity li {
|
||||
border-top: .1rem solid rgba($stratos, .1);
|
||||
}
|
||||
|
||||
.activity li:hover {
|
||||
background-color: rgba($stratos, .02);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Resume/Work/CV/Portfolio
|
||||
=========================================== */
|
||||
.work-label,
|
||||
.work li a {
|
||||
border-bottom: 1px solid rgba($stratos, .1);
|
||||
}
|
||||
|
||||
.work li:nth-child(odd)>a {
|
||||
background-color: rgba($stratos, .03);
|
||||
}
|
||||
|
||||
.work li a:hover {
|
||||
background-color: rgba($stratos, .04);
|
||||
}
|
||||
|
||||
/*===========================================
|
||||
Clients / Services / Logos...
|
||||
============================================= */
|
||||
.clients.border figcaption {
|
||||
border-top: 1px solid rgba($stratos, .1);
|
||||
}
|
||||
|
||||
/*====================
|
||||
LOGOS
|
||||
====================== */
|
||||
|
||||
/* --- Images (black logo/image) --- */
|
||||
img.blacklogo {
|
||||
background: none;
|
||||
filter: grayscale(100%) brightness(10%) contrast(100%);
|
||||
}
|
||||
|
||||
/* --- Images (gray logo/image) --- */
|
||||
img.graylogo {
|
||||
filter: grayscale(100%) brightness(10%) contrast(10%);
|
||||
}
|
||||
|
||||
/* --- Images (white Logo/Image) --- */
|
||||
img.whitelogo {
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
/* --- Logo/Images Hover --- */
|
||||
li:hover img.blacklogo,
|
||||
li:hover img.graylogo,
|
||||
img.blacklogo:hover,
|
||||
img.graylogo:hover {
|
||||
background: none;
|
||||
filter: grayscale(0%);
|
||||
transition: all .6s ease;
|
||||
}
|
||||
|
||||
/*=========================================================
|
||||
Cards
|
||||
=========================================================== */
|
||||
[class*='card-'] > a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* --- card ul specs --- */
|
||||
.description>li {
|
||||
border-bottom: 1px solid rgba($stratos, .1);
|
||||
}
|
||||
|
||||
.description>li:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
/*== Figure Background === */
|
||||
[class*='card-'][class*='bg-'] figure {
|
||||
background-color: rgba($stratos, .06);
|
||||
}
|
||||
|
||||
/*== Ficaption Cards === */
|
||||
[class*='card'] figcaption,
|
||||
[class*='card'] figcaption a {
|
||||
background: linear-gradient(to bottom, rgba($black, 0) 0%, rgba($black, .2) 100%);
|
||||
color: $white;
|
||||
}
|
||||
|
||||
/*===CTA (Call to Action - Numbers, Price, Promo...) ===== */
|
||||
@media (min-width: 768px) {
|
||||
.cta .benefit {
|
||||
border-image: linear-gradient(90deg, transparent, rgba($black, .4) 50%, transparent) 1 100%;
|
||||
border-left-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Tables
|
||||
=========================================== */
|
||||
table td,
|
||||
th,
|
||||
thead {
|
||||
border: 1px solid rgba($black, .5);
|
||||
}
|
||||
|
||||
thead {
|
||||
background-color: rgba($black, .3);
|
||||
}
|
||||
|
||||
tr:nth-child(even)>td {
|
||||
background: rgba($black, .1);
|
||||
}
|
||||
|
||||
tr>td {
|
||||
border-top: 1px solid rgba($black, .5);
|
||||
}
|
||||
|
||||
td:hover,
|
||||
tr:nth-child(even)>td:hover {
|
||||
background-color: rgba($white, .5);
|
||||
}
|
||||
|
||||
/*============================
|
||||
Browser (Screenshots)
|
||||
============================== */
|
||||
.browser {
|
||||
border: 1px solid rgba($stratos, .1);
|
||||
}
|
||||
|
||||
.browser:hover {
|
||||
box-shadow: 0 1px 1px rgba($black, .1), 0 8px 16px rgba($black, .1);
|
||||
}
|
||||
|
||||
/*=== Topbar === */
|
||||
.browser:before {
|
||||
background-color: rgba($stratos, .1);
|
||||
border-bottom: 1px solid rgba($stratos, .2);
|
||||
color: rgba($white, .9);
|
||||
}
|
||||
|
||||
.browser:hover:before {
|
||||
background-color: rgba($stratos, .12);
|
||||
color: $white;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Forms
|
||||
=========================================== */
|
||||
input,
|
||||
textarea {
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus {
|
||||
background-color: $white;
|
||||
box-shadow: 0 0 5px rgba(81, 203, 238, 1);
|
||||
}
|
||||
|
||||
input:focus::-moz-placeholder {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
input:focus::-webkit-input-placeholder {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
a.button,
|
||||
[class*='badge-'],
|
||||
button[type='submit'],
|
||||
input {
|
||||
box-shadow: 0 10px 16px -8px rgba($stratos, .3);
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
button[type='submit'],
|
||||
input[type='submit'],
|
||||
.button,
|
||||
.button:hover,
|
||||
button[type='submit']:hover,
|
||||
input[type='submit']:hover {
|
||||
border: 1px solid $royal-blue;
|
||||
}
|
||||
|
||||
button[type='submit'],
|
||||
input[type='submit'],
|
||||
.button,
|
||||
.button:hover,
|
||||
button[type='submit']:hover,
|
||||
input[type='submit']:hover {
|
||||
background-color: $royal-blue;
|
||||
color: $white;
|
||||
text-shadow: 0 1px 0 #123;
|
||||
}
|
||||
|
||||
.button:active,
|
||||
button[type='submit']:active,
|
||||
input[type='submit']:active {
|
||||
background-color: #17d;
|
||||
}
|
||||
|
||||
.ghost,
|
||||
.ghost:hover {
|
||||
background: none;
|
||||
color: inherit;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.bg-primary select,
|
||||
.bg-primary textarea,
|
||||
.bg-primary .button,
|
||||
.bg-primary button,
|
||||
.bg-primary button:hover,
|
||||
.bg-primary input,
|
||||
[class*='bg-gradient-'] .button,
|
||||
[class*='bg-'] a.button.ghost {
|
||||
border-color: $white;
|
||||
}
|
||||
|
||||
[class*='bg-'] a.button {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.bg-white a.button.ghost,
|
||||
.bg-gradient-white a.button.ghost {
|
||||
border: 1px solid $royal-blue;
|
||||
color: $body-color;
|
||||
}
|
||||
|
||||
:disabled,
|
||||
button:disabled:hover {
|
||||
background-color: #eee;
|
||||
border-color: #eee;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
background-color: rgba($stratos, .2);
|
||||
border: 1px solid $royal-blue;
|
||||
}
|
||||
|
||||
legend {
|
||||
background-color: rgba($black, .6);
|
||||
color: $white;
|
||||
}
|
||||
|
||||
/* Inputs/Buttons - hover */
|
||||
input:hover,
|
||||
select:hover {
|
||||
box-shadow: 0 0 8px rgba($black, .3);
|
||||
}
|
||||
|
||||
/* App Store Badges */
|
||||
[class*='badge-'] {
|
||||
background-color: $black;
|
||||
border: 1px solid #345;
|
||||
}
|
||||
|
||||
form .flexblock li:hover {
|
||||
background-color: rgba($black, .05);
|
||||
}
|
||||
|
||||
/*============================
|
||||
Table of Contents
|
||||
============================== */
|
||||
.toc,
|
||||
.toc ol>li:before,
|
||||
.chapter {
|
||||
background-color: #f7f9fb;
|
||||
}
|
||||
|
||||
.toc li .toc-page:before {
|
||||
border-bottom: 1px dotted rgba($black, .9);
|
||||
}
|
||||
|
||||
/*============================
|
||||
Slides (Counter/Arrows)
|
||||
============================== */
|
||||
#counter,
|
||||
#navigation a {
|
||||
color: #abc;
|
||||
}
|
||||
|
||||
#webslides:hover #navigation a:hover {
|
||||
background-color: $index-overlay;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
/*============================
|
||||
Footer
|
||||
============================== */
|
||||
footer[role='contentinfo'] {
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
/*============================
|
||||
Slides Index
|
||||
============================== */
|
||||
#webslides-zoomed {
|
||||
background: $index-overlay;
|
||||
}
|
||||
|
||||
#webslides-zoomed .column > .wrap-zoom {
|
||||
background-color: $catskill-white;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 4px 8px rgba(0, 0, 0, .04);
|
||||
color: $mine-shaft;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 4px 8px rgba(0, 0, 0, .08);
|
||||
}
|
||||
|
||||
&.current {
|
||||
border: .6rem solid rgba(0, 20, 280, .2);
|
||||
}
|
||||
}
|
||||
|
||||
.text-slide-number {
|
||||
color: #abc;
|
||||
}
|
468
src/scss/_typography.scss
Normal file
468
src/scss/_typography.scss
Normal file
@@ -0,0 +1,468 @@
|
||||
/*============================
|
||||
2. TYPOGRAPHY & LISTS
|
||||
============================== */
|
||||
html,
|
||||
body {
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: 'Roboto', 'San Francisco', helvetica, arial, sans-serif;
|
||||
font-size: 62.5%;
|
||||
}
|
||||
|
||||
body,
|
||||
textarea {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
p,
|
||||
li,
|
||||
dt,
|
||||
dd,
|
||||
time,
|
||||
table,
|
||||
big,
|
||||
textarea,
|
||||
label {
|
||||
line-height: 3.2rem;
|
||||
margin-bottom: 3.2rem;
|
||||
}
|
||||
|
||||
li,
|
||||
p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
ul>li,
|
||||
ol>li {
|
||||
margin-left: 3.2rem;
|
||||
}
|
||||
|
||||
li li {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
/*== List .description (Product/Specs) === */
|
||||
ul.description {
|
||||
padding: 0;
|
||||
|
||||
& + p {
|
||||
margin-top: 3.2rem;
|
||||
}
|
||||
|
||||
li {
|
||||
padding-bottom: .8rem;
|
||||
padding-top: .8rem;
|
||||
position: relative;
|
||||
transition: .3s;
|
||||
}
|
||||
|
||||
li:hover {
|
||||
padding-left: .4rem;
|
||||
}
|
||||
}
|
||||
|
||||
ul.description li,
|
||||
.column ul li {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.column ol>li {
|
||||
margin-left: 1.6rem;
|
||||
}
|
||||
|
||||
h1 svg,
|
||||
h2 svg,
|
||||
h3 svg,
|
||||
h4 svg {
|
||||
margin-top: -.8rem;
|
||||
}
|
||||
|
||||
.text-intro svg,
|
||||
.text-quote p svg,
|
||||
.wall p svg,
|
||||
.try svg {
|
||||
margin-top: -.4rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
line-height: 5.6rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 5.6rem;
|
||||
line-height: 7.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h1 span {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 3.2rem;
|
||||
line-height: 4.8rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 4.8rem;
|
||||
line-height: 6.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 2.4rem;
|
||||
line-height: 4rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 4rem;
|
||||
line-height: 5.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 2.2rem;
|
||||
line-height: 4rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 3.2rem;
|
||||
line-height: 4.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
line-height: 3.2rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 600;
|
||||
line-height: 3.2rem;
|
||||
}
|
||||
|
||||
h2.alignleft + p.alignright {
|
||||
margin-bottom: 0;
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
|
||||
h3.alignleft + p.alignright {
|
||||
margin-bottom: 0;
|
||||
margin-top: .4rem;
|
||||
}
|
||||
|
||||
@for $i from 1 through 6 {
|
||||
@for $j from 1 through 6 {
|
||||
h#{$i}+h#{$j} {
|
||||
margin-top: .8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h1+img,
|
||||
h2+img,
|
||||
h3+img {
|
||||
margin-bottom: 4.8rem;
|
||||
margin-top: 4.8rem;
|
||||
}
|
||||
|
||||
[class*='content-'] > [class*='content-'] h2,
|
||||
[class*='content-'] > [class*='content-'] h3,
|
||||
[class*='content-'] > [class*='content-'] h4 {
|
||||
font-size: 2.4rem;
|
||||
line-height: 4rem;
|
||||
}
|
||||
|
||||
/*== 2.1. Headings with background ==*/
|
||||
@for $i from 1 through 6 {
|
||||
h#{$i}[class*='bg-'] {
|
||||
padding: 2.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul[class*='bg-'],
|
||||
ol[class*='bg-'],
|
||||
li[class*='bg-'],
|
||||
p[class*='bg-'] {
|
||||
padding: 2.4rem;
|
||||
}
|
||||
|
||||
h1 [class*='bg-'],
|
||||
h2 [class*='bg-'],
|
||||
h3 [class*='bg-'] {
|
||||
padding: .4rem .8rem;
|
||||
}
|
||||
|
||||
/*== 2.2. Typography Classes = .text- == */
|
||||
.text-intro,
|
||||
[class*='content-'] p {
|
||||
font-size: 2.4rem;
|
||||
line-height: 4rem;
|
||||
}
|
||||
|
||||
/* -- Serif -- */
|
||||
.text-serif,
|
||||
h1 span {
|
||||
font-family: 'Maitree', times, serif;
|
||||
}
|
||||
|
||||
/* -- h1,h2... Promo/Landings -- */
|
||||
.text-landing {
|
||||
letter-spacing: .4rem;
|
||||
text-transform: uppercase;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
letter-spacing: 1.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Subtitle (Before h1, h2) p.subtitle + h1/h2 */
|
||||
.text-subtitle {
|
||||
letter-spacing: .2rem;
|
||||
margin-bottom: 0;
|
||||
text-transform: uppercase;
|
||||
|
||||
p#{&} {
|
||||
font-size: 1.6rem;
|
||||
|
||||
svg {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
}
|
||||
|
||||
+ p {
|
||||
margin-top: 3.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.text-uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.text-lowercase {
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
/* -- Emoji (you'll love this) -- */
|
||||
.text-emoji {
|
||||
font-size: 6.8rem;
|
||||
line-height: 8.8rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 12.8rem;
|
||||
line-height: 16rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Numbers (results, sales... 23,478,289 iphones) -- */
|
||||
.text-data {
|
||||
font-size: 6.4rem;
|
||||
line-height: 8rem;
|
||||
margin-bottom: .8rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 15.2rem;
|
||||
line-height: 16.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.text-label {
|
||||
display: inline-block;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
width: 12.8rem;
|
||||
}
|
||||
|
||||
/* -- Magazine Two Columns -- */
|
||||
@media (min-width: 768px) {
|
||||
.text-cols {
|
||||
column-count: 2;
|
||||
column-gap: 4.8rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.text-landing + .text-cols {
|
||||
margin-top: 3.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.text-cols p:first-child:first-letter {
|
||||
float: left;
|
||||
font-size: 11rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
margin: -.4rem 1.6rem 0 0;
|
||||
padding: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* -- Heading with border -- */
|
||||
.text-context {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
height: .2rem;
|
||||
margin-bottom: .6rem;
|
||||
width: 12rem;
|
||||
|
||||
.column & {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.text-uppercase {
|
||||
letter-spacing: .1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Separator/Symbols (stars ***...) -- */
|
||||
.text-symbols {
|
||||
font-weight: 600;
|
||||
letter-spacing: .8rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-separator {
|
||||
margin-top: 2.4rem;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
height: .4rem;
|
||||
left: 0;
|
||||
margin-top: -1.6rem;
|
||||
position: absolute;
|
||||
width: 16%;
|
||||
}
|
||||
|
||||
@media (min-width: 568px) {
|
||||
margin-left: 20%;
|
||||
margin-top: 0;
|
||||
width: 80%;
|
||||
|
||||
&:before {
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Pull Quote (Right/Left) -- */
|
||||
[class*='text-pull'] {
|
||||
font-size: 2.4rem;
|
||||
font-weight: 400;
|
||||
line-height: 4rem;
|
||||
margin-bottom: 3.2rem;
|
||||
margin-left: 2.4rem;
|
||||
margin-right: 2.4rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[class*='text-pull-'] {
|
||||
margin-top: .8rem;
|
||||
padding-top: 1.4rem;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
margin-left: -4.8rem;
|
||||
margin-right: -4.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 568px) {
|
||||
[class*='text-pull-'] {
|
||||
max-width: 40%;
|
||||
}
|
||||
|
||||
.text-pull-right {
|
||||
float: right;
|
||||
margin-left: 2.4rem;
|
||||
margin-right: -2.4rem;
|
||||
}
|
||||
|
||||
.text-pull-left {
|
||||
float: left;
|
||||
margin-left: -2.4rem;
|
||||
margin-right: 2.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
img[class*='text-pull-'],
|
||||
figure[class*='text-pull-'] {
|
||||
margin-top: .8rem;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
/* -- Interviews (Questions & Answers) --- */
|
||||
/* -- <dl class="text-interview">
|
||||
<dt>name</dt>
|
||||
<dd><p>question or answer</p>
|
||||
</dd>
|
||||
--- */
|
||||
.text-interview dt {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.text-interview dt {
|
||||
margin-left: -34%;
|
||||
position: absolute;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -- Info Messages (error, warning, success... -- */
|
||||
.text-info {
|
||||
font-size: 1.6rem;
|
||||
line-height: 2.4rem;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
2.1. San Francisco Font (Apple's new font)
|
||||
=========================================== */
|
||||
.text-apple,
|
||||
.bg-apple {
|
||||
font-family: 'San Francisco', helvetica, arial, sans-serif;
|
||||
}
|
||||
|
||||
/* Ultra Light */
|
||||
@font-face {
|
||||
font-family: 'San Francisco';
|
||||
font-weight: 100;
|
||||
src: url('https://applesocial.s3.amazonaws.com/assets/styles/fonts/sanfrancisco/sanfranciscodisplay-ultralight-webfont.woff2');
|
||||
}
|
||||
|
||||
/* Thin */
|
||||
@font-face {
|
||||
font-family: 'San Francisco';
|
||||
font-weight: 200;
|
||||
src: url('https://applesocial.s3.amazonaws.com/assets/styles/fonts/sanfrancisco/sanfranciscodisplay-thin-webfont.woff2');
|
||||
}
|
||||
|
||||
/* Regular */
|
||||
@font-face {
|
||||
font-family: 'San Francisco';
|
||||
font-weight: 400;
|
||||
src: url('https://applesocial.s3.amazonaws.com/assets/styles/fonts/sanfrancisco/sanfranciscodisplay-regular-webfont.woff2');
|
||||
}
|
||||
|
||||
/* Bold */
|
||||
@font-face {
|
||||
font-family: 'San Francisco';
|
||||
font-weight: bold;
|
||||
src: url('https://applesocial.s3.amazonaws.com/assets/styles/fonts/sanfrancisco/sanfranciscodisplay-bold-webfont.woff2');
|
||||
}
|
63
src/scss/_vars.scss
Normal file
63
src/scss/_vars.scss
Normal file
@@ -0,0 +1,63 @@
|
||||
// sass-lint:disable no-color-literals
|
||||
|
||||
// =========
|
||||
// Colors. Names from http://chir.ag/projects/name-that-color/
|
||||
// =========
|
||||
$black: #000;
|
||||
$white: #fff;
|
||||
$mine-shaft: #333;
|
||||
$royal-blue: #44d;
|
||||
$havelock-blue: #67d;
|
||||
$catskill-white: #f7f9fb;
|
||||
$cod-gray: #111;
|
||||
$big-stone: #123;
|
||||
$rhino: #346;
|
||||
$athens-gray: #f8f8f9;
|
||||
$mischka: #d5d9e2;
|
||||
$pine-green: #077;
|
||||
$purple-heart: #62b;
|
||||
$cardinal: #c23;
|
||||
$mirage: #1a2028;
|
||||
$pickled-bluewood: #293845;
|
||||
$facebook: #3b5998;
|
||||
$spindle: #bce;
|
||||
$dodger-blue: #3af;
|
||||
$pattens-blue: #def;
|
||||
$stratos: #001450;
|
||||
$gray-brown: #f9f8f2;
|
||||
|
||||
$bg-colors: (
|
||||
'primary': $royal-blue,
|
||||
'secondary': $havelock-blue,
|
||||
'light': $catskill-white,
|
||||
'black': $cod-gray,
|
||||
'black-blue': $big-stone,
|
||||
'blue': $rhino,
|
||||
'brown': $gray-brown,
|
||||
'gray': $mischka,
|
||||
'green': $pine-green,
|
||||
'purple': $purple-heart,
|
||||
'red': $cardinal,
|
||||
'white': $white,
|
||||
// Branding
|
||||
'facebook': $facebook
|
||||
) !default;
|
||||
|
||||
$social-nav: (
|
||||
'twitter': #1da1f3,
|
||||
'facebook': $facebook,
|
||||
'linkedin': #1683bb,
|
||||
'dribbble': #ea4c89,
|
||||
'github': #60b044,
|
||||
'email': #dd4b39
|
||||
) !default;
|
||||
|
||||
$body-color: $mine-shaft !default;
|
||||
$body-bg: $catskill-white !default;
|
||||
$focus-box-shadow: 0 0 2px rgba(150, 187, 238, 1) !default;
|
||||
$link-color: $royal-blue !default;
|
||||
$link-color-secondary: $cardinal !default;
|
||||
$link-hover: $dodger-blue !default;
|
||||
$hr-bg: radial-gradient(ellipse at center, rgba(0, 20, 80, .2) 0, rgba(255, 255, 255, 0) 75%) !default;
|
||||
$current-zoomed-slide-shadow: 0 0 7px rgba(0, 187, 255, .5);
|
||||
$index-overlay: rgba(0, 10, 40, .8);
|
98
src/scss/full.scss
Normal file
98
src/scss/full.scss
Normal file
@@ -0,0 +1,98 @@
|
||||
/*-----------------------------------------------------------------------------------
|
||||
0. CSS Reset & Normalize
|
||||
1. Base
|
||||
1.1 Wrap/Container
|
||||
1.2 Animations
|
||||
1.3 Responsive Media (videos, iframe, screenshots...)
|
||||
1.4 Basic Grid (2,3,4 columns)
|
||||
2. Typography & Lists
|
||||
2.1 Headings with background
|
||||
2.2 Classes: .text-
|
||||
2.3 San Francisco Font (Apple)
|
||||
3. Header & Footer
|
||||
3.1 Logo
|
||||
4. Navigation
|
||||
4.1 Navbars
|
||||
5. SLIDES (vertically and horizontally centered)
|
||||
5.1 Mini container & Alignment
|
||||
5.2 Counter / Navigation Slides
|
||||
5.3 Background Images/Video
|
||||
6. Magic blocks = .flexblock (Flexible blocks with auto-fill and equal height).
|
||||
6.1 .flexblock.features
|
||||
6.2 .flexblock.clients
|
||||
6.3 .flexblock.steps
|
||||
6.4 .flexblock.metrics
|
||||
6.5 .flexblock.specs
|
||||
6.6 .flexblock.reasons
|
||||
6.7 .flexblock.gallery
|
||||
6.8 .flexblock.plans
|
||||
6.9. flexblock.activity
|
||||
7. Promos/Offers (pricing, tagline, CTA...)
|
||||
8. Work / Resume / CV
|
||||
9. Table of contents
|
||||
10. Cards
|
||||
11. Quotes
|
||||
12. Avatars
|
||||
13. Tables
|
||||
14. Forms
|
||||
15. Longform Elements
|
||||
16. Safari Bug (flex-wrap)
|
||||
17. Slidex index (aka zoom)
|
||||
18. Print
|
||||
19. Colors
|
||||
----------------------------------------------------------------------------------- */
|
||||
|
||||
@import 'vars';
|
||||
@import 'utils/mixins';
|
||||
@import 'utils/reset';
|
||||
@import 'utils/clear';
|
||||
|
||||
@import 'base';
|
||||
@import 'utils/animations';
|
||||
@import 'modules/media';
|
||||
@import 'modules/browser';
|
||||
@import 'modules/grid';
|
||||
|
||||
@import 'typography';
|
||||
|
||||
@import 'modules/header-footer';
|
||||
@import 'modules/logo';
|
||||
@import 'modules/navigation';
|
||||
|
||||
@import 'modules/slides';
|
||||
@import 'modules/slides-bg';
|
||||
@import 'modules/slides-navigation';
|
||||
|
||||
@import 'modules/flexblock';
|
||||
@import 'modules/flexblock-features';
|
||||
@import 'modules/flexblock-clients';
|
||||
@import 'modules/flexblock-steps';
|
||||
@import 'modules/flexblock-metrics';
|
||||
@import 'modules/flexblock-specs';
|
||||
@import 'modules/flexblock-reasons';
|
||||
@import 'modules/flexblock-gallery';
|
||||
@import 'modules/flexblock-plans';
|
||||
@import 'modules/flexblock-activity';
|
||||
@import 'modules/promos';
|
||||
@import 'modules/work';
|
||||
@import 'modules/toc';
|
||||
|
||||
@import 'modules/cards';
|
||||
|
||||
@import 'modules/quotes';
|
||||
@import 'modules/avatars';
|
||||
|
||||
@import 'modules/tables';
|
||||
|
||||
@import 'modules/form';
|
||||
@import 'modules/button';
|
||||
@import 'modules/badges';
|
||||
|
||||
@import 'modules/longform';
|
||||
|
||||
@import 'utils/bugs';
|
||||
@import 'modules/zoom';
|
||||
|
||||
@import 'modules/print';
|
||||
|
||||
@import 'color';
|
22
src/scss/modules/_avatars.scss
Normal file
22
src/scss/modules/_avatars.scss
Normal file
@@ -0,0 +1,22 @@
|
||||
/*=========================================
|
||||
12. Avatars - uifaces.com
|
||||
=========================================== */
|
||||
|
||||
cite img,
|
||||
img[class*='avatar-'] {
|
||||
display: inline-block;
|
||||
margin-right: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
img[class*='avatar-'] {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
$avatar-sizes: 40, 48, 56, 64, 72, 80;
|
||||
|
||||
@each $size in $avatar-sizes {
|
||||
img.avatar-#{$size} {
|
||||
@include square(#{$size}px);
|
||||
}
|
||||
}
|
43
src/scss/modules/_badges.scss
Normal file
43
src/scss/modules/_badges.scss
Normal file
@@ -0,0 +1,43 @@
|
||||
/*=== App Store Badges === */
|
||||
/* Change width and height: 216x64px, 162x48px, 135x40... */
|
||||
|
||||
[class*='badge-'] {
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: .6rem;
|
||||
display: inline-block;
|
||||
height: 40px;
|
||||
line-height: 4rem;
|
||||
text-indent: -4000px;
|
||||
width: 135px;
|
||||
|
||||
&:hover {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
height: 48px;
|
||||
line-height: 4.8rem;
|
||||
width: 162px;
|
||||
}
|
||||
|
||||
@media (min-width: 500px) {
|
||||
& + & {
|
||||
margin-left: 1.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 499px) {
|
||||
& + & {
|
||||
margin-top: .8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.badge-ios {
|
||||
background-image: url('../images/bt-appstore.png');
|
||||
}
|
||||
|
||||
.badge-android {
|
||||
background-image: url('../images/bt-playstore.png');
|
||||
}
|
39
src/scss/modules/_browser.scss
Normal file
39
src/scss/modules/_browser.scss
Normal file
@@ -0,0 +1,39 @@
|
||||
/*=== HTML Browser (Screenshots) ================ */
|
||||
/* <figure class="browser"> img </figure> */
|
||||
|
||||
.browser {
|
||||
border-radius: .3rem;
|
||||
margin: 0 auto 3.2rem;
|
||||
max-width: 1024px;
|
||||
overflow: hidden;
|
||||
|
||||
li & {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h1 + &,
|
||||
h2 + &,
|
||||
p + & {
|
||||
margin-top: 4.8rem;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
padding: 2.4rem;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '● ● ●';
|
||||
font-size: .8rem;
|
||||
left: 0;
|
||||
line-height: 0;
|
||||
padding: 1.6rem;
|
||||
position: absolute;
|
||||
text-align: left;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
}
|
||||
}
|
14
src/scss/modules/_button.scss
Normal file
14
src/scss/modules/_button.scss
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Buttons/Badges */
|
||||
[class*='button'] {
|
||||
@media (min-width: 500px) {
|
||||
& + & {
|
||||
margin-left: 1.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 499px) {
|
||||
& + & {
|
||||
margin-top: .8rem;
|
||||
}
|
||||
}
|
||||
}
|
140
src/scss/modules/_cards.scss
Normal file
140
src/scss/modules/_cards.scss
Normal file
@@ -0,0 +1,140 @@
|
||||
/*===========================================
|
||||
10. Cards
|
||||
============================================= */
|
||||
|
||||
[class*='card-'] {
|
||||
&,
|
||||
& > a {
|
||||
clear: both;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fullscreen &,
|
||||
.fullscreen & > a {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
figure img,
|
||||
figure iframe {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
figure figcaption {
|
||||
bottom: 0;
|
||||
font-size: 1.4rem;
|
||||
left: 0;
|
||||
line-height: 2.4rem;
|
||||
padding: .8rem 2.4rem;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
|
||||
svg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
[class*='card'][class*='bg-'] figure,
|
||||
.fullscreen [class*='card'] figure {
|
||||
max-height: 100%;
|
||||
min-width: 380px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
[class*='card-'][class*='bg-'] figure img,
|
||||
[class*='card-'][class*='bg-'] figure iframe,
|
||||
.fullscreen [class*='card-'] figure img,
|
||||
.fullscreen [class*='card-'] figure iframe {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
object-fit: cover;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.flex-content,
|
||||
[class*='card'] blockquote {
|
||||
padding: 2.4rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[class*='card-'] .flex-content,
|
||||
[class*='card-'] blockquote {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-content p {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card-50 figure,
|
||||
.card-50 blockquote,
|
||||
.card-50 .flex-content {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.card-30 figure,
|
||||
.card-70 .flex-content,
|
||||
.card-70 blockquote {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.card-40 figure,
|
||||
.card-60 .flex-content,
|
||||
.card-60 blockquote {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.card-60 figure,
|
||||
.card-40 .flex-content,
|
||||
.card-40 blockquote {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.card-70 figure,
|
||||
.card-30 .flex-content,
|
||||
.card-30 blockquote {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
[class*='card']:nth-child(odd) figure {
|
||||
order: 0;
|
||||
}
|
||||
|
||||
[class*='card']:nth-child(even) figure {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.flex-content,
|
||||
[class*='card'] blockquote {
|
||||
padding: 4.8rem;
|
||||
}
|
||||
|
||||
.fullscreen [class*='card'] .flex-content,
|
||||
.fullscreen [class*='card'] blockquote {
|
||||
padding: 6.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
[class*='card-'],
|
||||
[class*='card-'] > a {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.card figure,
|
||||
.card header {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
58
src/scss/modules/_flexblock-activity.scss
Normal file
58
src/scss/modules/_flexblock-activity.scss
Normal file
@@ -0,0 +1,58 @@
|
||||
/*===========================================
|
||||
6.9 Block Activity <ul class="activity">
|
||||
CV / News
|
||||
============================================= */
|
||||
|
||||
.flexblock.activity {
|
||||
flex-direction: column;
|
||||
|
||||
li {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.year,
|
||||
.title {
|
||||
display: inline;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.summary {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 768px) {
|
||||
p {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.year {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
width: 27%;
|
||||
}
|
||||
|
||||
.summary {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
38
src/scss/modules/_flexblock-clients.scss
Normal file
38
src/scss/modules/_flexblock-clients.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
/*=====================================================================
|
||||
6.2 Clients Logos <ul class="flexblock clients">
|
||||
======================================================================= */
|
||||
|
||||
.flexblock.clients.blink li > a,
|
||||
.flexblock.clients li {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.flexblock.clients li figcaption {
|
||||
padding: 0 2.4rem 2.4rem;
|
||||
}
|
||||
|
||||
.flexblock.clients.border li figcaption {
|
||||
padding-top: 2.4rem;
|
||||
}
|
||||
|
||||
.clients.blink li>a,
|
||||
.clients li {
|
||||
justify-content: inherit;
|
||||
}
|
||||
|
||||
.clients li img,
|
||||
.clients li svg {
|
||||
display: block;
|
||||
padding: 2.4rem;
|
||||
}
|
||||
|
||||
.clients.border li img,
|
||||
.clients.border li svg {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.clients li:hover {
|
||||
z-index: 1;
|
||||
}
|
77
src/scss/modules/_flexblock-features.scss
Normal file
77
src/scss/modules/_flexblock-features.scss
Normal file
@@ -0,0 +1,77 @@
|
||||
/*====================================================================
|
||||
6.1 Features <ul class="flexblock features">
|
||||
====================================================================== */
|
||||
|
||||
.flexblock.features {
|
||||
> li {
|
||||
border-radius: .4rem;
|
||||
margin-bottom: 4.8rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
li h2 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
li span {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
li p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li p em {
|
||||
display: block;
|
||||
}
|
||||
|
||||
li span,
|
||||
li svg {
|
||||
display: block;
|
||||
font-size: 6.4rem;
|
||||
line-height: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li img {
|
||||
width: 6.4rem;
|
||||
}
|
||||
|
||||
li span sup {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
li span,
|
||||
li svg,
|
||||
li img {
|
||||
float: left;
|
||||
margin-right: .8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.flexblock.features {
|
||||
margin-left: -2%;
|
||||
margin-right: -2%;
|
||||
}
|
||||
|
||||
.flexblock.features > li {
|
||||
margin-left: 2%;
|
||||
margin-right: 2%;
|
||||
width: 29%;
|
||||
}
|
||||
|
||||
.size-50 .flexblock.features > li {
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.column .flexblock.features > li {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
footer .flexblock.features>li {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
141
src/scss/modules/_flexblock-gallery.scss
Normal file
141
src/scss/modules/_flexblock-gallery.scss
Normal file
@@ -0,0 +1,141 @@
|
||||
/*=================================================
|
||||
6.7 Gallery - <ul class="flexblock gallery">
|
||||
Block Thumbnails li+.overlay+image
|
||||
img size recommended:800x600px
|
||||
=================================================== */
|
||||
|
||||
.flexblock.gallery {
|
||||
li {
|
||||
margin-bottom: 4.8rem;
|
||||
|
||||
&:nth-child(n+4) {
|
||||
flex: inherit;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
padding: 1.6rem;
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
height: 0;
|
||||
left: 20%;
|
||||
margin-left: -.5em;
|
||||
position: absolute;
|
||||
top: .4rem;
|
||||
transform: rotate(135deg);
|
||||
transform-origin: 0 0;
|
||||
transition: .1s;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover figcaption:before {
|
||||
top: .3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.aligncenter & li figcaption:before {
|
||||
left: 55%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
li,
|
||||
&.blink li > a {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h2 + p,
|
||||
h3 + p {
|
||||
margin-top: .8rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.6rem;
|
||||
line-height: 2.4rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
li footer {
|
||||
margin-top: .8rem;
|
||||
padding: 1.2rem 0 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
li img {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
margin-left: -2%;
|
||||
margin-right: -2%;
|
||||
|
||||
li {
|
||||
margin-left: 2%;
|
||||
margin-right: 2%;
|
||||
width: 46%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.flexblock.gallery li {
|
||||
width: 21%;
|
||||
}
|
||||
|
||||
.grid.sm .flexblock.gallery li,
|
||||
.grid.ms .flexblock.gallery li {
|
||||
width: 29%;
|
||||
}
|
||||
|
||||
.grid.sms .flexblock.gallery li {
|
||||
width: 46%;
|
||||
}
|
||||
}
|
||||
|
||||
.overlay {
|
||||
bottom: 0;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transition: all .3s linear;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
li .overlay {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
li .overlay h2 {
|
||||
letter-spacing: .2rem;
|
||||
margin: 0;
|
||||
padding: 0 2.4rem;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.overlay p,
|
||||
.overlay time {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
li:hover .overlay {
|
||||
cursor: pointer;
|
||||
}
|
32
src/scss/modules/_flexblock-metrics.scss
Normal file
32
src/scss/modules/_flexblock-metrics.scss
Normal file
@@ -0,0 +1,32 @@
|
||||
/*=================================================
|
||||
6.4 Block Numbers - <ul class="flexblock metrics">
|
||||
=================================================== */
|
||||
|
||||
.metrics li {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
|
||||
@media (min-width: 568px) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.metrics li strong {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.metrics li span,
|
||||
.metrics li svg {
|
||||
display: block;
|
||||
font-size: 6.4rem;
|
||||
line-height: 7.2rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.card-50 .metrics li {
|
||||
width: 50%;
|
||||
}
|
85
src/scss/modules/_flexblock-plans.scss
Normal file
85
src/scss/modules/_flexblock-plans.scss
Normal file
@@ -0,0 +1,85 @@
|
||||
/*===============================================
|
||||
6.8 Plans / Pricing <ul class="flexblock plans">
|
||||
================================================= */
|
||||
|
||||
.flexblock.plans {
|
||||
> li {
|
||||
border-radius: 3px;
|
||||
margin-bottom: 4.8rem;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
li,
|
||||
&.blink li>a {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.blink li > a div,
|
||||
li div {
|
||||
padding-bottom: 3.2rem;
|
||||
}
|
||||
|
||||
li p,
|
||||
li h2 {
|
||||
padding: .8rem 3.2rem;
|
||||
}
|
||||
|
||||
li h2 {
|
||||
float: left;
|
||||
font-weight: 400;
|
||||
letter-spacing: .1rem;
|
||||
text-transform: uppercase;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.price {
|
||||
clear: both;
|
||||
display: block;
|
||||
font-size: 4.8rem;
|
||||
font-weight: 400;
|
||||
line-height: 6.2rem;
|
||||
padding: 2.4rem;
|
||||
|
||||
sup {
|
||||
font-size: 1.8rem;
|
||||
margin-right: .4rem;
|
||||
}
|
||||
|
||||
li ul {
|
||||
margin-bottom: 2.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
li ul li {
|
||||
display: block;
|
||||
padding: .8rem 3.2rem;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
margin-left: -2%;
|
||||
margin-right: -2%;
|
||||
|
||||
>li {
|
||||
margin-left: 2%;
|
||||
margin-right: 2%;
|
||||
width: 29%;
|
||||
}
|
||||
|
||||
>li:hover,
|
||||
>li:nth-child(2) {
|
||||
position: relative;
|
||||
transform: scale(1.08);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&:hover li:nth-child(2):not(:hover) {
|
||||
position: relative;
|
||||
transform: scale(1);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
41
src/scss/modules/_flexblock-reasons.scss
Normal file
41
src/scss/modules/_flexblock-reasons.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
/*=================================================
|
||||
6.6 Reasons/Why/Numbers (counter-increment)
|
||||
<ul class="flexblock reasons">
|
||||
=================================================== */
|
||||
.flexblock.reasons {
|
||||
li {
|
||||
counter-increment: list;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-.2rem);
|
||||
}
|
||||
|
||||
&:after {
|
||||
bottom: -2.4rem;
|
||||
content: '';
|
||||
display: block;
|
||||
height: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: counter(list)'.';
|
||||
font-size: 6.4rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding-left: 8.8rem;
|
||||
/* You need two digits? (1-10)*/
|
||||
/*padding-left: 12rem; */
|
||||
|
||||
&:before {
|
||||
left: 2.4rem;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
49
src/scss/modules/_flexblock-specs.scss
Normal file
49
src/scss/modules/_flexblock-specs.scss
Normal file
@@ -0,0 +1,49 @@
|
||||
/*=====================================================
|
||||
6.5 Specs/Items: <ul class="flexblock specs">
|
||||
======================================================= */
|
||||
|
||||
.specs li {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
&:after {
|
||||
bottom: -2.4rem;
|
||||
content: '';
|
||||
display: block;
|
||||
height: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translateX(.2rem);
|
||||
}
|
||||
|
||||
span,
|
||||
svg {
|
||||
display: block;
|
||||
font-size: 6.4rem;
|
||||
line-height: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 6.4rem;
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: 300;
|
||||
|
||||
sup {
|
||||
font-size: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
span,
|
||||
svg,
|
||||
img {
|
||||
float: left;
|
||||
margin-right: 2.4rem;
|
||||
}
|
||||
}
|
||||
}
|
38
src/scss/modules/_flexblock-steps.scss
Normal file
38
src/scss/modules/_flexblock-steps.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
/*==================================================
|
||||
6.3 flexblock.steps <ul class="flexblock steps">
|
||||
About, Philosophy...
|
||||
=================================================== */
|
||||
|
||||
.steps li {
|
||||
width: 100%;
|
||||
|
||||
img,
|
||||
span {
|
||||
display: block;
|
||||
margin: 0 auto .8rem;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 6.4rem;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.steps li {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.process {
|
||||
border-left-style: solid;
|
||||
border-left-width: 15px;
|
||||
height: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
width: 0;
|
||||
}
|
||||
}
|
101
src/scss/modules/_flexblock.scss
Normal file
101
src/scss/modules/_flexblock.scss
Normal file
@@ -0,0 +1,101 @@
|
||||
/*===============================================================
|
||||
6. Magic blocks with flexbox (Auto-fill & Equal Height)
|
||||
Blocks Links li>a = .flexblock.blink (.blink required)
|
||||
================================================================= */
|
||||
|
||||
.flexblock {
|
||||
clear: both;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: table;
|
||||
}
|
||||
|
||||
li,
|
||||
&.blink li > a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: 2.4rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
li {
|
||||
flex: auto;
|
||||
text-align: left;
|
||||
transition: .3s;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-.2rem);
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
&.aligncenter li {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.vertical-align li {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&.blink li {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li h2 svg,
|
||||
li h3 svg {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h1 + .flexblock,
|
||||
h2 + .flexblock,
|
||||
h3 + .flexblock,
|
||||
div + ul,
|
||||
div + ol {
|
||||
margin-top: 3.2rem;
|
||||
}
|
||||
|
||||
.flexblock li h2,
|
||||
.flexblock li h3,
|
||||
footer .column h2,
|
||||
footer .column h3 {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 600;
|
||||
line-height: 3.2rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.flexblock li li,
|
||||
.flexblock.blink li li {
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
[class*='content-'] .flexblock li p {
|
||||
font-size: 1.8rem;
|
||||
line-height: 3.2rem;
|
||||
}
|
||||
|
||||
.content-right .flexblock.features li,
|
||||
.content-left .flexblock.features li {
|
||||
width: 46%;
|
||||
}
|
159
src/scss/modules/_form.scss
Normal file
159
src/scss/modules/_form.scss
Normal file
@@ -0,0 +1,159 @@
|
||||
/*=========================================
|
||||
14. Forms
|
||||
=========================================== */
|
||||
|
||||
form {
|
||||
text-align: left;
|
||||
|
||||
& + p,
|
||||
input + p,
|
||||
textarea + p {
|
||||
margin-top: .8rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
input[type='text'],
|
||||
input[type='email'],
|
||||
input[type='tel'],
|
||||
input[type='url'],
|
||||
input[type='search'],
|
||||
input[type='password'] {
|
||||
appearance: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select {
|
||||
display: inline-block;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
height: 4.8rem;
|
||||
margin: 0;
|
||||
padding: .7rem;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
input[type='radio'],
|
||||
input[type='checkbox'] {
|
||||
height: auto;
|
||||
padding: 4px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
button[type='submit'],
|
||||
textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
textarea {
|
||||
padding: .7rem;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.button {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 400;
|
||||
line-height: 4.8rem;
|
||||
min-width: 16rem;
|
||||
padding: 0 1.6rem;
|
||||
text-align: center;
|
||||
|
||||
svg {
|
||||
font-size: 2.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.button.radius,
|
||||
input.radius {
|
||||
border-radius: 2.4rem;
|
||||
}
|
||||
|
||||
button,
|
||||
input[type='submit'] {
|
||||
font-weight: 400;
|
||||
letter-spacing: .1rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
|
||||
.plans .button {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.try {
|
||||
display: block;
|
||||
font-size: 1.6rem;
|
||||
margin-top: 1.6rem;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
padding: 2.4rem;
|
||||
}
|
||||
|
||||
legend {
|
||||
border: 0;
|
||||
font-weight: 400;
|
||||
letter-spacing: .1rem;
|
||||
padding: 1.6rem 2.4rem;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
a.button:hover,
|
||||
button[type='submit']:hover,
|
||||
input[type='submit']:hover {
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
:disabled,
|
||||
button:disabled:hover {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.user {
|
||||
input {
|
||||
margin-bottom: 0;
|
||||
|
||||
&[type='email'],
|
||||
&[type='search'],
|
||||
&[type='text'] {
|
||||
width: 100%;
|
||||
|
||||
@media (min-width: 500px) {
|
||||
float: left;
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button,
|
||||
input[type='submit'] {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
|
||||
@media (min-width: 500px) {
|
||||
cursor: pointer;
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
}
|
59
src/scss/modules/_grid.scss
Normal file
59
src/scss/modules/_grid.scss
Normal file
@@ -0,0 +1,59 @@
|
||||
/*=== 1.4. Basic Grid (Flexible blocks)
|
||||
Auto-fill & Equal height === */
|
||||
|
||||
.grid {
|
||||
clear: both;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: table;
|
||||
}
|
||||
|
||||
& > .column {
|
||||
display: flex;
|
||||
flex: auto;
|
||||
flex-direction: column;
|
||||
padding: 2.4rem;
|
||||
position: relative;
|
||||
transition: .3s;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.vertical-align .column {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
& > .column {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
&.sm .column:nth-child(1) {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
&.sm .column:nth-child(2) {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
&.ms .column:nth-child(1) {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
&.ms .column:nth-child(2) {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
&.sms .column:nth-child(2) {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
64
src/scss/modules/_header-footer.scss
Normal file
64
src/scss/modules/_header-footer.scss
Normal file
@@ -0,0 +1,64 @@
|
||||
/*=========================================
|
||||
3. Header & Footer
|
||||
=========================================== */
|
||||
|
||||
/* -- If you want an unique, global header/footer,read this:
|
||||
https://github.com/webslides/webslides/issues/57 -- */
|
||||
|
||||
header,
|
||||
footer,
|
||||
#navigation {
|
||||
padding: 2.4rem;
|
||||
transition: all .4s ease-in-out;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
header p,
|
||||
footer p {
|
||||
line-height: 4.8rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
header[role='banner'] img,
|
||||
footer img {
|
||||
height: 4rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header,
|
||||
footer {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
header,
|
||||
.ws-ready footer {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.ws-ready footer {
|
||||
bottom: 0;
|
||||
top: auto;
|
||||
}
|
||||
|
||||
// Remove "opacity=0" if you want an unique, visible header on each slide
|
||||
header[role='banner'] {
|
||||
opacity: 0;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
footer .alignleft,
|
||||
footer .alignright {
|
||||
display: block;
|
||||
float: none;
|
||||
}
|
||||
}
|
17
src/scss/modules/_logo.scss
Normal file
17
src/scss/modules/_logo.scss
Normal file
@@ -0,0 +1,17 @@
|
||||
/*=== 3.1. Logo === */
|
||||
|
||||
.logo {
|
||||
text-transform: lowercase;
|
||||
|
||||
a {
|
||||
background: url('../images/logos/logo.svg') no-repeat 0 0;
|
||||
background-size: 4.8rem;
|
||||
float: left;
|
||||
height: 4.8rem;
|
||||
text-indent: -4000px;
|
||||
/*If you remove text-indent and add: */
|
||||
/*padding-left: 6rem;*/
|
||||
vertical-align: middle;
|
||||
width: 4.8rem;
|
||||
}
|
||||
}
|
67
src/scss/modules/_longform.scss
Normal file
67
src/scss/modules/_longform.scss
Normal file
@@ -0,0 +1,67 @@
|
||||
/*=========================================
|
||||
15. Longform
|
||||
=========================================== */
|
||||
/* -- Posts = .wrap.longform -- */
|
||||
|
||||
.longform {
|
||||
width: 72rem;
|
||||
/* Why 72rem=720px?
|
||||
90-95 characters per line = better reading speed */
|
||||
|
||||
& .alignleft,
|
||||
& .alignright {
|
||||
max-width: 40%;
|
||||
}
|
||||
|
||||
img.aligncenter,
|
||||
figure.aligncenter {
|
||||
margin-bottom: 3.2rem;
|
||||
margin-top: 3.2rem;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin-bottom: 3.2rem;
|
||||
}
|
||||
|
||||
ul ol,
|
||||
ol ul,
|
||||
ul ul,
|
||||
ol ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
figcaption p,
|
||||
[class*='text-pull-'] p {
|
||||
font-size: 1.6rem;
|
||||
line-height: 2.4rem;
|
||||
}
|
||||
|
||||
/* Mobile: video full width */
|
||||
.text-pull.embed {
|
||||
margin-left: -2.4rem;
|
||||
margin-right: -2.4rem;
|
||||
padding-bottom: 60.6%;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
[class*='text-pull-'] {
|
||||
max-width: 32%;
|
||||
}
|
||||
|
||||
.text-pull-right {
|
||||
margin-right: -256px;
|
||||
}
|
||||
|
||||
.text-pull-left {
|
||||
margin-left: -256px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.text-quote {
|
||||
margin-left: -4.8rem;
|
||||
margin-right: -4.8rem;
|
||||
}
|
||||
}
|
||||
}
|
61
src/scss/modules/_media.scss
Normal file
61
src/scss/modules/_media.scss
Normal file
@@ -0,0 +1,61 @@
|
||||
/*=== 1.3 Responsive Media (videos, iframe...) === */
|
||||
|
||||
.embed {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
/*aspect ratio:16:9*/
|
||||
padding-bottom: 56.6%;
|
||||
/*aspect ratio: 4:3*/
|
||||
/*padding-bottom: 75%;*/
|
||||
position: relative;
|
||||
|
||||
iframe,
|
||||
object,
|
||||
embed,
|
||||
video {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* -- Responsive background video
|
||||
https://fvsch.com/code/video-background/ -- */
|
||||
|
||||
.fullscreen > & {
|
||||
bottom: 0;
|
||||
height: auto;
|
||||
left: 0;
|
||||
padding-bottom: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
/* 1. No object-fit support: */
|
||||
& > iframe,
|
||||
& > object,
|
||||
& > embed,
|
||||
& > video {
|
||||
@media (min-aspect-ratio: 16 / 9) {
|
||||
height: 300%;
|
||||
top: -100%;
|
||||
}
|
||||
|
||||
@media (max-aspect-ratio: 16 / 9) {
|
||||
left: -100%;
|
||||
width: 300%;
|
||||
}
|
||||
|
||||
/* 2. If supporting object-fit, overriding (1): */
|
||||
@supports (object-fit: cover) {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
object-fit: cover;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
72
src/scss/modules/_navigation.scss
Normal file
72
src/scss/modules/_navigation.scss
Normal file
@@ -0,0 +1,72 @@
|
||||
/*=========================================
|
||||
4. Navigation
|
||||
=========================================== */
|
||||
|
||||
/*=== 4.1. Navbars === */
|
||||
|
||||
nav ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
/*====align left====*/
|
||||
justify-content: flex-start;
|
||||
/* ==== align center ====*/
|
||||
/*justify-content: center; */
|
||||
/*====align right====*/
|
||||
/* justify-content: flex-end; */
|
||||
/*====separated columns li a====*/
|
||||
/* justify-content: space-between; */
|
||||
/*====separated columns centered li a====*/
|
||||
/*justify-content: space-around;*/
|
||||
|
||||
li {
|
||||
float: left;
|
||||
list-style: none;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
nav ul li:first-child,
|
||||
nav[role='navigation'] ul li {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
nav[role='navigation'] li a {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
line-height: 4.8rem;
|
||||
max-width: 100%;
|
||||
padding: 0 1.6rem;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
|
||||
svg {
|
||||
margin: 1.5rem .4rem 1.5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
header nav ul {
|
||||
justify-content: flex-end;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav.aligncenter ul,
|
||||
.aligncenter nav ul {
|
||||
/* ==== align center ====*/
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
nav.navbar ul li {
|
||||
/*====full float li a ====*/
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 568px) {
|
||||
nav.navbar ul {
|
||||
flex-flow: column wrap;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav.navbar li a {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
52
src/scss/modules/_print.scss
Normal file
52
src/scss/modules/_print.scss
Normal file
@@ -0,0 +1,52 @@
|
||||
/*=========================================
|
||||
17. PRINT
|
||||
=========================================== */
|
||||
|
||||
// sass-lint:disable no-important
|
||||
@media print {
|
||||
@page {
|
||||
margin: .5cm;
|
||||
size: A4 landscape;
|
||||
}
|
||||
|
||||
// Black prints faster
|
||||
* {
|
||||
background: transparent !important;
|
||||
color: $black !important;
|
||||
filter: none !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#webslides {
|
||||
height: auto !important;
|
||||
overflow: auto !important;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
#webslides {
|
||||
overflow-x: auto !important;
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
|
||||
section,
|
||||
.slide {
|
||||
display: flex !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
section * {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
table,
|
||||
figure {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
#counter,
|
||||
#navigation {
|
||||
display: none;
|
||||
}
|
||||
}
|
98
src/scss/modules/_promos.scss
Normal file
98
src/scss/modules/_promos.scss
Normal file
@@ -0,0 +1,98 @@
|
||||
/*=============================================
|
||||
7. Promos/Offers (pricing, tagline, CTA...)
|
||||
=============================================== */
|
||||
|
||||
.cta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.number,
|
||||
.cta .benefit {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
max-width: 100%;
|
||||
padding: .8rem;
|
||||
}
|
||||
|
||||
.number {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta .benefit {
|
||||
max-width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.number span {
|
||||
display: block;
|
||||
font-size: 8rem;
|
||||
line-height: 8rem;
|
||||
}
|
||||
|
||||
.number span sup {
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
||||
.cta p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.number,
|
||||
.cta .benefit {
|
||||
max-width: 50%;
|
||||
padding: 4.8rem;
|
||||
}
|
||||
|
||||
.cta .benefit {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.number span {
|
||||
font-size: 16rem;
|
||||
line-height: 16rem;
|
||||
|
||||
sup {
|
||||
font-size: 6rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Header CTA --- */
|
||||
.cta-cover {
|
||||
display: table;
|
||||
width: 100%;
|
||||
|
||||
h1 strong {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
h1 {
|
||||
float: left;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
h1 strong {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
|
||||
.try {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.alignright {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
}
|
71
src/scss/modules/_quotes.scss
Normal file
71
src/scss/modules/_quotes.scss
Normal file
@@ -0,0 +1,71 @@
|
||||
/*=========================================
|
||||
11. Quotes
|
||||
=========================================== */
|
||||
|
||||
blockquote {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
p {
|
||||
font-size: 2.4rem;
|
||||
line-height: 4rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 3.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Interviews dl.text-interview -- */
|
||||
dd blockquote p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
cite {
|
||||
display: block;
|
||||
text-align: center;
|
||||
|
||||
&:before {
|
||||
content: '\2014 \2009';
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
cite span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* -- A big Blockquote -- */
|
||||
/* .wall will be deprecated soon. Use .text-quote ;) */
|
||||
.text-quote,
|
||||
.wall {
|
||||
/* Versatility: blockquote, p, h2... */
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '\201C';
|
||||
font-family: arial, sans-serif;
|
||||
font-size: 12rem;
|
||||
height: 5.6rem;
|
||||
left: -.8rem;
|
||||
line-height: 1;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: -4rem;
|
||||
width: 5.6rem;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding-left: 6.4rem;
|
||||
|
||||
p {
|
||||
font-size: 3.2rem;
|
||||
line-height: 4.8rem;
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: .8rem;
|
||||
top: -1.6rem;
|
||||
}
|
||||
}
|
||||
}
|
126
src/scss/modules/_slides-bg.scss
Normal file
126
src/scss/modules/_slides-bg.scss
Normal file
@@ -0,0 +1,126 @@
|
||||
/*=== 5.3 Slides - Background Images/Videos === */
|
||||
|
||||
.background,
|
||||
[class*='background-'] {
|
||||
background-repeat: no-repeat;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/*=== BG Positions === */
|
||||
|
||||
.background {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
|
||||
&-top {
|
||||
background-position: top;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
&-bottom {
|
||||
background-position: bottom;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
&-center {
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
&-center-top {
|
||||
background-position: center top;
|
||||
}
|
||||
|
||||
&-right-top {
|
||||
background-position: right top;
|
||||
}
|
||||
|
||||
&-left-top {
|
||||
background-position: left top;
|
||||
}
|
||||
|
||||
&-center-bottom,
|
||||
&-left-bottom,
|
||||
&-right-bottom,
|
||||
&-left,
|
||||
&-right {
|
||||
background-position: center bottom;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
&-left-bottom {
|
||||
background-position: left bottom;
|
||||
}
|
||||
|
||||
&-right-bottom {
|
||||
background-position: right bottom;
|
||||
}
|
||||
|
||||
&-right {
|
||||
background-position: right;
|
||||
}
|
||||
|
||||
&-left {
|
||||
background-position: left;
|
||||
}
|
||||
}
|
||||
|
||||
/*fullscreen video
|
||||
<video class="background-video">
|
||||
*/
|
||||
|
||||
&-video {
|
||||
height: 100%;
|
||||
object-fit: fill;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
/*=== bg image/video overlay === */
|
||||
/*-- [class*="bg-"] .background.dark, [class*="bg-"] .embed.dark... -- */
|
||||
|
||||
[class*='bg-'] .light,
|
||||
[class*='bg-'] .light {
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
[class*='bg-'] .dark,
|
||||
[class*='bg-'] .dark {
|
||||
opacity: .2;
|
||||
}
|
||||
|
||||
[class*='bg-'] .background-video.dark {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
[class*='background-'] {
|
||||
animation: fadeIn ease-in .2;
|
||||
opacity: .2;
|
||||
}
|
||||
|
||||
.background-video {
|
||||
opacity: .8;
|
||||
}
|
||||
}
|
||||
|
||||
/*=== Animated Background Image === */
|
||||
|
||||
.background.anim {
|
||||
animation: anim 80s linear infinite;
|
||||
background-position: center top;
|
||||
background-repeat: repeat;
|
||||
background-size: 100%;
|
||||
height: 200%;
|
||||
|
||||
}
|
||||
|
||||
/*=== Background with a frame === */
|
||||
/*<span class="background" style="background-image:url('image.jpg')"></span>
|
||||
<span class="background frame"></span>*/
|
||||
|
||||
[class*='background'].frame {
|
||||
margin: 2.4rem;
|
||||
}
|
70
src/scss/modules/_slides-navigation.scss
Normal file
70
src/scss/modules/_slides-navigation.scss
Normal file
@@ -0,0 +1,70 @@
|
||||
/* === 5.2 Counter / Navigation Slides === */
|
||||
|
||||
#navigation {
|
||||
animation: fadeIn 8s;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
opacity: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
width: 24.4rem;
|
||||
/* hover/visibility */
|
||||
z-index: 4;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#counter {
|
||||
display: block;
|
||||
line-height: 4.8rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: 10rem;
|
||||
|
||||
a:hover {
|
||||
padding: .8rem;
|
||||
}
|
||||
}
|
||||
|
||||
a#next,
|
||||
a#previous {
|
||||
border-radius: .4rem;
|
||||
cursor: pointer;
|
||||
font-size: 2.4rem;
|
||||
height: 4rem;
|
||||
padding: .8rem;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 4rem;
|
||||
}
|
||||
|
||||
a#next {
|
||||
right: 3.2rem;
|
||||
}
|
||||
|
||||
a#previous {
|
||||
left: 3.2rem;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
#navigation {
|
||||
animation: fadeIn 6s;
|
||||
background: url('../images/swipe.svg') no-repeat center top;
|
||||
background-size: 4.8rem;
|
||||
}
|
||||
|
||||
#navigation a,
|
||||
#counter {
|
||||
display: none;
|
||||
}
|
||||
}
|
118
src/scss/modules/_slides.scss
Normal file
118
src/scss/modules/_slides.scss
Normal file
@@ -0,0 +1,118 @@
|
||||
/*============================================
|
||||
5. SLIDES (Full Screen)
|
||||
Vertically and horizontally centered
|
||||
============================================== */
|
||||
|
||||
/* Fade transition to all slides.
|
||||
* = All HTML elements will have those styles.*/
|
||||
|
||||
section * {
|
||||
animation: fadeIn .6s ease-in-out;
|
||||
}
|
||||
|
||||
section .background,
|
||||
section .light,
|
||||
section .dark {
|
||||
animation-duration: 0s;
|
||||
}
|
||||
|
||||
/*=== Section = Slide === */
|
||||
section,
|
||||
.slide {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
min-height: 100vh; /*Fullscreen*/
|
||||
/* Prototyping? min-height: 720px (Baseline: 8px = .8rem)*/
|
||||
padding: 2.4rem;
|
||||
/*Fixed/Visible header? padding-top: 12rem; */
|
||||
page-break-after: always;
|
||||
position: relative;
|
||||
word-wrap: break-word;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
padding-bottom: 12rem;
|
||||
padding-top: 12rem;
|
||||
}
|
||||
}
|
||||
|
||||
/*slide with no padding (full card, .embed youtube video...) */
|
||||
.fullscreen {
|
||||
padding: 0;
|
||||
/* Fixed/Visible header?
|
||||
padding:8.2rem 0 0 0;
|
||||
*/
|
||||
}
|
||||
|
||||
/* slide alignment - top */
|
||||
.slide-top {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
/* slide alignment - bottom */
|
||||
.slide-bottom {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/*== 5.1. Mini container width:50%
|
||||
Aligned items [class*="content-"]=== */
|
||||
[class*='content-'] {
|
||||
position: relative;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.wrap[class*='bg-'],
|
||||
.wrap.frame,
|
||||
[class*='content-'][class*='bg-'],
|
||||
[class*='content-'].frame,
|
||||
[class*='align'][class*='bg-'] {
|
||||
padding: 4.8rem;
|
||||
}
|
||||
|
||||
form[class*='bg-'] {
|
||||
padding: 2.4rem;
|
||||
}
|
||||
|
||||
[class*='content-'] > [class*='content-'] p {
|
||||
font-size: 1.8rem;
|
||||
line-height: 3.2rem;
|
||||
}
|
||||
|
||||
.content-center {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
[class*='content-'] {
|
||||
width: 50%;
|
||||
|
||||
&:after,
|
||||
&:before {
|
||||
content: '';
|
||||
display: table;
|
||||
}
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
.content-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
[class*='content-'] + [class*='content-'] {
|
||||
margin-bottom: 4.8rem;
|
||||
padding-left: 2.4rem;
|
||||
}
|
||||
|
||||
[class*='content-'] + [class*='size-'] {
|
||||
clear: both;
|
||||
margin-top: 6.4rem;
|
||||
}
|
||||
}
|
34
src/scss/modules/_tables.scss
Normal file
34
src/scss/modules/_tables.scss
Normal file
@@ -0,0 +1,34 @@
|
||||
/*=========================================
|
||||
13. Tables
|
||||
=========================================== */
|
||||
|
||||
table {
|
||||
margin-bottom: 3.2rem;
|
||||
margin-top: 3.2rem;
|
||||
}
|
||||
|
||||
td,
|
||||
th,
|
||||
thead {
|
||||
border-spacing: 0;
|
||||
padding: .7rem 2.4rem;
|
||||
}
|
||||
|
||||
thead th,
|
||||
th {
|
||||
cursor: default;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
thead,
|
||||
td.goals {
|
||||
font-weight: 600;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
tr > td {
|
||||
font-weight: 400;
|
||||
}
|
77
src/scss/modules/_toc.scss
Normal file
77
src/scss/modules/_toc.scss
Normal file
@@ -0,0 +1,77 @@
|
||||
/*===========================================
|
||||
9. Table of contents
|
||||
============================================= */
|
||||
|
||||
.toc,
|
||||
.toc ol > li:before,
|
||||
.chapter {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.toc {
|
||||
ol {
|
||||
counter-reset: item;
|
||||
position: relative;
|
||||
|
||||
& > li:before {
|
||||
content: counters(item, '.') '. ';
|
||||
display: table-cell;
|
||||
padding-right: .8rem;
|
||||
width: 2.4rem;
|
||||
}
|
||||
|
||||
li li:before {
|
||||
content: counters(item, '.') ' ';
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
counter-increment: item;
|
||||
display: table;
|
||||
font-weight: 400;
|
||||
margin-bottom: .8rem;
|
||||
margin-left: 0;
|
||||
transition: .3s;
|
||||
width: 100%;
|
||||
|
||||
li {
|
||||
font-weight: 300;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.toc-page:before {
|
||||
content: '';
|
||||
display: block;
|
||||
left: 0;
|
||||
margin-top: 1.8rem;
|
||||
position: absolute;
|
||||
right: 4rem;
|
||||
}
|
||||
|
||||
& > a {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a:hover span {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
a:hover .toc-page:before {
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chapter {
|
||||
display: inline-block;
|
||||
font-size: 1.8rem;
|
||||
line-height: 3.2rem;
|
||||
padding-right: .8rem;
|
||||
}
|
||||
|
||||
.toc-page {
|
||||
float: right;
|
||||
}
|
107
src/scss/modules/_work.scss
Normal file
107
src/scss/modules/_work.scss
Normal file
@@ -0,0 +1,107 @@
|
||||
/*=========================================
|
||||
8. Work/Resumé/CV <ul class="work">
|
||||
=========================================== */
|
||||
.work {
|
||||
clear: both;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: left;
|
||||
|
||||
h1 + &,
|
||||
h2 + &,
|
||||
h3 + &,
|
||||
p + & {
|
||||
margin-top: 4.8rem;
|
||||
}
|
||||
|
||||
li {
|
||||
flex: 1;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
transition: .3s;
|
||||
}
|
||||
|
||||
li a {
|
||||
display: block;
|
||||
float: left;
|
||||
height: 100%;
|
||||
padding: 2.4rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
li p {
|
||||
padding-left: 1.2rem;
|
||||
}
|
||||
|
||||
li.work-label p {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
li a:hover p:first-child {
|
||||
padding-left: 1.6rem;
|
||||
}
|
||||
|
||||
li p:last-child {
|
||||
position: absolute;
|
||||
right: 1.2rem;
|
||||
top: 2.4rem;
|
||||
}
|
||||
|
||||
li.work-label p:last-child {
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&-label {
|
||||
float: left;
|
||||
font-weight: 600;
|
||||
padding: 0 0 2.4rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-title {
|
||||
display: block;
|
||||
padding-right: 1.2rem;
|
||||
width: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.work-label p,
|
||||
.work li p {
|
||||
float: left;
|
||||
margin-right: 2%;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.work li.work-label p:last-child,
|
||||
.work li p:last-child {
|
||||
float: right;
|
||||
margin-right: 0;
|
||||
padding-right: 1.2rem;
|
||||
position: relative;
|
||||
right: auto;
|
||||
text-align: right;
|
||||
top: auto;
|
||||
}
|
||||
|
||||
.work li p.work-date {
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.work-client,
|
||||
.work-label .work-services {
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
}
|
155
src/scss/modules/_zoom.scss
Normal file
155
src/scss/modules/_zoom.scss
Normal file
@@ -0,0 +1,155 @@
|
||||
/*==============================================
|
||||
18. Slides Index: Thumbnails navigation gallery
|
||||
================================================ */
|
||||
|
||||
#webslides-zoomed {
|
||||
align-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
&.disabled {
|
||||
left: -100000px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.slide {
|
||||
height: 400%;
|
||||
width: 400%;
|
||||
|
||||
@media screen and (orientation: portrait), screen and (max-width: 768px) and (orientation: landscape) {
|
||||
height: 200%;
|
||||
width: 200%;
|
||||
}
|
||||
|
||||
@media (max-aspect-ratio: 2 / 3) {
|
||||
height: 200%;
|
||||
width: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
> .wrap {
|
||||
@media (min-width: 1024px) {
|
||||
padding-bottom: 12rem;
|
||||
padding-top: 12rem;
|
||||
}
|
||||
}
|
||||
|
||||
> .wrap > .grid > .column {
|
||||
align-self: auto;
|
||||
flex: 0 1 auto;
|
||||
order: 0;
|
||||
position: relative;
|
||||
width: 25%;
|
||||
|
||||
@media screen and (max-width: 567px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 568px) and (max-width: 1024px) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 567px) and (orientation: portrait) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> .wrap-zoom {
|
||||
border-radius: .3rem;
|
||||
display: inline-block;
|
||||
height: 25vh;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
transition: .3s;
|
||||
|
||||
@media screen and (max-width: 567px) {
|
||||
height: 50vh;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 568px) and (max-width: 1023px) {
|
||||
height: 33vh;
|
||||
}
|
||||
|
||||
@media screen and (orientation: portrait) {
|
||||
height: 50vw;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.02);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&.current {
|
||||
transform: scale(1.08);
|
||||
}
|
||||
}
|
||||
|
||||
> .wrap-zoom > .zoom-layer {
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.column > .wrap-zoom > .slide {
|
||||
clip: rect(0 auto auto 0);
|
||||
display: flex !important; // sass-lint:disable-line no-important
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
transform: scale(.25) translate(-150%, -150vh);
|
||||
|
||||
@media screen and (orientation: portrait), screen and (max-width: 768px) and (orientation: landscape) {
|
||||
transform: scale(.5) translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@media (max-aspect-ratio: 2 / 3) {
|
||||
transform: scale(.5) translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
& .column {
|
||||
opacity: 0;
|
||||
transform: scale(1.2);
|
||||
transition: opacity .4s, transform .4s;
|
||||
transition-delay: .2s;
|
||||
}
|
||||
|
||||
&.in {
|
||||
.column {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-slide-number {
|
||||
display: inline-block;
|
||||
margin: .8rem auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#webslides {
|
||||
transition: filter .3s;
|
||||
|
||||
&.disabled,
|
||||
&.zooming {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
/*
|
||||
filter: blur(10px);
|
||||
transform: scale(1.1);
|
||||
*/
|
||||
/* Blur makes scroll no accesible */
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
}
|
106
src/scss/utils/_animations.scss
Normal file
106
src/scss/utils/_animations.scss
Normal file
@@ -0,0 +1,106 @@
|
||||
/* === 1.2 Animations ================
|
||||
Just 5 basic animations:
|
||||
.fadeIn, .fadeInUp, .zoomIn, .slideInLeft, and .slideInRight
|
||||
https://github.com/daneden/animate.css */
|
||||
|
||||
/*-- fadeIn -- */
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fadeIn {
|
||||
animation: fadeIn 1s;
|
||||
}
|
||||
|
||||
/*-- fadeInUp -- */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fadeInUp {
|
||||
animation: fadeInUp 1s;
|
||||
}
|
||||
|
||||
/*-- zoomIn -- */
|
||||
@keyframes zoomIn {
|
||||
from {
|
||||
transform: scale3d(.3, .3, .3);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.zoomIn {
|
||||
animation: zoomIn 1s;
|
||||
}
|
||||
|
||||
/*-- slideInLeft -- */
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.slideInLeft {
|
||||
animation: slideInLeft 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
/*-- slideInRight -- */
|
||||
@keyframes slideInRight {
|
||||
from {
|
||||
transform: translate3d(100%, 0, 0);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.slideInRight {
|
||||
animation: slideInRight 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
/* Animated Background (Matrix) */
|
||||
@keyframes anim {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(-1200px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Duration */
|
||||
.slow {
|
||||
animation-duration: 4s;
|
||||
|
||||
& + & {
|
||||
animation-duration: 5s;
|
||||
}
|
||||
}
|
13
src/scss/utils/_bugs.scss
Normal file
13
src/scss/utils/_bugs.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
/*=========================================
|
||||
16. SAFARI BUGS (flex-wrap)
|
||||
Solution: stackoverflow.com/questions/34250282/flexbox-safari-bug-flex-wrap
|
||||
=========================================== */
|
||||
|
||||
.flexblock:before,
|
||||
.flexblock:after,
|
||||
.grid:before,
|
||||
.grid:after,
|
||||
.cta:before,
|
||||
.cta:after {
|
||||
width: 0;
|
||||
}
|
19
src/scss/utils/_clear.scss
Normal file
19
src/scss/utils/_clear.scss
Normal file
@@ -0,0 +1,19 @@
|
||||
/*=== Clearing === */
|
||||
|
||||
header,
|
||||
main,
|
||||
section,
|
||||
aside,
|
||||
footer,
|
||||
.clear,
|
||||
.wrap {
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
display: table;
|
||||
}
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
}
|
||||
}
|
4
src/scss/utils/_mixins.scss
Normal file
4
src/scss/utils/_mixins.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
@mixin square($width) {
|
||||
height: $width;
|
||||
width: $width;
|
||||
}
|
300
src/scss/utils/_reset.scss
Normal file
300
src/scss/utils/_reset.scss
Normal file
@@ -0,0 +1,300 @@
|
||||
// sass-lint:disable no-vendor-prefixes
|
||||
/*
|
||||
=========================================
|
||||
0. CSS Reset & Normalize
|
||||
=========================================
|
||||
*/
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
span,
|
||||
applet,
|
||||
object,
|
||||
iframe,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
blockquote,
|
||||
pre,
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
big,
|
||||
cite,
|
||||
code,
|
||||
del,
|
||||
dfn,
|
||||
em,
|
||||
img,
|
||||
ins,
|
||||
kbd,
|
||||
q,
|
||||
s,
|
||||
samp,
|
||||
small,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
sup,
|
||||
tt,
|
||||
var,
|
||||
b,
|
||||
u,
|
||||
i,
|
||||
center,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li,
|
||||
fieldset,
|
||||
form,
|
||||
label,
|
||||
legend,
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
article,
|
||||
aside,
|
||||
canvas,
|
||||
details,
|
||||
embed,
|
||||
figure,
|
||||
figcaption,
|
||||
footer,
|
||||
header,
|
||||
menu,
|
||||
nav,
|
||||
output,
|
||||
ruby,
|
||||
section,
|
||||
summary,
|
||||
time,
|
||||
mark,
|
||||
audio,
|
||||
video {
|
||||
border: 0;
|
||||
font: inherit;
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
main,
|
||||
menu,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
q {
|
||||
quotes: '' '';
|
||||
}
|
||||
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: '';
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
margin-bottom: 24px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
embed,
|
||||
iframe,
|
||||
object {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
[hidden],
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: square;
|
||||
text-indent: inherit;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
sup,
|
||||
sub {
|
||||
font-size: .75em;
|
||||
height: 0;
|
||||
line-height: 2.2em;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
bottom: 1ex;
|
||||
}
|
||||
|
||||
sub {
|
||||
top: .5ex;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: .75em;
|
||||
line-height: 1.72;
|
||||
}
|
||||
|
||||
big {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
clear: both;
|
||||
display: block;
|
||||
height: 1px;
|
||||
margin: 3.2rem auto;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2 + hr,
|
||||
h3 + hr {
|
||||
margin-bottom: 4.8rem;
|
||||
}
|
||||
|
||||
p + hr {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
dfn,
|
||||
cite,
|
||||
em,
|
||||
i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
abbr,
|
||||
acronym {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
mark,
|
||||
ins {
|
||||
padding: 0 4px;
|
||||
text-decoration: none;
|
||||
text-shadow: none;
|
||||
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
::selection {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
img:hover {
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
figure {
|
||||
line-height: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0;
|
||||
}
|
3340
static/css/base.css
3340
static/css/base.css
File diff suppressed because it is too large
Load Diff
@@ -1,921 +0,0 @@
|
||||
/*=========================================
|
||||
WebSlides - Colors
|
||||
=========================================== */
|
||||
|
||||
/* == Backgrounds == */
|
||||
|
||||
/* .bg-primary */
|
||||
/* .bg-secondary */
|
||||
/* .bg-light */
|
||||
|
||||
/* == General == */
|
||||
/* .bg-white */
|
||||
/* .bg-black */
|
||||
/* .bg-black-blue */
|
||||
/* .bg-brown */
|
||||
/* .bg-blue */
|
||||
/* .bg-gray */
|
||||
/* .bg-purple */
|
||||
/* .bg-red */
|
||||
|
||||
/* == Brands == */
|
||||
/* .bg-apple */
|
||||
/* .bg-facebook */
|
||||
|
||||
/* == Gradients == */
|
||||
/* .bg-gradient-r (radial) */
|
||||
/* .bg-gradient-h (horizontal) */
|
||||
/* .bg-gradient-v (vertical) */
|
||||
/* .bg-gradient-white */
|
||||
/* .bg-gradient-gray */
|
||||
|
||||
/* == Transparent/Opacity Black == */
|
||||
/* .bg-trans-dark */
|
||||
/* .bg-trans-light */
|
||||
/* .bg-trans-gradient */
|
||||
|
||||
|
||||
/*=========================================
|
||||
Base
|
||||
=========================================== */
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
background-color: #f7f9fb;
|
||||
}
|
||||
:focus {
|
||||
box-shadow: 0 0 2px rgba(150, 187, 238, 1);
|
||||
}
|
||||
svg {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
[class*="bg-"] a,
|
||||
[class*="bg-gradient-"] a {
|
||||
color: #bce;
|
||||
}
|
||||
.bg-brown a {color: #c23;}
|
||||
|
||||
a,
|
||||
.bg-white a,
|
||||
.bg-light a,.bg-gradient-white a {
|
||||
color: #44d;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #3af;
|
||||
}
|
||||
.flexblock li>a,[class*="bg-"] li>a,
|
||||
[class*="bg-gradient-"] li>a,
|
||||
article header a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
hr {
|
||||
background: rgba(0, 20, 80, 0.2);
|
||||
background: radial-gradient(ellipse at center, rgba(0, 20, 80, 0.2) 0, rgba(255, 255, 255, 0) 75%);
|
||||
}
|
||||
|
||||
hr:after {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
color: #333;
|
||||
}
|
||||
|
||||
bbbr,
|
||||
acronym {
|
||||
border-bottom: 1px dotted #333;
|
||||
}
|
||||
|
||||
mark,
|
||||
ins {
|
||||
background-color: rgba(221,238,255, 0.8);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background-color: rgba(221,238,255, 0.8);
|
||||
}
|
||||
|
||||
::-webkit-selection {
|
||||
background-color: rgba(221,238,255, 0.8);
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: rgba(221,238,255, 0.8);
|
||||
}
|
||||
|
||||
pre {
|
||||
border: 1px solid rgba(0, 20, 80, 0.1);
|
||||
box-shadow: 0 8px 16px rgba(0,20,80,.04),0 4px 16px rgba(0,0,0,.08);
|
||||
background: #fff;
|
||||
|
||||
}
|
||||
pre:hover {
|
||||
box-shadow: 0 8px 16px rgba(0,40,160,.08),0 8px 24px rgba(0,0,0,.08);
|
||||
|
||||
}
|
||||
code,[class*="bg-"] pre {
|
||||
background-color: rgba(255, 255, 255, 0.09);
|
||||
}
|
||||
|
||||
.bg-white code{
|
||||
background: rgba(0, 20, 80, 0.03);
|
||||
}
|
||||
/*================================================
|
||||
Slides - Backgrounds <section class="bg-primary">
|
||||
================================================== */
|
||||
|
||||
/*3 Corp Colors*/
|
||||
|
||||
.bg-primary {
|
||||
background-color: #44d;
|
||||
}
|
||||
|
||||
.bg-secondary {
|
||||
background-color: #67d;
|
||||
}
|
||||
|
||||
.bg-light {
|
||||
background-color: #edf2f7;
|
||||
}
|
||||
|
||||
/*General Colors*/
|
||||
|
||||
.bg-black {
|
||||
background-color: #111;
|
||||
}
|
||||
.bg-black-blue {
|
||||
background-color: #123;
|
||||
}
|
||||
.bg-blue {
|
||||
background-color: #346;
|
||||
}
|
||||
.bg-brown {
|
||||
background-color: #f8f8f9;
|
||||
}
|
||||
.bg-gray {
|
||||
background-color: #d5d9e2;
|
||||
}
|
||||
.bg-green {
|
||||
background-color: #077;
|
||||
}
|
||||
.bg-purple {
|
||||
background-color: #62b;
|
||||
}
|
||||
|
||||
.bg-red {
|
||||
background-color: #c23;
|
||||
}
|
||||
|
||||
.bg-white {
|
||||
background-color: #fff;
|
||||
}
|
||||
[class*="bg-"] .bg-white {
|
||||
text-shadow: none;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* BG Apple Keynote*/
|
||||
|
||||
.bg-apple {
|
||||
background: linear-gradient(to bottom, #000 0%, #1a2028 50%, #293845 100%);
|
||||
}
|
||||
|
||||
|
||||
/* BG Facebook */
|
||||
|
||||
.bg-facebook {
|
||||
background: #3b5998;
|
||||
}
|
||||
|
||||
|
||||
/*Font Color*/
|
||||
.bg-trans-dark,.bg-trans-gradient,
|
||||
.bg-primary,
|
||||
.bg-secondary,
|
||||
.bg-blue,
|
||||
.bg-green,.bg-purple,.bg-red,.bg-facebook,.bg-apple,[class*="bg-black"],[class*="bg-gradient-"] {
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 #013;
|
||||
}
|
||||
|
||||
.bg-light p {
|
||||
color: #456;
|
||||
}
|
||||
/*.bg-white p,*/
|
||||
.bg-brown p{color: #666;
|
||||
}
|
||||
|
||||
/*Transparent/Opacity*/
|
||||
|
||||
.bg-trans-dark {
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.bg-trans-light {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/*Covers/Longforms...*/
|
||||
.bg-trans-gradient{
|
||||
background: linear-gradient(to top, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0) 100%);
|
||||
}
|
||||
|
||||
/*Horizontal Gradient*/
|
||||
|
||||
.bg-gradient-h {
|
||||
background: linear-gradient(134deg,#32b 0,#62b 100%);
|
||||
}
|
||||
|
||||
|
||||
/*Vertical Gradient*/
|
||||
|
||||
.bg-gradient-v {
|
||||
background: linear-gradient(to top, #62b 0%, #32b 100%);
|
||||
}
|
||||
|
||||
|
||||
/*Radial Gradient*/
|
||||
|
||||
.bg-gradient-r {
|
||||
background: radial-gradient(ellipse at center, #62b 0%, #32b 100%);
|
||||
}
|
||||
|
||||
/*White Gradient (vertical)*/
|
||||
.bg-gradient-white {
|
||||
background: linear-gradient(180deg,#f2f4f6 0,#fff 100%);
|
||||
color: #333;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*Gray Gradient (horizontal)*/
|
||||
.bg-gradient-gray{
|
||||
background: linear-gradient(90deg,#f7f9fb 0,#dee2e6 100%);
|
||||
color: #333;
|
||||
text-shadow: none;
|
||||
}
|
||||
/*Border/Frame*/
|
||||
.frame {
|
||||
border: .8rem solid #fff;
|
||||
}
|
||||
[class*="background"].frame {
|
||||
border-width: .2rem;
|
||||
}
|
||||
/*Layer/Box Shadow*/
|
||||
.shadow,.pre {
|
||||
position: relative;
|
||||
}
|
||||
.shadow:before,.shadow:after {
|
||||
box-shadow: 0 16px 24px rgba(0, 20, 80, 0.3);
|
||||
}
|
||||
|
||||
/*============================
|
||||
TYPOGRAPHY
|
||||
============================== */
|
||||
|
||||
/* -- Horizontal separator -- */
|
||||
|
||||
.text-separator:before {
|
||||
background-color: rgba(170, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
/* -- Pull Quote (Right/Left) -- */
|
||||
|
||||
[class*="text-pull-"] {
|
||||
border-top: 4px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
img[class*="text-pull-"],figure[class*="text-pull-"] {
|
||||
border-top: none;
|
||||
}
|
||||
/* -- Context -- */
|
||||
|
||||
[class*="bg-"] .text-context:before {
|
||||
background-color: #fff;
|
||||
}
|
||||
.text-context:before,.bg-white .text-context:before{
|
||||
background-color: rgba(0, 20, 80, 0.2);
|
||||
}
|
||||
|
||||
/* -- Text shadow -- */
|
||||
.text-shadow {
|
||||
text-shadow: 0 0 40px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* -- time, ampersands, prepositions (for, of...), symbols... -- */
|
||||
|
||||
[class*="card-"] time,
|
||||
h1 span {
|
||||
color: #abd;
|
||||
}
|
||||
|
||||
/* -- <pre> comment -- */
|
||||
.code-comment {
|
||||
color: rgba(70, 170, 130, 0.9);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Header/Nav
|
||||
=========================================== */
|
||||
|
||||
header[role=banner] {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.logo a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
nav[role=navigation] li a {
|
||||
background-color: rgba(50, 50, 50, .9);
|
||||
}
|
||||
|
||||
nav[role=navigation] li a:hover {
|
||||
background-color: rgba(50, 50, 50, .7);
|
||||
}
|
||||
|
||||
nav[role=navigation] li a,
|
||||
nav[role=navigation] li a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
nav[role=navigation] li.active a {
|
||||
background-color: #555;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
nav li.twitter a:hover {
|
||||
background-color: #1da1f3;
|
||||
}
|
||||
nav li.facebook a:hover {
|
||||
background-color: #3b5998;
|
||||
}
|
||||
|
||||
nav li.linkedin a:hover {
|
||||
background-color: #1683bb;
|
||||
}
|
||||
|
||||
nav li.dribbble a:hover {
|
||||
background-color: #ea4c89;
|
||||
}
|
||||
|
||||
nav li.github a:hover {
|
||||
background-color: #60b044;
|
||||
}
|
||||
|
||||
nav li.email a:hover {
|
||||
background: #dd4b39;
|
||||
}
|
||||
|
||||
/*===================================================
|
||||
.flexblock li hover/active
|
||||
===================================================== */
|
||||
|
||||
.flexblock li.active a,
|
||||
.metrics li:hover,
|
||||
.specs li:hover,.reasons li:hover {
|
||||
background-color: rgba(0, 20, 80, 0.03);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Features & Clients List
|
||||
=========================================== */
|
||||
|
||||
.features li,.clients li {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
[class*="bg-"] .features li,
|
||||
[class*="bg-"] .clients li {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.features li:hover,.clients li:hover {
|
||||
box-shadow: 0 8px 16px rgba(0,20,80,.02),0 4px 16px rgba(0,0,0,.08);
|
||||
}
|
||||
/*.features li span,.features li svg{color: #44d;}*/
|
||||
|
||||
/*============================
|
||||
.flexblock with border
|
||||
============================== */
|
||||
|
||||
.border {
|
||||
border-right: 1px solid rgba(0, 20, 80, 0.1);
|
||||
border-bottom: 1px solid rgba(0, 20, 80, 0.1);
|
||||
}
|
||||
|
||||
.border li {
|
||||
border-top: 1px solid rgba(0, 20, 80, 0.1);
|
||||
border-left: 1px solid rgba(0, 20, 80, 0.1);
|
||||
}
|
||||
|
||||
.flexblock.border li li {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/*===========================================
|
||||
flexblock.steps
|
||||
============================================= */
|
||||
|
||||
.steps li:nth-child(1) {
|
||||
background-color: #e8eef7;
|
||||
}
|
||||
|
||||
.steps li:nth-child(2) {
|
||||
background-color: #dde5f3;
|
||||
}
|
||||
|
||||
.steps li:nth-child(3) {
|
||||
background-color: #cdd8ec;
|
||||
}
|
||||
|
||||
.steps li:nth-child(4) {
|
||||
background-color: #bbcdec;
|
||||
}
|
||||
|
||||
.process {
|
||||
border-top: 15px solid transparent;
|
||||
border-bottom: 15px solid transparent;
|
||||
}
|
||||
|
||||
.steps li:hover,
|
||||
.steps.blink li:hover>a {
|
||||
background-color: #b8cef7;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.process.step-2 {
|
||||
border-left-color: #e8eef7;
|
||||
}
|
||||
.process.step-3 {
|
||||
border-left-color: #dde5f3;
|
||||
}
|
||||
.process.step-4 {
|
||||
border-left-color: #cdd8ec;
|
||||
}
|
||||
.steps li:hover + li [class*="step-"] {
|
||||
border-left-color: #b8cef7;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=========================================================
|
||||
Items: You can use for settings, drag&drop, close/delete...
|
||||
=========================================================== */
|
||||
|
||||
.specs li:after {
|
||||
background: linear-gradient(to right, rgba(0, 20, 80, 0) 0%, rgba(0, 20, 80, 0.2) 50%, rgba(0, 20, 80, 0) 100%);
|
||||
}
|
||||
|
||||
.specs li:last-child:after {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/*.specs li {background: rgba(255,255,255,0.2);}*/
|
||||
|
||||
/*=========================================================
|
||||
Why/Steps/Motivation/Reasons - Decimal/Numbers
|
||||
=========================================================== */
|
||||
|
||||
.reasons li:after {
|
||||
background: linear-gradient(to right, rgba(0, 20, 80, 0) 0%, rgba(0, 20, 80, 0.2) 50%, rgba(0, 20, 80, 0) 100%);
|
||||
}
|
||||
|
||||
.reasons li:last-child:after {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Overlays
|
||||
=========================================== */
|
||||
|
||||
.overlay {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
/*background-color: rgba(255,255,255 , 0.9);*/
|
||||
/*border: 3px double #fff;*/
|
||||
}
|
||||
|
||||
li:hover .overlay {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.overlay,
|
||||
.overlay a {
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 #111;
|
||||
}
|
||||
|
||||
|
||||
/*=========================================
|
||||
Gallery li+.overlay+image
|
||||
=========================================== */
|
||||
|
||||
.gallery li {
|
||||
background-color: rgba(0, 20, 80, 0.06);
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
.gallery li figcaption {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.flexblock.gallery li:hover {
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
.gallery li footer {
|
||||
border-top:1px solid rgba(0,20,80,0.1);
|
||||
}
|
||||
|
||||
.gallery li a {
|
||||
color: #333;
|
||||
text-shadow: none;
|
||||
}
|
||||
.flesblock.gallery li a footer{color: #aaa;}
|
||||
/*Arrow */
|
||||
|
||||
.gallery li figcaption:before {
|
||||
border: .8rem solid black;
|
||||
border-color: transparent transparent #fff #fff;
|
||||
/*box-shadow: -3px 3px 3px 0 rgba(0, 0, 0, 0.4);*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=========================================
|
||||
Plans / Pricing
|
||||
=========================================== */
|
||||
|
||||
.plans>li div,
|
||||
.flexblock.plans li:hover div {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.plans>li:hover,
|
||||
.plans>li:nth-child(2) {
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.plans:hover li:nth-child(2):not(:hover) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.plans li h2 {
|
||||
background-color: rgba(0, 20, 80, 0.5);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.plans ul li {
|
||||
border-bottom: 1px solid rgba(0, 20, 80, 0.1);
|
||||
}
|
||||
|
||||
.plans ul li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.plans>li>a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.plans>li>a {
|
||||
color: #333;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
/*============================
|
||||
Activity/CV/Timeline/News
|
||||
============================== */
|
||||
|
||||
.activity li {
|
||||
border-top: .1rem solid rgba(0, 20, 80, 0.1);
|
||||
}
|
||||
|
||||
.activity li:hover {
|
||||
background-color: rgba(0, 20, 80, 0.02);
|
||||
}
|
||||
|
||||
|
||||
/*=========================================
|
||||
Resume/Work/CV/Portfolio
|
||||
=========================================== */
|
||||
|
||||
.work-label,
|
||||
.work li a {
|
||||
border-bottom: 1px solid rgba(0, 20, 80, 0.1);
|
||||
}
|
||||
|
||||
.work li:nth-child(odd)>a {
|
||||
background-color: rgba(0, 20, 80, 0.03);
|
||||
}
|
||||
|
||||
.work li a:hover {
|
||||
background-color: rgba(0, 20, 80, 0.04);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================
|
||||
Clients / Services / Logos...
|
||||
============================================= */
|
||||
|
||||
|
||||
.clients.border figcaption {border-top:1px solid rgba(0,20,80,0.1);
|
||||
}
|
||||
/*.clients>li {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
*/
|
||||
|
||||
/*====================
|
||||
LOGOS
|
||||
====================== */
|
||||
|
||||
img.blacklogo {
|
||||
background: none;
|
||||
/* --- Images (black logo/image) --- */
|
||||
-webkit-filter: grayscale(100%) brightness(10%) contrast(100%);
|
||||
filter: grayscale(100%) brightness(10%) contrast(100%);
|
||||
}
|
||||
|
||||
|
||||
/* --- Images (gray logo/image) --- */
|
||||
|
||||
img.graylogo {
|
||||
-webkit-filter: grayscale(100%) brightness(10%) contrast(10%);
|
||||
filter: grayscale(100%) brightness(10%) contrast(10%);
|
||||
}
|
||||
|
||||
|
||||
/* --- Images (white Logo/Image) --- */
|
||||
|
||||
img.whitelogo {
|
||||
-webkit-filter: brightness(0) invert(1);
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
|
||||
/* --- Logo/Images Hover --- */
|
||||
|
||||
li:hover img.blacklogo,
|
||||
li:hover img.graylogo,
|
||||
img.blacklogo:hover,img.graylogo:hover {
|
||||
background: none;
|
||||
/*Images - Original Color*/
|
||||
filter: grayscale(0%);
|
||||
-webkit-filter: grayscale(0%);
|
||||
filter: none;
|
||||
transition: all 0.6s ease;
|
||||
}
|
||||
|
||||
|
||||
/*=========================================================
|
||||
Cards
|
||||
=========================================================== */
|
||||
|
||||
[class*="card-"]>a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* --- card ul specs --- */
|
||||
|
||||
.description>li {
|
||||
border-bottom: 1px solid rgba(0, 20, 80, 0.1);
|
||||
}
|
||||
|
||||
.description>li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/*== Figure Background === */
|
||||
|
||||
[class*="card-"][class*="bg-"] figure {
|
||||
background-color: rgba(0, 20, 80, 0.06);
|
||||
}
|
||||
|
||||
/*== Ficaption Cards === */
|
||||
|
||||
[class*="card"] figcaption,
|
||||
[class*="card"] figcaption a {
|
||||
color: #fff;
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.2) 100%);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
/*===CTA (Call to Action - Numbers, Price, Promo...) ===== */
|
||||
.cta .benefit {
|
||||
border-left-width: 1px;
|
||||
border-style: solid;
|
||||
border-image: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.4) 50%, transparent) 1 100%;
|
||||
-webkit-border-image: -webkit-linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.4) 50%, transparent) 1 100%;
|
||||
-moz-border-image: -moz-linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.4) 50%, transparent) 1 100%;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=========================================
|
||||
Tables
|
||||
=========================================== */
|
||||
|
||||
table td,
|
||||
th,
|
||||
thead {
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
thead {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
tr:nth-child(even)>td {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
tr>td {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
td:hover,
|
||||
tr:nth-child(even)>td:hover {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
|
||||
/*============================
|
||||
Browser (Screenshots)
|
||||
============================== */
|
||||
|
||||
.browser {
|
||||
border: 1px solid rgba(0, 20, 80, 0.1);
|
||||
}
|
||||
|
||||
.browser:hover {
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
|
||||
/*=== Topbar === */
|
||||
|
||||
.browser:before {
|
||||
background-color: rgba(0, 20, 80, 0.1);
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
border-bottom: 1px solid rgba(0, 20, 80, 0.2);
|
||||
}
|
||||
|
||||
.browser:hover:before {
|
||||
background-color: rgba(0, 20, 80, 0.12);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
/*=========================================
|
||||
Forms
|
||||
=========================================== */
|
||||
|
||||
input,
|
||||
textarea {
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 5px rgba(81, 203, 238, 1);
|
||||
}
|
||||
input:focus::-moz-placeholder {
|
||||
color: #ddd;
|
||||
}
|
||||
input:focus::-webkit-input-placeholder {
|
||||
color: #ddd;
|
||||
}
|
||||
a.button,[class*="badge-"]
|
||||
button[type="submit"],
|
||||
input {
|
||||
box-shadow: 0px 10px 16px -8px rgba(0, 20, 80, 0.3);
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
button[type="submit"],
|
||||
input[type="submit"],
|
||||
.button,.button:hover,
|
||||
button[type="submit"]:hover,
|
||||
input[type="submit"]:hover
|
||||
{
|
||||
border: 1px solid #44d;
|
||||
}
|
||||
|
||||
button[type="submit"],
|
||||
input[type="submit"],
|
||||
.button,.button:hover,button[type="submit"]:hover,input[type="submit"]:hover {
|
||||
color: #fff;
|
||||
background-color: #44d;
|
||||
text-shadow: 0 1px 0 #123;
|
||||
}
|
||||
.button:active,button[type="submit"]:active,input[type="submit"]:active {
|
||||
background-color: #17d;
|
||||
}
|
||||
.ghost,.ghost:hover {background: none;color: inherit;text-shadow: none;}
|
||||
.bg-primary select,
|
||||
.bg-primary textarea,
|
||||
.bg-primary .button,
|
||||
.bg-primary button,.bg-primary button:hover,
|
||||
.bg-primary input,
|
||||
[class*="bg-gradient-"] .button,[class*="bg-"] a.button.ghost
|
||||
{
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
[class*="bg-"] a.button {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.bg-white a.button.ghost,.bg-gradient-white a.button.ghost {color: #333;border: 1px solid #44d;}
|
||||
|
||||
:disabled,
|
||||
button:disabled:hover {
|
||||
background-color: #eee;
|
||||
border-color: #eee;
|
||||
color: #ccc;
|
||||
}
|
||||
fieldset {
|
||||
border: 1px solid #44d;
|
||||
background-color: rgba(0, 20, 80, 0.2)
|
||||
}
|
||||
|
||||
legend {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
/* Inputs/Buttons - hover */
|
||||
|
||||
input:hover,
|
||||
select:hover {
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
|
||||
/* App Store Badges */
|
||||
|
||||
[class*="badge-"] {
|
||||
border: 1px solid #345;
|
||||
background-color: #000;
|
||||
/* Transparent Button */
|
||||
/* background: none;*/
|
||||
}
|
||||
|
||||
|
||||
form .flexblock li:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/*============================
|
||||
Table of Contents
|
||||
============================== */
|
||||
|
||||
.toc,
|
||||
.toc ol>li:before,
|
||||
.chapter {
|
||||
background-color: #f7f9fb;
|
||||
}
|
||||
|
||||
.toc li .toc-page:before {
|
||||
border-bottom: 1px dotted rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
|
||||
/*============================
|
||||
Slides (Counter/Arrows)
|
||||
============================== */
|
||||
|
||||
|
||||
/*#navigation:hover {
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
*/
|
||||
#counter,
|
||||
#navigation a {
|
||||
color: #abc;
|
||||
}
|
||||
|
||||
#webslides:hover #navigation a:hover {
|
||||
color: #fff;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
/*============================
|
||||
Footer
|
||||
============================== */
|
||||
|
||||
footer[role=contentinfo] {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/*footer:hover {
|
||||
background-color:rgba(255,255,255 , 0.3);
|
||||
}
|
||||
*/
|
3791
static/css/webslides.css
Normal file
3791
static/css/webslides.css
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
6
static/js/webslides.min.js
vendored
6
static/js/webslides.min.js
vendored
File diff suppressed because one or more lines are too long
40
test/dom.js
40
test/dom.js
@@ -1,40 +0,0 @@
|
||||
import test from 'ava';
|
||||
import DOM from '../src/js/utils/dom';
|
||||
|
||||
test('DOM.createNode', t => {
|
||||
const div = DOM.createNode('div', 'my-id');
|
||||
t.is(div.tagName, 'DIV');
|
||||
t.is(div.id, 'my-id');
|
||||
t.is(div.innerHTML, '');
|
||||
});
|
||||
|
||||
test('DOM.once', t => {
|
||||
const div = DOM.createNode('div');
|
||||
DOM.once(div, 'click', () => div.classList.toggle('ok'));
|
||||
div.click();
|
||||
t.is(div.className, 'ok');
|
||||
div.click();
|
||||
t.is(div.className, 'ok');
|
||||
});
|
||||
|
||||
test('DOM.hide', t => {
|
||||
const div = DOM.createNode('div');
|
||||
DOM.hide(div);
|
||||
t.is(div.style.display, 'none');
|
||||
});
|
||||
|
||||
test('DOM.show', t => {
|
||||
const div = DOM.createNode('div');
|
||||
DOM.hide(div);
|
||||
DOM.show(div);
|
||||
t.is(div.style.display, '');
|
||||
});
|
||||
|
||||
test('DOM.fireEvent', t => {
|
||||
const div = DOM.createNode('div');
|
||||
div.addEventListener('toggle-class', () => div.classList.toggle('ok'));
|
||||
DOM.fireEvent(div, 'toggle-class');
|
||||
t.is(div.className, 'ok');
|
||||
DOM.fireEvent(div, 'toggle-class');
|
||||
t.is(div.className, '');
|
||||
});
|
@@ -1,2 +0,0 @@
|
||||
import browserEnv from 'browser-env';
|
||||
browserEnv();
|
152
test/modules/slide.test.js
Normal file
152
test/modules/slide.test.js
Normal file
@@ -0,0 +1,152 @@
|
||||
import Slide from '../../src/js/modules/slide';
|
||||
|
||||
describe('Slide module', () => {
|
||||
test('Candidate', () => {
|
||||
const valid = document.createElement('section');
|
||||
const invalid = document.createElement('p');
|
||||
|
||||
expect(Slide.isCandidate(valid)).toBe(true);
|
||||
expect(Slide.isCandidate(invalid)).toBe(false);
|
||||
});
|
||||
|
||||
describe('Instance behaviour', () => {
|
||||
let ws;
|
||||
let slides;
|
||||
|
||||
beforeEach(() => {
|
||||
const template =
|
||||
'<section><div class="content">Content</div></section>'
|
||||
.repeat(5);
|
||||
document.body.innerHTML = `<div id="webslides">${template}</div>`;
|
||||
|
||||
const el = document.getElementById('webslides');
|
||||
slides = [];
|
||||
|
||||
el.querySelectorAll('section').forEach((el, i) => {
|
||||
slides.push(new Slide(el, i));
|
||||
});
|
||||
|
||||
ws = {
|
||||
el,
|
||||
slides
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
test('Slides should have some properties', () => {
|
||||
const slide = ws.slides[0];
|
||||
|
||||
expect(slide.el).toBeInstanceOf(Element);
|
||||
expect(slide.el.id).toBe('section-1');
|
||||
expect(slide.parent).toBeInstanceOf(Element);
|
||||
expect(slide.parent.id).toBe('webslides');
|
||||
expect(slide.i).toBe(0);
|
||||
});
|
||||
|
||||
test('Slides should get a slide class and be hidden', () => {
|
||||
const slide = ws.slides[0];
|
||||
|
||||
expect(slide.el.classList.contains('slide')).toBe(true);
|
||||
expect(slide.el.style.display).toBe('none');
|
||||
});
|
||||
|
||||
test('Show/hide', () => {
|
||||
const slide = ws.slides[0];
|
||||
|
||||
slide.show();
|
||||
expect(slide.el.style.display).not.toBe('none');
|
||||
expect(slide.el.classList.contains('current')).toBe(true);
|
||||
|
||||
slide.hide();
|
||||
expect(slide.el.style.display).toBe('none');
|
||||
expect(slide.el.classList.contains('current')).not.toBe(true);
|
||||
});
|
||||
|
||||
test('Events', () => {
|
||||
const slide = ws.slides[0];
|
||||
const leave = jest.fn();
|
||||
const enter = jest.fn();
|
||||
const enable = jest.fn();
|
||||
const disable = jest.fn();
|
||||
const show = jest.fn();
|
||||
|
||||
slide.el.addEventListener('dom:leave', leave);
|
||||
slide.el.addEventListener('dom:enter', enter);
|
||||
slide.el.addEventListener('slide:enable', enable);
|
||||
slide.el.addEventListener('slide:disable', disable);
|
||||
slide.el.addEventListener('slide:show', show);
|
||||
|
||||
expect(enter).not.toHaveBeenCalled();
|
||||
expect(leave).not.toHaveBeenCalled();
|
||||
expect(enable).not.toHaveBeenCalled();
|
||||
expect(disable).not.toHaveBeenCalled();
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
|
||||
slide.enable();
|
||||
expect(enter).not.toHaveBeenCalled();
|
||||
expect(leave).not.toHaveBeenCalled();
|
||||
expect(enable).toHaveBeenCalledTimes(1);
|
||||
expect(disable).not.toHaveBeenCalled();
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
enable.mockClear();
|
||||
|
||||
slide.disable();
|
||||
expect(enter).not.toHaveBeenCalled();
|
||||
expect(leave).not.toHaveBeenCalled();
|
||||
expect(enable).not.toHaveBeenCalled();
|
||||
expect(disable).toHaveBeenCalledTimes(1);
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
disable.mockClear();
|
||||
|
||||
slide.moveAfterLast();
|
||||
expect(enter).toHaveBeenCalledTimes(1);
|
||||
expect(leave).toHaveBeenCalledTimes(1);
|
||||
expect(enable).not.toHaveBeenCalled();
|
||||
expect(disable).not.toHaveBeenCalled();
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
enter.mockClear();
|
||||
leave.mockClear();
|
||||
|
||||
slide.moveBeforeFirst();
|
||||
expect(enter).toHaveBeenCalledTimes(1);
|
||||
expect(leave).toHaveBeenCalledTimes(1);
|
||||
expect(enable).not.toHaveBeenCalled();
|
||||
expect(disable).not.toHaveBeenCalled();
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
enter.mockClear();
|
||||
leave.mockClear();
|
||||
|
||||
slide.show();
|
||||
expect(show).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Move', () => {
|
||||
const wsEl = document.getElementById('webslides');
|
||||
const slide = ws.slides[0];
|
||||
|
||||
expect(wsEl.lastChild).not.toBe(slide.el);
|
||||
slide.moveAfterLast();
|
||||
expect(wsEl.lastChild).toBe(slide.el);
|
||||
|
||||
expect(wsEl.firstChild).not.toBe(slide.el);
|
||||
slide.moveBeforeFirst();
|
||||
expect(wsEl.firstChild).toBe(slide.el);
|
||||
});
|
||||
|
||||
test('Get section from el', () => {
|
||||
const wsEl = document.getElementById('webslides');
|
||||
const el = ws.slides[3].el.firstChild;
|
||||
const found = Slide.getSectionFromEl(el);
|
||||
|
||||
expect(found.section.id).toBe('section-4');
|
||||
expect(found.i).toBe(4);
|
||||
|
||||
const notFound = Slide.getSectionFromEl(wsEl);
|
||||
expect(notFound.section).toBeNull();
|
||||
expect(notFound.i).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
411
test/modules/webslides.test.js
Normal file
411
test/modules/webslides.test.js
Normal file
@@ -0,0 +1,411 @@
|
||||
import WebSlides from '../../src/js/modules/webslides';
|
||||
import Slide from '../../src/js/modules/slide';
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
let ws;
|
||||
let webslides;
|
||||
|
||||
beforeEach(() => {
|
||||
const slides =
|
||||
'<section class="slide"><div class="content">Content</section>'.repeat(20);
|
||||
document.body.innerHTML =
|
||||
`<div id="webslides">${slides}<div id="other"></div></div>`;
|
||||
|
||||
ws = document.getElementById('webslides');
|
||||
webslides = new WebSlides();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.body.innerHTML = '';
|
||||
location.hash = '';
|
||||
});
|
||||
|
||||
test('Should throw if no element is found with webslides id', () => {
|
||||
document.body.innerHTML = '';
|
||||
|
||||
expect(() => {
|
||||
ws.setAttribute('id', '');
|
||||
new WebSlides();
|
||||
}).toThrow('Couldn\'t find the webslides container!');
|
||||
});
|
||||
|
||||
test('Should have correct properties', () => {
|
||||
expect(webslides.isMoving).toBe(false);
|
||||
expect(webslides.slides.length).toBe(20);
|
||||
expect(webslides.currentSlideI_).toBe(0);
|
||||
expect(webslides.currentSlide_).toBe(webslides.slides[0]);
|
||||
expect(webslides.maxSlide_).toBe(20);
|
||||
expect(webslides.isVertical).toBe(false);
|
||||
expect(webslides.initialised).toBe(true);
|
||||
|
||||
expect(webslides.slides[0]).toBeInstanceOf(Slide);
|
||||
|
||||
// Plugins
|
||||
expect(webslides.plugins.autoslide).toBeDefined();
|
||||
expect(webslides.plugins.clickNav).toBeDefined();
|
||||
expect(webslides.plugins.grid).toBeDefined();
|
||||
expect(webslides.plugins.hash).toBeDefined();
|
||||
expect(webslides.plugins.keyboard).toBeDefined();
|
||||
expect(webslides.plugins.nav).toBeDefined();
|
||||
expect(webslides.plugins.scroll).toBeDefined();
|
||||
expect(webslides.plugins.touch).toBeDefined();
|
||||
expect(webslides.plugins.video).toBeDefined();
|
||||
expect(webslides.plugins.youtube).toBeDefined();
|
||||
expect(webslides.plugins.zoom).toBeDefined();
|
||||
|
||||
// Options
|
||||
expect(webslides.options.autoslide).toBe(false);
|
||||
expect(webslides.options.changeOnClick).toBe(false);
|
||||
expect(webslides.options.loop).toBe(true);
|
||||
expect(webslides.options.minWheelDelta).toBe(40);
|
||||
expect(webslides.options.navigateOnScroll).toBe(true);
|
||||
expect(webslides.options.scrollWait).toBe(450);
|
||||
expect(webslides.options.slideOffset).toBe(50);
|
||||
});
|
||||
|
||||
test('Should be able to define vertical WS', () => {
|
||||
ws.classList.add('vertical');
|
||||
webslides = new WebSlides();
|
||||
|
||||
expect(webslides.isVertical).toBe(true);
|
||||
});
|
||||
|
||||
test('Should remove all elements that are not sections', () => {
|
||||
expect(document.getElementById('other')).toBeNull();
|
||||
});
|
||||
|
||||
test('Ready', () => {
|
||||
// Already initialised
|
||||
expect(document.documentElement.classList.contains('ws-ready')).toBe(true);
|
||||
document.documentElement.classList.remove('ws-ready');
|
||||
const listener = jest.fn();
|
||||
|
||||
ws.addEventListener('ws:init', listener);
|
||||
webslides.initialised = false;
|
||||
webslides.onInit_();
|
||||
expect(listener).toHaveBeenCalled();
|
||||
expect(document.documentElement.classList.contains('ws-ready')).toBe(true);
|
||||
expect(webslides.initialised).toBe(true);
|
||||
});
|
||||
|
||||
test('Should be possible to init with a different slide', () => {
|
||||
location.hash = '#slide=4';
|
||||
webslides = new WebSlides();
|
||||
expect(webslides.currentSlideI_).toBe(3);
|
||||
});
|
||||
|
||||
describe('Go to slide', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(webslides, 'scrollTransitionToSlide_');
|
||||
jest.spyOn(webslides, 'transitionToSlide_');
|
||||
});
|
||||
|
||||
test('Shouldn\'t allow to go to invalid indexes', () => {
|
||||
webslides.goToSlide(-4);
|
||||
webslides.goToSlide(null);
|
||||
webslides.goToSlide(99);
|
||||
|
||||
expect(webslides.scrollTransitionToSlide_).not.toHaveBeenCalled();
|
||||
expect(webslides.transitionToSlide_).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Shouldn\'t allow to move if already moving', () => {
|
||||
webslides.isMoving = true;
|
||||
webslides.goToSlide(2);
|
||||
expect(webslides.scrollTransitionToSlide_).not.toHaveBeenCalled();
|
||||
expect(webslides.transitionToSlide_).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Shouldn\'t allow to move if going to same slide', () => {
|
||||
webslides.goToSlide(0);
|
||||
expect(webslides.scrollTransitionToSlide_).not.toHaveBeenCalled();
|
||||
expect(webslides.transitionToSlide_).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Shouldn\'t use Scroll if first slide', () => {
|
||||
webslides.isVertical = true;
|
||||
webslides.currentSlide_ = null;
|
||||
|
||||
webslides.goToSlide(1);
|
||||
|
||||
expect(webslides.scrollTransitionToSlide_).not.toHaveBeenCalled();
|
||||
expect(webslides.transitionToSlide_).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Shouldn\'t use Scroll if not vertical', () => {
|
||||
webslides.isVertical = false;
|
||||
webslides.goToSlide(1);
|
||||
|
||||
expect(webslides.scrollTransitionToSlide_).not.toHaveBeenCalled();
|
||||
expect(webslides.transitionToSlide_).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Shouldn\'t use Scroll if no touch or not enabled', () => {
|
||||
webslides.plugins.touch = null;
|
||||
webslides.goToSlide(1);
|
||||
|
||||
expect(webslides.scrollTransitionToSlide_).not.toHaveBeenCalled();
|
||||
expect(webslides.transitionToSlide_).toHaveBeenCalled();
|
||||
webslides.transitionToSlide_.mockClear();
|
||||
|
||||
webslides.plugins.touch = {
|
||||
isEnabled: false
|
||||
};
|
||||
|
||||
webslides.goToSlide(2);
|
||||
|
||||
expect(webslides.scrollTransitionToSlide_).not.toHaveBeenCalled();
|
||||
expect(webslides.transitionToSlide_).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Forward should be true if moving ahead or forced', () => {
|
||||
const getIsMovingForward = () =>
|
||||
webslides.transitionToSlide_.mock.calls[0][0];
|
||||
|
||||
webslides.goToSlide(2);
|
||||
expect(getIsMovingForward()).toBe(true);
|
||||
webslides.transitionToSlide_.mockClear();
|
||||
|
||||
// Going back
|
||||
webslides.goToSlide(1);
|
||||
expect(getIsMovingForward()).toBe(false);
|
||||
webslides.transitionToSlide_.mockClear();
|
||||
|
||||
// Going forward but forced
|
||||
webslides.goToSlide(3, false);
|
||||
expect(getIsMovingForward()).toBe(false);
|
||||
webslides.transitionToSlide_.mockClear();
|
||||
});
|
||||
|
||||
test('Should pass correct arguments to transition to slide', () => {
|
||||
webslides.goToSlide(2);
|
||||
const args = webslides.transitionToSlide_.mock.calls[0];
|
||||
|
||||
expect(args[1]).toBeInstanceOf(Slide);
|
||||
expect(args[1]).toBe(webslides.slides[2]);
|
||||
expect(args[2]).toBe(webslides.onSlideChange_);
|
||||
});
|
||||
|
||||
test('Should pass correct arguments to scroll to slide', () => {
|
||||
webslides.isVertical = true;
|
||||
webslides.goToSlide(2);
|
||||
const args = webslides.scrollTransitionToSlide_.mock.calls[0];
|
||||
|
||||
expect(args[1]).toBeInstanceOf(Slide);
|
||||
expect(args[1]).toBe(webslides.slides[2]);
|
||||
expect(args[2]).toBe(webslides.onSlideChange_);
|
||||
});
|
||||
|
||||
test('After move', () => {
|
||||
webslides.isVertical = true;
|
||||
const mock = jest.fn();
|
||||
const currentSlide = webslides.currentSlide_;
|
||||
webslides.el.addEventListener('ws:slide-change', mock);
|
||||
|
||||
webslides.goToSlide(1);
|
||||
expect(webslides.isMoving).toBe(true);
|
||||
jest.runAllTimers();
|
||||
expect(webslides.isMoving).toBe(false);
|
||||
expect(webslides.currentSlide_).not.toBe(currentSlide);
|
||||
expect(webslides.currentSlide_).toBe(webslides.slides[1]);
|
||||
expect(webslides.currentSlideI_).toBe(1);
|
||||
expect(currentSlide.el.style.display).toBe('none');
|
||||
|
||||
const mockEvent = mock.mock.calls[0][0].detail;
|
||||
expect(mockEvent.slides).toBe(webslides.maxSlide_);
|
||||
expect(mockEvent.currentSlide0).toBe(1);
|
||||
expect(mockEvent.currentSlide).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Go next/prev', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(webslides, 'goToSlide');
|
||||
});
|
||||
|
||||
test('Go next should go to the next slide', () => {
|
||||
webslides.goNext();
|
||||
expect(webslides.goToSlide).toHaveBeenCalledWith(1, true);
|
||||
});
|
||||
|
||||
test('Go prev should go to the previous slide', () => {
|
||||
webslides.currentSlideI_ = 2;
|
||||
webslides.goPrev();
|
||||
expect(webslides.goToSlide).toHaveBeenCalledWith(1, false);
|
||||
});
|
||||
|
||||
test('Should not be possible to move if loop is disabled and on edge', () => {
|
||||
webslides.options.loop = false;
|
||||
webslides.goPrev();
|
||||
expect(webslides.goToSlide).not.toHaveBeenCalled();
|
||||
webslides.currentSlideI_ = webslides.maxSlide_;
|
||||
webslides.goNext();
|
||||
expect(webslides.goToSlide).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('It should loop correctly', () => {
|
||||
webslides.currentSlideI_ = webslides.maxSlide_ - 1;
|
||||
webslides.goNext();
|
||||
expect(webslides.goToSlide).toHaveBeenCalledWith(0, true);
|
||||
|
||||
webslides.goPrev();
|
||||
expect(webslides.goToSlide).toHaveBeenCalledWith(19, false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Scroll to', () => {
|
||||
test('Overflow should be removed and resetted', () => {
|
||||
webslides.scrollTransitionToSlide_(true, webslides.slides[1], () => {});
|
||||
expect(webslides.el.style.overflow).toBe('hidden');
|
||||
jest.runAllTimers();
|
||||
expect(webslides.el.style.overflow).not.toBe('hidden');
|
||||
});
|
||||
|
||||
test('Should move slide if not moving forward', () => {
|
||||
const getHTML = () => webslides.el.innerHTML;
|
||||
|
||||
expect(getHTML().indexOf('section-1"'))
|
||||
.toBeLessThan(getHTML().indexOf('section-20"'));
|
||||
|
||||
webslides.scrollTransitionToSlide_(false, webslides.slides[19], () => {});
|
||||
|
||||
expect(getHTML().indexOf('section-20"'))
|
||||
.toBeLessThan(getHTML().indexOf('section-1"'));
|
||||
});
|
||||
|
||||
test('Should not move slide if moving forward', () => {
|
||||
const getHTML = () => webslides.el.innerHTML;
|
||||
|
||||
expect(getHTML().indexOf('section-1"'))
|
||||
.toBeLessThan(getHTML().indexOf('section-2"'));
|
||||
|
||||
webslides.scrollTransitionToSlide_(true, webslides.slides[1], () => {});
|
||||
|
||||
expect(getHTML().indexOf('section-1"'))
|
||||
.toBeLessThan(getHTML().indexOf('section-2"'));
|
||||
});
|
||||
|
||||
test('Should call the callback once finished with the next slide', () => {
|
||||
const cb = jest.fn();
|
||||
|
||||
webslides.scrollTransitionToSlide_(true, webslides.slides[1], cb);
|
||||
expect(cb).not.toHaveBeenCalled();
|
||||
jest.runAllTimers();
|
||||
expect(cb).toHaveBeenCalledWith(webslides.slides[1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Transition to', () => {
|
||||
test('Should move slide if not moving forward', () => {
|
||||
const getHTML = () => webslides.el.innerHTML;
|
||||
|
||||
expect(getHTML().indexOf('section-1"'))
|
||||
.toBeLessThan(getHTML().indexOf('section-20"'));
|
||||
|
||||
webslides.transitionToSlide_(false, webslides.slides[19], () => {});
|
||||
|
||||
expect(getHTML().indexOf('section-20"'))
|
||||
.toBeLessThan(getHTML().indexOf('section-1"'));
|
||||
});
|
||||
|
||||
test('Should move current slide to last if moving forward', () => {
|
||||
const getHTML = () => webslides.el.innerHTML;
|
||||
|
||||
expect(getHTML().indexOf('section-1'))
|
||||
.toBeLessThan(getHTML().indexOf('section-2'));
|
||||
|
||||
webslides.transitionToSlide_(true, webslides.slides[1], () => {});
|
||||
|
||||
expect(getHTML().indexOf('section-1"'))
|
||||
.toBeGreaterThan(getHTML().indexOf('section-20"'));
|
||||
});
|
||||
|
||||
test('Should slideInRight if touch and moving forward', () => {
|
||||
const callback = jest.fn();
|
||||
const nextSlideEl = webslides.slides[19].el;
|
||||
webslides.initialised = true;
|
||||
webslides.plugins.touch = {
|
||||
isEnabled: true
|
||||
};
|
||||
|
||||
webslides.transitionToSlide_(true, webslides.slides[19], callback);
|
||||
expect(nextSlideEl.classList.contains('slideInRight'))
|
||||
.toBe(true);
|
||||
expect(callback).not.toBeCalled();
|
||||
DOM.fireEvent(nextSlideEl, 'animationend');
|
||||
expect(callback).toHaveBeenCalledWith(webslides.slides[19]);
|
||||
expect(nextSlideEl.classList.contains('slideInRight'))
|
||||
.toBe(false);
|
||||
});
|
||||
|
||||
test('Should slideInLeft if touch and not moving forward', () => {
|
||||
const callback = jest.fn();
|
||||
const nextSlideEl = webslides.slides[1].el;
|
||||
webslides.initialised = true;
|
||||
webslides.plugins.touch = {
|
||||
isEnabled: true
|
||||
};
|
||||
|
||||
webslides.transitionToSlide_(false, webslides.slides[1], callback);
|
||||
expect(nextSlideEl.classList.contains('slideInLeft'))
|
||||
.toBe(true);
|
||||
expect(callback).not.toBeCalled();
|
||||
DOM.fireEvent(nextSlideEl, 'animationend');
|
||||
expect(callback).toHaveBeenCalledWith(webslides.slides[1]);
|
||||
expect(nextSlideEl.classList.contains('slideInLeft'))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
test('Enable/Disable', () => {
|
||||
expect(webslides.isDisabled()).toBe(false);
|
||||
expect(webslides.el.classList.contains('disabled')).toBe(false);
|
||||
webslides.disable();
|
||||
expect(webslides.el.classList.contains('disabled')).toBe(true);
|
||||
expect(webslides.isDisabled()).toBe(true);
|
||||
|
||||
webslides.enable();
|
||||
expect(webslides.isDisabled()).toBe(false);
|
||||
|
||||
expect(webslides.el.classList.contains('disabled')).toBe(false);
|
||||
});
|
||||
|
||||
test('Fullscreen', () => {
|
||||
// Mocking FullScreen API
|
||||
document.fullscreen = false;
|
||||
document.documentElement.requestFullscreen = jest.fn();
|
||||
document.exitFullScreen = jest.fn();
|
||||
|
||||
expect(document.documentElement.requestFullscreen).not.toHaveBeenCalled();
|
||||
webslides.fullscreen();
|
||||
expect(document.documentElement.requestFullscreen).toHaveBeenCalled();
|
||||
document.fullscreen = true;
|
||||
expect(document.exitFullScreen).not.toHaveBeenCalled();
|
||||
webslides.fullscreen();
|
||||
expect(document.exitFullScreen).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Zoom', () => {
|
||||
webslides.plugins.zoom = {
|
||||
toggleZoom: jest.fn()
|
||||
};
|
||||
|
||||
expect(webslides.plugins.zoom.toggleZoom).not.toHaveBeenCalled();
|
||||
webslides.toggleZoom();
|
||||
expect(webslides.plugins.zoom.toggleZoom).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Plugin register', () => {
|
||||
const cto = jest.fn();
|
||||
const Mock = function() {
|
||||
cto();
|
||||
};
|
||||
|
||||
WebSlides.registerPlugin('mock', Mock);
|
||||
webslides = new WebSlides();
|
||||
|
||||
expect(cto).toHaveBeenCalled();
|
||||
expect(webslides.plugins.mock).toBeDefined();
|
||||
});
|
43
test/plugins/autoslide.test.js
Normal file
43
test/plugins/autoslide.test.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
import AutoSlide from '../../src/js/plugins/autoslide';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
beforeAll(() => {
|
||||
document.body.innerHTML =
|
||||
`<div id="webslides"></div><input id="focusable" />`;
|
||||
});
|
||||
|
||||
test('AutoSlide plugin', () => {
|
||||
const next = jest.fn();
|
||||
const ws = document.getElementById('webslides');
|
||||
const webslides = {
|
||||
options: {
|
||||
autoslide: 100
|
||||
},
|
||||
goNext: next,
|
||||
el: ws
|
||||
};
|
||||
|
||||
expect(next).not.toBeCalled();
|
||||
|
||||
new AutoSlide(webslides);
|
||||
DOM.fireEvent(ws, 'ws:init');
|
||||
|
||||
// Wait until next execution
|
||||
jest.runTimersToTime(101);
|
||||
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
|
||||
// Wait until next execution
|
||||
jest.runTimersToTime(101);
|
||||
|
||||
expect(next.mock.calls.length).toBe(2);
|
||||
|
||||
// Pause on focus
|
||||
document.getElementById('focusable').focus();
|
||||
DOM.fireEvent(document.body, 'focus');
|
||||
jest.runTimersToTime(101);
|
||||
|
||||
expect(next.mock.calls.length).toBe(2);
|
||||
});
|
26
test/plugins/click-nav.test.js
Normal file
26
test/plugins/click-nav.test.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
import ClickNav from '../../src/js/plugins/click-nav';
|
||||
|
||||
beforeAll(() => {
|
||||
document.body.innerHTML =
|
||||
`<div id="webslides" data-test="test"><p>Text</p></div>`;
|
||||
});
|
||||
|
||||
test('Click nav plugin', () => {
|
||||
const next = jest.fn();
|
||||
const ws = document.getElementById('webslides');
|
||||
|
||||
const webslides = {
|
||||
options: {
|
||||
changeOnClick: true
|
||||
},
|
||||
goNext: next,
|
||||
el: ws
|
||||
};
|
||||
|
||||
expect(next).not.toBeCalled();
|
||||
|
||||
new ClickNav(webslides);
|
||||
DOM.fireEvent(ws, 'click');
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
});
|
91
test/plugins/keyboard.test.js
Normal file
91
test/plugins/keyboard.test.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import Keyboard from '../../src/js/plugins/keyboard';
|
||||
import Keys from '../../src/js/utils/keys';
|
||||
|
||||
// @TODO: Check to do this with simulant
|
||||
const simulateKeyEvent = (el, code, extra) => {
|
||||
const config = Object.assign({
|
||||
bubbles: true,
|
||||
cancelableCode: true,
|
||||
which: code,
|
||||
shiftKey: false}, extra);
|
||||
|
||||
const evt = new KeyboardEvent('keydown', config);
|
||||
el.dispatchEvent(evt);
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
document.body.innerHTML = `<div id="webslides" data-test="test">
|
||||
<p>Text</p>
|
||||
</div>
|
||||
<input id="focusable" />`;
|
||||
});
|
||||
|
||||
test('Keyboard plugin', () => {
|
||||
const goto = jest.fn();
|
||||
const next = jest.fn();
|
||||
const prev = jest.fn();
|
||||
const fullscreen = jest.fn();
|
||||
const ws = document.getElementById('webslides');
|
||||
|
||||
let disabled = true;
|
||||
|
||||
const webslides = {
|
||||
goToSlide: goto,
|
||||
goNext: next,
|
||||
goPrev: prev,
|
||||
isVertical: false,
|
||||
fullscreen: fullscreen,
|
||||
isDisabled: () => disabled,
|
||||
el: ws
|
||||
};
|
||||
|
||||
const key = new Keyboard(webslides);
|
||||
|
||||
expect(goto).not.toBeCalled();
|
||||
expect(next).not.toBeCalled();
|
||||
expect(prev).not.toBeCalled();
|
||||
|
||||
simulateKeyEvent(document, Keys.AV_PAGE);
|
||||
expect(next.mock.calls.length).toBe(0);
|
||||
|
||||
disabled = false;
|
||||
simulateKeyEvent(document, Keys.AV_PAGE);
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
simulateKeyEvent(document, Keys.SPACE);
|
||||
expect(next.mock.calls.length).toBe(2);
|
||||
// Shift + Space
|
||||
simulateKeyEvent(document, Keys.SPACE, {shiftKey: true});
|
||||
expect(next.mock.calls.length).toBe(2);
|
||||
expect(prev.mock.calls.length).toBe(1);
|
||||
simulateKeyEvent(document, Keys.RE_PAGE);
|
||||
expect(prev.mock.calls.length).toBe(2);
|
||||
|
||||
// Home - End
|
||||
simulateKeyEvent(document, Keys.HOME);
|
||||
expect(goto.mock.calls.length).toBe(1);
|
||||
simulateKeyEvent(document, Keys.END);
|
||||
expect(goto.mock.calls.length).toBe(2);
|
||||
|
||||
// Arrow keys, only left right should increase
|
||||
simulateKeyEvent(document, Keys.DOWN);
|
||||
simulateKeyEvent(document, Keys.UP);
|
||||
simulateKeyEvent(document, Keys.LEFT);
|
||||
simulateKeyEvent(document, Keys.RIGHT);
|
||||
expect(prev.mock.calls.length).toBe(3);
|
||||
expect(next.mock.calls.length).toBe(3);
|
||||
|
||||
// Arrow keys, only up down should increase
|
||||
key.ws_.isVertical = true;
|
||||
simulateKeyEvent(document, Keys.DOWN);
|
||||
simulateKeyEvent(document, Keys.UP);
|
||||
simulateKeyEvent(document, Keys.LEFT);
|
||||
simulateKeyEvent(document, Keys.RIGHT);
|
||||
expect(prev.mock.calls.length).toBe(4);
|
||||
expect(next.mock.calls.length).toBe(4);
|
||||
|
||||
// F, only trigger on when alone
|
||||
simulateKeyEvent(document, Keys.F);
|
||||
simulateKeyEvent(document, Keys.F, {ctrlKey: true});
|
||||
simulateKeyEvent(document, Keys.F, {metaKey: true});
|
||||
expect(fullscreen.mock.calls.length).toBe(1);
|
||||
});
|
65
test/plugins/navigation.test.js
Normal file
65
test/plugins/navigation.test.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
import Navigation from '../../src/js/plugins/navigation';
|
||||
|
||||
beforeAll(() => {
|
||||
document.body.innerHTML = `<div id="webslides"></div>`;
|
||||
});
|
||||
|
||||
test('Navigation plugin', () => {
|
||||
const ws = document.getElementById('webslides');
|
||||
|
||||
const zoom = jest.fn();
|
||||
const next = jest.fn();
|
||||
const prev = jest.fn();
|
||||
const webslides = {
|
||||
el: ws,
|
||||
goNext: next,
|
||||
goPrev: prev,
|
||||
toggleZoom: zoom,
|
||||
options: {showIndex: true}
|
||||
};
|
||||
|
||||
const fakeArrow = Navigation.createArrow('arrow', 'Test');
|
||||
expect(fakeArrow.tagName).toBe('A');
|
||||
expect(fakeArrow.title).toBe('Arrow Keys');
|
||||
expect(fakeArrow.id).toBe('arrow');
|
||||
expect(fakeArrow.textContent).toBe('Test');
|
||||
|
||||
const fakeCounter = Navigation.createCounter('counter', webslides);
|
||||
expect(fakeCounter.tagName).toBe('SPAN');
|
||||
expect(fakeCounter.childNodes.length).toBe(1);
|
||||
expect(fakeCounter.childNodes[0].tagName).toBe('A');
|
||||
expect(fakeCounter.childNodes[0].href).toBe('http://localhost/#');
|
||||
expect(fakeCounter.childNodes[0].title).toBe('View all slides');
|
||||
|
||||
new Navigation(webslides);
|
||||
|
||||
const navElem = ws.querySelector('#navigation');
|
||||
const counter = navElem.querySelector('#counter');
|
||||
const nextElem = navElem.querySelector('#next');
|
||||
const prevElem = navElem.querySelector('#previous');
|
||||
expect(navElem).not.toBe(null);
|
||||
expect(counter).not.toBe(null);
|
||||
expect(nextElem).not.toBe(null);
|
||||
expect(prevElem).not.toBe(null);
|
||||
|
||||
DOM.fireEvent(ws, 'ws:slide-change', {
|
||||
slides: 3,
|
||||
currentSlide0: 1,
|
||||
currentSlide: 2
|
||||
});
|
||||
expect(counter.textContent).toBe('2 / 3');
|
||||
|
||||
expect(next.mock.calls.length).toBe(0);
|
||||
expect(prev.mock.calls.length).toBe(0);
|
||||
expect(zoom.mock.calls.length).toBe(0);
|
||||
|
||||
DOM.fireEvent(nextElem, 'click');
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
|
||||
DOM.fireEvent(prevElem, 'click');
|
||||
expect(prev.mock.calls.length).toBe(1);
|
||||
|
||||
DOM.fireEvent(counter, 'click');
|
||||
expect(zoom.mock.calls.length).toBe(1);
|
||||
});
|
67
test/plugins/scroll.test.js
Normal file
67
test/plugins/scroll.test.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import Scroll from '../../src/js/plugins/scroll';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
// Copy of DOM.fireEvent, but using wheel deltas
|
||||
const fireEvent = (target, eventType, deltaX, deltaY) => {
|
||||
const event = new CustomEvent(eventType);
|
||||
event.deltaX = deltaX;
|
||||
event.deltaY = deltaY;
|
||||
event.deltaMode = 0;
|
||||
|
||||
target.dispatchEvent(event);
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
const brs = '<br />'.repeat(20);
|
||||
document.body.innerHTML = `<div id="webslides">${brs}</div>`;
|
||||
});
|
||||
|
||||
test('Scroll utility', () => {
|
||||
// Forces mobile detection
|
||||
window.navigator = {
|
||||
userAgent: 'Android'
|
||||
};
|
||||
const ws = document.getElementById('webslides');
|
||||
const next = jest.fn();
|
||||
const prev = jest.fn();
|
||||
|
||||
let disabled = true;
|
||||
const webslides = {
|
||||
el: ws,
|
||||
isDisabled: () => disabled,
|
||||
isMoving: false,
|
||||
isVertical: false,
|
||||
goNext: next,
|
||||
goPrev: prev,
|
||||
options: {
|
||||
navigateOnScroll: true,
|
||||
scrollWait: 200,
|
||||
minWheelDelta: 50
|
||||
}
|
||||
};
|
||||
|
||||
new Scroll(webslides);
|
||||
fireEvent(ws, 'wheel', 300, 200);
|
||||
|
||||
expect(next).not.toBeCalled();
|
||||
expect(prev).not.toBeCalled();
|
||||
|
||||
// Wait until next execution
|
||||
jest.runTimersToTime(201);
|
||||
expect(next.mock.calls.length).toBe(0);
|
||||
expect(prev.mock.calls.length).toBe(0);
|
||||
|
||||
disabled = false;
|
||||
fireEvent(ws, 'wheel', 300, 200);
|
||||
|
||||
jest.runTimersToTime(201);
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
expect(prev.mock.calls.length).toBe(0);
|
||||
|
||||
fireEvent(ws, 'wheel', -200, -300);
|
||||
|
||||
jest.runTimersToTime(201);
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
expect(prev.mock.calls.length).toBe(1);
|
||||
});
|
80
test/plugins/touch.test.js
Normal file
80
test/plugins/touch.test.js
Normal file
@@ -0,0 +1,80 @@
|
||||
import Touch from '../../src/js/plugins/touch';
|
||||
|
||||
// Copy of DOM.fireEvent, but using touch offets
|
||||
const getEvent = (eventType, offsetX, offsetY, touches) => {
|
||||
const event = new CustomEvent(eventType);
|
||||
|
||||
event.offsetX = offsetX;
|
||||
event.offsetY = offsetY;
|
||||
event.touches = touches;
|
||||
|
||||
return event;
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
const brs = '<br />'.repeat(20);
|
||||
document.body.innerHTML = `<div id="webslides">${brs}</div>`;
|
||||
});
|
||||
|
||||
test('Touch utility', () => {
|
||||
// Overrides userAgent to force mobile detection
|
||||
Object.getOwnPropertyDescriptor(window.navigator.__proto__, 'userAgent');
|
||||
Object.defineProperty(window.navigator, 'userAgent', {get: () => 'Android'});
|
||||
|
||||
const ws = document.getElementById('webslides');
|
||||
const next = jest.fn();
|
||||
const prev = jest.fn();
|
||||
const zoom = jest.fn();
|
||||
|
||||
let disabled = true;
|
||||
const webslides = {
|
||||
el: ws,
|
||||
isDisabled: () => disabled,
|
||||
isMoving: false,
|
||||
isVertical: false,
|
||||
goNext: next,
|
||||
goPrev: prev,
|
||||
toggleZoom: zoom,
|
||||
options: {
|
||||
slideOffset: 100
|
||||
}
|
||||
};
|
||||
|
||||
const touch = new Touch(webslides);
|
||||
touch.onStart_(getEvent('touchstart', 200, 200, [1]));
|
||||
touch.onMove_(getEvent('touchstart', 200, 400, [1]));
|
||||
touch.onStop_(getEvent('touchstart', 200, 200, [1]));
|
||||
|
||||
expect(next).not.toBeCalled();
|
||||
expect(prev).not.toBeCalled();
|
||||
expect(zoom).not.toBeCalled();
|
||||
|
||||
disabled = false;
|
||||
|
||||
touch.onStart_(getEvent('touchstart', 800, 200, [1]));
|
||||
touch.onMove_(getEvent('touchstart', 400, 400, [1]));
|
||||
touch.onStop_(getEvent('touchstart', 400, 200, [1]));
|
||||
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
expect(prev.mock.calls.length).toBe(0);
|
||||
expect(zoom.mock.calls.length).toBe(0);
|
||||
|
||||
touch.onStart_(getEvent('touchstart', 200, 200, [1]));
|
||||
touch.onMove_(getEvent('touchstart', 400, 200, [1]));
|
||||
touch.onStop_(getEvent('touchstart', 400, 200, [1]));
|
||||
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
expect(prev.mock.calls.length).toBe(1);
|
||||
expect(zoom.mock.calls.length).toBe(0);
|
||||
|
||||
touch.onStart_(getEvent('touchstart', 200, 200,
|
||||
[{clientX: 100, clientY: 100}, {clientX: 400, clientY: 400}]));
|
||||
touch.onMove_(getEvent('touchstart', 400, 200,
|
||||
[{clientX: 200, clientY: 200}, {clientX: 300, clientY: 300}]));
|
||||
touch.onStop_(getEvent('touchstart', 400, 200,
|
||||
[{clientX: 200, clientY: 200}, {clientX: 300, clientY: 300}]));
|
||||
|
||||
expect(next.mock.calls.length).toBe(1);
|
||||
expect(prev.mock.calls.length).toBe(1);
|
||||
expect(zoom.mock.calls.length).toBe(1);
|
||||
});
|
40
test/plugins/video.test.js
Normal file
40
test/plugins/video.test.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import Video from '../../src/js/plugins/video';
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
|
||||
beforeAll(() => {
|
||||
const slides = '12345'.replace(/(\d)/g,
|
||||
'<div id="section-$1" class="slide"><video autoplay="true" /></div>');
|
||||
document.body.innerHTML = `<div id="webslides">${slides}</div>`;
|
||||
});
|
||||
|
||||
test('Video utility', () => {
|
||||
const ws = document.getElementById('webslides');
|
||||
const slides = ws.querySelectorAll('.slide');
|
||||
const videos = ws.querySelectorAll('video');
|
||||
const play = jest.fn();
|
||||
const pause = jest.fn();
|
||||
videos.forEach(video => {
|
||||
video.play = play;
|
||||
video.pause = pause;
|
||||
});
|
||||
|
||||
const webslides = {
|
||||
el: ws,
|
||||
slides: []
|
||||
};
|
||||
slides.forEach(slide => webslides.slides.push({el: slide}));
|
||||
|
||||
expect(ws.querySelectorAll('video[autoplay]').length).toBe(5);
|
||||
|
||||
new Video(webslides);
|
||||
|
||||
expect(ws.querySelectorAll('video[autoplay]').length).toBe(0);
|
||||
expect(pause.mock.calls.length).toBe(5);
|
||||
|
||||
webslides.slides.forEach(slide => {
|
||||
DOM.fireEvent(slide.el, 'slide:enable', {slide: slide});
|
||||
DOM.fireEvent(slide.el, 'slide:disable', {slide: slide});
|
||||
});
|
||||
|
||||
expect(pause.mock.calls.length).toBe(10);
|
||||
});
|
89
test/plugins/youtube.test.js
Normal file
89
test/plugins/youtube.test.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import YouTube from '../../src/js/plugins/youtube';
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
|
||||
beforeAll(() => {
|
||||
const video = '<div id="section-1" class="slide"><div class="embed">' +
|
||||
'<div data-youtube="video" ' +
|
||||
' data-youtube-id="CQY3KUR3VzM" ' +
|
||||
' data-autoplay data-loop></div></div></div>';
|
||||
document.body.innerHTML =
|
||||
`<script></script><div id="webslides">${video}</div>`;
|
||||
});
|
||||
|
||||
test('YouTube utility', () => {
|
||||
const ws = document.getElementById('webslides');
|
||||
const slides = ws.querySelectorAll('.slide');
|
||||
const play = jest.fn();
|
||||
const pause = jest.fn();
|
||||
const destroy = jest.fn();
|
||||
const create = jest.fn();
|
||||
|
||||
const webslides = {
|
||||
el: ws,
|
||||
slides: []
|
||||
};
|
||||
slides.forEach(slide => webslides.slides.push({el: slide}));
|
||||
|
||||
window.YT = {
|
||||
Player: function(a, b) {
|
||||
return {
|
||||
getIframe: () => {
|
||||
const div = DOM.createNode('div');
|
||||
div.innerHTML =
|
||||
`<iframe id="widget8"
|
||||
src="https://www.youtube.com/embed/_m67JbGjWnc"
|
||||
data-youtube-id="_m67JbGjWnc"
|
||||
frameborder="0" height="360" width="640"></iframe>`;
|
||||
webslides.slides[0].el.appendChild(div);
|
||||
return div.querySelector('iframe');
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
new YouTube(webslides);
|
||||
|
||||
expect(typeof window.onYouTubeIframeAPIReady).toBe('function');
|
||||
const el = webslides.el.querySelector('[data-youtube]');
|
||||
|
||||
el.dataset.autoplay = true;
|
||||
el.dataset.youtubeId = 'CQY3KUR3VzM';
|
||||
|
||||
window.onYouTubeIframeAPIReady();
|
||||
|
||||
const slide = {
|
||||
slide: {
|
||||
player: {
|
||||
autoplay: true,
|
||||
play: play,
|
||||
pause: pause,
|
||||
destroy: destroy,
|
||||
create: create
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DOM.fireEvent(webslides.slides[0].el, 'dom:enter', slide);
|
||||
expect(play.mock.calls.length).toBe(0);
|
||||
expect(pause.mock.calls.length).toBe(0);
|
||||
expect(destroy.mock.calls.length).toBe(0);
|
||||
expect(create.mock.calls.length).toBe(1);
|
||||
|
||||
DOM.fireEvent(webslides.slides[0].el, 'dom:leave', slide);
|
||||
expect(play.mock.calls.length).toBe(0);
|
||||
expect(pause.mock.calls.length).toBe(0);
|
||||
expect(destroy.mock.calls.length).toBe(1);
|
||||
expect(create.mock.calls.length).toBe(1);
|
||||
|
||||
DOM.fireEvent(webslides.slides[0].el, 'slide:enable', slide);
|
||||
expect(play.mock.calls.length).toBe(1);
|
||||
expect(pause.mock.calls.length).toBe(0);
|
||||
expect(destroy.mock.calls.length).toBe(1);
|
||||
expect(create.mock.calls.length).toBe(1);
|
||||
|
||||
DOM.fireEvent(webslides.slides[0].el, 'slide:disable', slide);
|
||||
expect(play.mock.calls.length).toBe(1);
|
||||
expect(pause.mock.calls.length).toBe(1);
|
||||
expect(destroy.mock.calls.length).toBe(1);
|
||||
expect(create.mock.calls.length).toBe(1);
|
||||
});
|
70
test/plugins/zoom.test.js
Normal file
70
test/plugins/zoom.test.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import Zoom from '../../src/js/plugins/zoom';
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
// Copy of DOM.fireEvent, but using keydown
|
||||
const simulateKeyEvent = (el, code) => {
|
||||
const evt = new KeyboardEvent('keydown', {
|
||||
bubbles: true,
|
||||
cancelableCode: true,
|
||||
which: code,
|
||||
shiftKey: true});
|
||||
el.dispatchEvent(evt);
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
const slides = '12345'.replace(/(\d)/g,
|
||||
'<div id="section-$1" class="slide"><div>Slide $1</div></div>')
|
||||
.replace('section-1" class="', 'section-1" class="current ');
|
||||
document.body.innerHTML = `<div id="webslides">${slides}</div>`;
|
||||
});
|
||||
|
||||
test('Zoom utility', () => {
|
||||
const ws = document.getElementById('webslides');
|
||||
const slides = ws.querySelectorAll('.slide');
|
||||
const goto = jest.fn();
|
||||
const enable = jest.fn();
|
||||
const disable = jest.fn();
|
||||
|
||||
const webslides = {
|
||||
el: ws,
|
||||
slides: [],
|
||||
goToSlide: goto,
|
||||
enable: enable,
|
||||
disable: disable,
|
||||
options: {showIndex: true}
|
||||
};
|
||||
slides.forEach(slide => webslides.slides.push({el: slide}));
|
||||
webslides.currentSlide_ = webslides.slides[0];
|
||||
|
||||
new Zoom(webslides);
|
||||
|
||||
const zws = document.querySelector('#webslides-zoomed');
|
||||
const zoomSlides = zws.querySelectorAll('.slide');
|
||||
|
||||
expect(zws).not.toBe(null);
|
||||
expect(zws.className).toMatch('disable');
|
||||
expect(slides.length).toBe(zoomSlides.length);
|
||||
expect(zws.childNodes[0].className).toBe('wrap');
|
||||
expect(zws.childNodes[0].childNodes[0].className).toBe('grid');
|
||||
|
||||
simulateKeyEvent(document.body, 109);
|
||||
|
||||
expect(zws.className).not.toMatch('disable');
|
||||
|
||||
|
||||
// Wait until next execution
|
||||
jest.runTimersToTime(600);
|
||||
expect(disable.mock.calls.length).toBe(1);
|
||||
expect(enable.mock.calls.length).toBe(0);
|
||||
expect(goto.mock.calls.length).toBe(0);
|
||||
|
||||
DOM.fireEvent(zws.querySelector('.zoom-layer'), 'click');
|
||||
|
||||
// Wait until next execution
|
||||
jest.runTimersToTime(401);
|
||||
expect(disable.mock.calls.length).toBe(1);
|
||||
expect(enable.mock.calls.length).toBe(1);
|
||||
expect(goto.mock.calls.length).toBe(1);
|
||||
});
|
320
test/utils/dom.test.js
Normal file
320
test/utils/dom.test.js
Normal file
@@ -0,0 +1,320 @@
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
import simulant from 'simulant';
|
||||
|
||||
describe('Node creation', () => {
|
||||
test('Creates a node', () => {
|
||||
const node = DOM.createNode('p');
|
||||
|
||||
expect(node).toBeInstanceOf(Element);
|
||||
expect(node.tagName).toBe('P');
|
||||
expect(node.id).toBe('');
|
||||
});
|
||||
|
||||
test('Should be possible to pass an id', () => {
|
||||
const node = DOM.createNode('p', 'myId');
|
||||
|
||||
expect(node.id).toBe('myId');
|
||||
});
|
||||
|
||||
test('Should be possible to pass text', () => {
|
||||
const node = DOM.createNode('p', 'id', 'foo');
|
||||
|
||||
expect(node.textContent).toBe('foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Once', () => {
|
||||
let parent;
|
||||
let inner;
|
||||
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `
|
||||
<div id="parent">
|
||||
<div id="inner"></div>
|
||||
</div>
|
||||
`;
|
||||
parent = document.getElementById('parent');
|
||||
inner = document.getElementById('inner');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
test('Only once called once', () => {
|
||||
const cb = jest.fn();
|
||||
DOM.once(parent, 'click', cb);
|
||||
simulant.fire(parent, 'click');
|
||||
simulant.fire(parent, 'click');
|
||||
simulant.fire(parent, 'click');
|
||||
|
||||
expect(cb).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Callback doesn\'t run on bubbled event', () => {
|
||||
const cb = jest.fn();
|
||||
DOM.once(parent, 'click', cb);
|
||||
simulant.fire(inner, 'click');
|
||||
|
||||
expect(cb).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Transition', () => {
|
||||
test('Returns unprefixed first if available', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
transition: 'foo',
|
||||
OTransition: 'foo',
|
||||
MozTransition: 'foo',
|
||||
WebkitTransition: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getTransitionEvent(fakeEl)).toBe('transitionend');
|
||||
});
|
||||
|
||||
test('Prefixed Opera', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
OTransition: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getTransitionEvent(fakeEl)).toBe('oTransitionEnd');
|
||||
});
|
||||
|
||||
|
||||
test('Prefixed Gecko', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
MozTransition: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getTransitionEvent(fakeEl)).toBe('transitionend');
|
||||
});
|
||||
|
||||
|
||||
test('Prefixed Webkit', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
WebkitTransition: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getTransitionEvent(fakeEl)).toBe('webkitTransitionEnd');
|
||||
});
|
||||
|
||||
test('Retains value', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
WebkitTransition: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getTransitionEvent(fakeEl)).toBe('webkitTransitionEnd');
|
||||
expect(DOM.getTransitionEvent()).toBe('webkitTransitionEnd');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Animation', () => {
|
||||
test('Returns unprefixed first if available', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
animation: 'foo',
|
||||
OAnimation: 'foo',
|
||||
MozAnimation: 'foo',
|
||||
WebkitAnimation: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getAnimationEvent(fakeEl)).toBe('animationend');
|
||||
});
|
||||
|
||||
test('Prefixed Opera', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
OAnimation: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getAnimationEvent(fakeEl)).toBe('oAnimationEnd');
|
||||
});
|
||||
|
||||
test('Prefixed Gecko', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
MozAnimation: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getAnimationEvent(fakeEl)).toBe('animationend');
|
||||
});
|
||||
|
||||
test('Prefixed Webkit', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
WebkitAnimation: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getAnimationEvent(fakeEl)).toBe('webkitAnimationEnd');
|
||||
});
|
||||
|
||||
test('Retains value', () => {
|
||||
const fakeEl = {
|
||||
style: {
|
||||
WebkitAnimation: 'foo'
|
||||
}
|
||||
};
|
||||
|
||||
expect(DOM.getAnimationEvent(fakeEl)).toBe('webkitAnimationEnd');
|
||||
expect(DOM.getAnimationEvent()).toBe('webkitAnimationEnd');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Show/hide', () => {
|
||||
test('Show removes the display property', () => {
|
||||
const el = DOM.createNode('div');
|
||||
el.style.display = 'flex';
|
||||
|
||||
expect(el.style.display).toBe('flex');
|
||||
DOM.show(el);
|
||||
expect(el.style.display).toBe('');
|
||||
});
|
||||
|
||||
test('Hide adds display none', () => {
|
||||
const el = DOM.createNode('div');
|
||||
|
||||
expect(el.style.display).toBe('');
|
||||
DOM.hide(el);
|
||||
expect(el.style.display).toBe('none');
|
||||
});
|
||||
|
||||
test('Is visible', () => {
|
||||
// offsetParent doesn't work nice with JSDom
|
||||
const el = DOM.createNode('div');
|
||||
let offsetParent = document.body;
|
||||
el.style.display = 'block';
|
||||
|
||||
document.body.appendChild(el);
|
||||
Object.defineProperty(el, 'offsetParent', {get: () => offsetParent});
|
||||
expect(DOM.isVisible(el)).toBe(true);
|
||||
|
||||
DOM.hide(el);
|
||||
offsetParent = null;
|
||||
|
||||
expect(DOM.isVisible(el)).toBe(false);
|
||||
document.body.removeChild(el);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Custom Event', () => {
|
||||
test('Event gets fired', () => {
|
||||
const cb = jest.fn();
|
||||
const el = DOM.createNode('div');
|
||||
|
||||
el.addEventListener('foo', cb);
|
||||
DOM.fireEvent(el, 'foo');
|
||||
expect(cb).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Event can pass data', () => {
|
||||
const cb = jest.fn();
|
||||
const el = DOM.createNode('div');
|
||||
|
||||
el.addEventListener('foo', cb);
|
||||
DOM.fireEvent(el, 'foo', {
|
||||
foo: 'bar'
|
||||
});
|
||||
expect(cb.mock.calls[0][0].detail.foo).toBe('bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('To Array', () => {
|
||||
test('Converts to array', () => {
|
||||
document.body.innerHTML = '<p></p><p></p><p></p><p></p><p></p>';
|
||||
const paragraphs = document.querySelectorAll('p');
|
||||
|
||||
expect(paragraphs.length).toBe(5);
|
||||
expect(paragraphs).not.toBeInstanceOf(Array);
|
||||
expect(DOM.toArray(paragraphs)).toBeInstanceOf(Array);
|
||||
expect(DOM.toArray(paragraphs).length).toBe(5);
|
||||
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
});
|
||||
|
||||
describe('Focusable Element', () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `
|
||||
<p id="noContent" tabindex="0"></p>
|
||||
<input id="input" type="text">
|
||||
<select id="select">
|
||||
<option id="option1"></option>
|
||||
<option id="option2"></option>
|
||||
</select>
|
||||
<textarea id="textarea"></textarea>
|
||||
`;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
test('Returns false if not focusable', () => {
|
||||
document.getElementById('noContent').focus();
|
||||
expect(DOM.isFocusableElement()).toBe(false);
|
||||
});
|
||||
|
||||
test('Returns true if focusable', () => {
|
||||
document.getElementById('noContent').focus();
|
||||
expect(DOM.isFocusableElement()).toBe(false);
|
||||
document.getElementById('input').focus();
|
||||
expect(DOM.isFocusableElement()).toBe(true);
|
||||
document.getElementById('noContent').focus();
|
||||
expect(DOM.isFocusableElement()).toBe(false);
|
||||
document.getElementById('select').focus();
|
||||
expect(DOM.isFocusableElement()).toBe(true);
|
||||
document.getElementById('noContent').focus();
|
||||
expect(DOM.isFocusableElement()).toBe(false);
|
||||
document.getElementById('textarea').focus();
|
||||
expect(DOM.isFocusableElement()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Parse size', () => {
|
||||
test('Parses a css string to number', () => {
|
||||
expect(DOM.parseSize('10px')).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('After', () => {
|
||||
afterEach(() => {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = '<div id="content">' +
|
||||
'<div id="1"></div>' +
|
||||
'<div id="2"></div>' +
|
||||
'<div id="3"></div>' +
|
||||
'</div>';
|
||||
});
|
||||
|
||||
test('Inserts node after target', () => {
|
||||
const content = document.getElementById('content');
|
||||
const lastDiv = document.getElementById('3');
|
||||
const secondDiv = document.getElementById('2');
|
||||
|
||||
DOM.after(secondDiv, lastDiv);
|
||||
expect(content.innerHTML)
|
||||
.toBe('<div id="1"></div><div id="3"></div><div id="2"></div>');
|
||||
DOM.after(secondDiv, lastDiv);
|
||||
expect(content.innerHTML)
|
||||
.toBe('<div id="1"></div><div id="3"></div><div id="2"></div>');
|
||||
});
|
||||
});
|
||||
|
||||
|
63
test/utils/hash.test.js
Normal file
63
test/utils/hash.test.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
import Hash from '../../src/js/plugins/hash';
|
||||
|
||||
describe('Hash utility', () => {
|
||||
document.body.innerHTML =
|
||||
`<div id="webslides" data-test="test"><p>Text</p></div>`;
|
||||
|
||||
document.location.hash = '#slide=1';
|
||||
const goto = jest.fn();
|
||||
const ws = document.getElementById('webslides');
|
||||
|
||||
|
||||
const webslides = {
|
||||
options: {
|
||||
changeOnClick: true
|
||||
},
|
||||
goToSlide: goto,
|
||||
el: ws
|
||||
};
|
||||
|
||||
test('Make sure it has not changed the slide', () => {
|
||||
expect(goto).not.toBeCalled();
|
||||
});
|
||||
|
||||
new Hash(webslides);
|
||||
|
||||
test('Move to slide 1', () => {
|
||||
expect(Hash.getSlideNumber()).toBe(0);
|
||||
DOM.fireEvent(ws, 'ws:slide-change', {
|
||||
slides: 3,
|
||||
currentSlide0: 1,
|
||||
currentSlide: 2
|
||||
});
|
||||
expect(Hash.getSlideNumber()).toBe(1);
|
||||
expect(document.location.hash).toBe('#slide=2');
|
||||
|
||||
DOM.fireEvent(window, 'hashchange');
|
||||
expect(goto.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
test('Forces slide change', () => {
|
||||
Hash.setSlideNumber(5);
|
||||
const state = history.state;
|
||||
expect(state.slideI).toBe(4);
|
||||
});
|
||||
|
||||
test('Wrong hash', () => {
|
||||
document.location.hash = 'slide=NaN';
|
||||
DOM.fireEvent(window, 'hashchange');
|
||||
// It shouldn't be call.
|
||||
expect(goto.mock.calls.length).toBe(1);
|
||||
expect(Hash.getSlideNumber()).toBe(null);
|
||||
});
|
||||
|
||||
test('Repeat slide change', () => {
|
||||
Hash.setSlideNumber(5);
|
||||
let state = history.state;
|
||||
expect(state.slideI).toBe(4);
|
||||
Hash.setSlideNumber(5);
|
||||
state = history.state;
|
||||
expect(state.slideI).toBe(4);
|
||||
});
|
||||
});
|
14
test/utils/keys.test.js
Normal file
14
test/utils/keys.test.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import Keys from '../../src/js/utils/keys';
|
||||
|
||||
test('Keys are present', () => {
|
||||
expect(Keys.ENTER).toBe(13);
|
||||
expect(Keys.SPACE).toBe(32);
|
||||
expect(Keys.RE_PAGE).toBe(33);
|
||||
expect(Keys.AV_PAGE).toBe(34);
|
||||
expect(Keys.END).toBe(35);
|
||||
expect(Keys.HOME).toBe(36);
|
||||
expect(Keys.LEFT).toBe(37);
|
||||
expect(Keys.UP).toBe(38);
|
||||
expect(Keys.RIGHT).toBe(39);
|
||||
expect(Keys.DOWN).toBe(40);
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user