├── 1. Intersection Observer
├── index.html
├── lazy-loading.gif
├── main.js
└── style.css
├── 2. navigation style on scroll with Intersection Observer
├── css
│ └── main.css
├── gulpfile.js
├── index.html
├── js
│ └── observers.js
└── scss
│ └── main.scss
├── 3. Fade and scroll items into view while scrolling with Intersection Observer
├── css
│ └── main.css
├── gulpfile.js
├── index.html
├── js
│ └── observers.js
└── scss
│ └── main.scss
├── 4. How to lazy load images with Intersection Obserrver
├── css
│ └── main.css
├── gulpfile.js
├── index.html
├── js
│ ├── lazy-loader.js
│ └── observers.js
├── lazy loading v2.gif
└── scss
│ └── main.scss
├── LICENSE
└── README.md
/1. Intersection Observer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Intersection Observer
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/1. Intersection Observer/lazy-loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AbdallahHemdan/Lazy-Loading/2a2d7f1cf370b525937394dd0ab551ca564fc511/1. Intersection Observer/lazy-loading.gif
--------------------------------------------------------------------------------
/1. Intersection Observer/main.js:
--------------------------------------------------------------------------------
1 | const sections = document.querySelectorAll('section');
2 |
3 | const options = {
4 | root: null, // it is the viewport
5 | threshold: 0, // threshold is a value from 0 to 1 represent what percentage of the target's visibility the observer's callback should be executed
6 | rootMargin: '-400px', // margin around the entries
7 | };
8 | const observer = new IntersectionObserver((entries, observer) => {
9 | entries.forEach(entry => {
10 | if (entry.isIntersecting) {
11 | console.log(entry.target);
12 | entry.target.classList.toggle('reverse');
13 | observer.unobserve(entry.target);
14 | }
15 | });
16 | }, options);
17 |
18 | sections.forEach(section => {
19 | observer.observe(section);
20 | });
21 |
--------------------------------------------------------------------------------
/1. Intersection Observer/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | height: 3500px;
3 | }
4 |
5 | section {
6 | display: flex;
7 | align-items: center;
8 | justify-content: center;
9 | height: 100vh;
10 | color: #fff;
11 | font-size: 24px;
12 | }
13 |
14 | .section1 {
15 | background-color: #f00;
16 | }
17 |
18 | .section2 {
19 | background-color: #0f0;
20 | }
21 |
22 | .section3 {
23 | background-color: #00f;
24 | }
25 |
26 | .section4 {
27 | background-color: #f0f;
28 | }
29 |
30 | .reverse {
31 | background-color: #000;
32 | }
33 |
--------------------------------------------------------------------------------
/2. navigation style on scroll with Intersection Observer/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: "Poppins", sans-serif;
4 | }
5 |
6 | .site-logo {
7 | font-weight: 900;
8 | font-size: 0.8rem;
9 | color: var(--text);
10 | text-decoration: none;
11 | }
12 |
13 | header {
14 | --text: #f4f4f4;
15 | --text-inverse: #333;
16 | --background: transparent;
17 | position: fixed;
18 | top: 0;
19 | left: 0;
20 | right: 0;
21 | z-index: 999;
22 | display: flex;
23 | justify-content: space-between;
24 | align-items: center;
25 | padding: 2em 3em;
26 | transition: background 250ms ease-in;
27 | background: var(--background);
28 | color: var(--text);
29 | }
30 |
31 | .nav__list {
32 | list-style: none;
33 | margin: 0;
34 | padding: 0;
35 | display: flex;
36 | }
37 |
38 | .nav__link {
39 | --spacing: 1em;
40 | text-decoration: none;
41 | color: inherit;
42 | display: inline-block;
43 | padding: calc(var(--spacing) / 2) var(--spacing);
44 | position: relative;
45 | text-transform: uppercase;
46 | letter-spacing: 2px;
47 | font-size: 0.9rem;
48 | }
49 |
50 | .nav__link:after {
51 | content: "";
52 | position: absolute;
53 | bottom: 0;
54 | left: var(--spacing);
55 | right: var(--spacing);
56 | height: 2px;
57 | background: currentColor;
58 | -webkit-transform: scaleX(0);
59 | transform: scaleX(0);
60 | transition: -webkit-transform 150ms ease-in-out;
61 | transition: transform 150ms ease-in-out;
62 | transition: transform 150ms ease-in-out, -webkit-transform 150ms ease-in-out;
63 | }
64 |
65 | .nav__link:hover::after {
66 | -webkit-transform: scaleX(1);
67 | transform: scaleX(1);
68 | }
69 |
70 | .nav__link--btn {
71 | border: 1.5px solid currentColor;
72 | border-radius: 2em;
73 | margin-left: 1em;
74 | transition: background 250ms ease-in-out;
75 | letter-spacing: 1px;
76 | padding: 0.75em 1.5em;
77 | }
78 |
79 | .nav__link--btn:hover {
80 | background: var(--text);
81 | color: var(--text-inverse);
82 | border-color: var(--text);
83 | }
84 |
85 | .nav__link--btn::after {
86 | display: none;
87 | }
88 |
89 | .nav__link--btn--highlight {
90 | background: limegreen;
91 | border-color: limegreen;
92 | color: #333;
93 | }
94 |
95 | .nav__link--btn--highlight:hover {
96 | background: var(--text);
97 | border-color: var(--text);
98 | }
99 |
100 | .nav-scrolled {
101 | --text: #333;
102 | --text-inverse: #f4f4f4;
103 | --background: #f4f4f4;
104 | box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
105 | }
106 |
107 | .home-intro {
108 | padding: 50vh 0;
109 | background: #123 url(//unsplash.it/900);
110 | background-size: cover;
111 | background-blend-mode: multiply;
112 | color: white;
113 | text-align: center;
114 | }
115 |
116 | .home-about {
117 | padding: 4em 0;
118 | max-width: 900px;
119 | margin: 0 auto;
120 | }
121 |
122 | .columns {
123 | display: flex;
124 | }
125 |
126 | .col + .col {
127 | margin-left: 1.5em;
128 | }
129 |
130 | .more-stuff-grid {
131 | background: #f4f4f4;
132 | padding: 4em 0;
133 | display: grid;
134 | grid-gap: 2em;
135 | align-items: center;
136 | grid-template-columns: minmax(1em, 1fr) repeat(2, minmax(200px, 400px)) minmax(1em, 1fr);
137 | }
138 |
139 | .from-left {
140 | grid-column: 2 / 3;
141 | }
142 |
143 | .from-right {
144 | grid-column: 3 / 4;
145 | }
146 |
147 | /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5jc3MiLCJzb3VyY2VzIjpbIm1haW4uc2NzcyJdLCJzb3VyY2VzQ29udGVudCI6WyJib2R5IHtcclxuICBtYXJnaW46IDA7XHJcbiAgZm9udC1mYW1pbHk6IFwiUG9wcGluc1wiLCBzYW5zLXNlcmlmO1xyXG59XHJcblxyXG4uc2l0ZS1sb2dvIHtcclxuICBmb250LXdlaWdodDogOTAwO1xyXG4gIGZvbnQtc2l6ZTogMC44cmVtO1xyXG4gIGNvbG9yOiB2YXIoLS10ZXh0KTtcclxuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XHJcbn1cclxuXHJcbmhlYWRlciB7XHJcbiAgLS10ZXh0OiAjZjRmNGY0O1xyXG4gIC0tdGV4dC1pbnZlcnNlOiAjMzMzO1xyXG4gIC0tYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XHJcblxyXG4gIHBvc2l0aW9uOiBmaXhlZDtcclxuICB0b3A6IDA7XHJcbiAgbGVmdDogMDtcclxuICByaWdodDogMDtcclxuICB6LWluZGV4OiA5OTk7XHJcbiAgZGlzcGxheTogZmxleDtcclxuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XHJcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICBwYWRkaW5nOiAyZW0gM2VtO1xyXG4gIHRyYW5zaXRpb246IGJhY2tncm91bmQgMjUwbXMgZWFzZS1pbjtcclxuICBiYWNrZ3JvdW5kOiB2YXIoLS1iYWNrZ3JvdW5kKTtcclxuICBjb2xvcjogdmFyKC0tdGV4dCk7XHJcbn1cclxuXHJcbi5uYXZfX2xpc3Qge1xyXG4gIGxpc3Qtc3R5bGU6IG5vbmU7XHJcbiAgbWFyZ2luOiAwO1xyXG4gIHBhZGRpbmc6IDA7XHJcbiAgZGlzcGxheTogZmxleDtcclxufVxyXG5cclxuLm5hdl9fbGluayB7XHJcbiAgLS1zcGFjaW5nOiAxZW07XHJcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xyXG4gIGNvbG9yOiBpbmhlcml0O1xyXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcclxuICBwYWRkaW5nOiBjYWxjKHZhcigtLXNwYWNpbmcpIC8gMikgdmFyKC0tc3BhY2luZyk7XHJcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XHJcbiAgbGV0dGVyLXNwYWNpbmc6IDJweDtcclxuICBmb250LXNpemU6IDAuOXJlbTtcclxuXHJcbiAgJjphZnRlciB7XHJcbiAgICBjb250ZW50OiBcIlwiO1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgYm90dG9tOiAwO1xyXG4gICAgbGVmdDogdmFyKC0tc3BhY2luZyk7XHJcbiAgICByaWdodDogdmFyKC0tc3BhY2luZyk7XHJcbiAgICBoZWlnaHQ6IDJweDtcclxuICAgIGJhY2tncm91bmQ6IGN1cnJlbnRDb2xvcjtcclxuICAgIHRyYW5zZm9ybTogc2NhbGVYKDApO1xyXG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDE1MG1zIGVhc2UtaW4tb3V0O1xyXG4gIH1cclxuXHJcbiAgJjpob3Zlcjo6YWZ0ZXIge1xyXG4gICAgdHJhbnNmb3JtOiBzY2FsZVgoMSk7XHJcbiAgfVxyXG5cclxuICAmLS1idG4ge1xyXG4gICAgYm9yZGVyOiAxLjVweCBzb2xpZCBjdXJyZW50Q29sb3I7XHJcbiAgICBib3JkZXItcmFkaXVzOiAyZW07XHJcbiAgICBtYXJnaW4tbGVmdDogMWVtO1xyXG4gICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAyNTBtcyBlYXNlLWluLW91dDtcclxuICAgIGxldHRlci1zcGFjaW5nOiAxcHg7XHJcbiAgICBwYWRkaW5nOiAwLjc1ZW0gMS41ZW07XHJcblxyXG4gICAgJjpob3ZlciB7XHJcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXRleHQpO1xyXG4gICAgICBjb2xvcjogdmFyKC0tdGV4dC1pbnZlcnNlKTtcclxuICAgICAgYm9yZGVyLWNvbG9yOiB2YXIoLS10ZXh0KTtcclxuICAgIH1cclxuXHJcbiAgICAmOjphZnRlciB7XHJcbiAgICAgIGRpc3BsYXk6IG5vbmU7XHJcbiAgICB9XHJcblxyXG4gICAgJi0taGlnaGxpZ2h0IHtcclxuICAgICAgYmFja2dyb3VuZDogbGltZWdyZWVuO1xyXG4gICAgICBib3JkZXItY29sb3I6IGxpbWVncmVlbjtcclxuICAgICAgY29sb3I6ICMzMzM7XHJcblxyXG4gICAgICAmOmhvdmVyIHtcclxuICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS10ZXh0KTtcclxuICAgICAgICBib3JkZXItY29sb3I6IHZhcigtLXRleHQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4ubmF2LXNjcm9sbGVkIHtcclxuICAtLXRleHQ6ICMzMzM7XHJcbiAgLS10ZXh0LWludmVyc2U6ICNmNGY0ZjQ7XHJcbiAgLS1iYWNrZ3JvdW5kOiAjZjRmNGY0O1xyXG5cclxuICBib3gtc2hhZG93OiAwIDNweCAyMHB4IHJnYmEoYmxhY2ssIDAuMik7XHJcbn1cclxuXHJcbi5ob21lLWludHJvIHtcclxuICBwYWRkaW5nOiA1MHZoIDA7XHJcbiAgYmFja2dyb3VuZDogIzEyMyB1cmwoLy91bnNwbGFzaC5pdC85MDApO1xyXG4gIGJhY2tncm91bmQtc2l6ZTogY292ZXI7XHJcbiAgYmFja2dyb3VuZC1ibGVuZC1tb2RlOiBtdWx0aXBseTtcclxuICBjb2xvcjogd2hpdGU7XHJcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG59XHJcblxyXG4uaG9tZS1hYm91dCB7XHJcbiAgcGFkZGluZzogNGVtIDA7XHJcbiAgbWF4LXdpZHRoOiA5MDBweDtcclxuICBtYXJnaW46IDAgYXV0bztcclxufVxyXG5cclxuLmNvbHVtbnMge1xyXG4gIGRpc3BsYXk6IGZsZXg7XHJcbn1cclxuXHJcbi5jb2wgKyAuY29sIHtcclxuICBtYXJnaW4tbGVmdDogMS41ZW07XHJcbn1cclxuXHJcbi5tb3JlLXN0dWZmLWdyaWQge1xyXG4gIGJhY2tncm91bmQ6ICNmNGY0ZjQ7XHJcbiAgcGFkZGluZzogNGVtIDA7XHJcbiAgZGlzcGxheTogZ3JpZDtcclxuICBncmlkLWdhcDogMmVtO1xyXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBtaW5tYXgoMWVtLCAxZnIpIHJlcGVhdCgyLCBtaW5tYXgoMjAwcHgsIDQwMHB4KSkgbWlubWF4KFxyXG4gICAgICAxZW0sXHJcbiAgICAgIDFmclxyXG4gICAgKTtcclxufVxyXG5cclxuLmZyb20tbGVmdCB7XHJcbiAgZ3JpZC1jb2x1bW46IDIgLyAzO1xyXG59XHJcblxyXG4uZnJvbS1yaWdodCB7XHJcbiAgZ3JpZC1jb2x1bW46IDMgLyA0O1xyXG59XHJcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUFBLElBQUksQ0FBQztFQUNILE1BQU0sRUFBRSxDQUFDO0VBQ1QsV0FBVyxFQUFFLHFCQUFxQjtDQUNuQzs7QUFFRCxBQUFBLFVBQVUsQ0FBQztFQUNULFdBQVcsRUFBRSxHQUFHO0VBQ2hCLFNBQVMsRUFBRSxNQUFNO0VBQ2pCLEtBQUssRUFBRSxXQUFXO0VBQ2xCLGVBQWUsRUFBRSxJQUFJO0NBQ3RCOztBQUVELEFBQUEsTUFBTSxDQUFDO0VBQ0wsTUFBTSxDQUFBLFFBQUM7RUFDUCxjQUFjLENBQUEsS0FBQztFQUNmLFlBQVksQ0FBQSxZQUFDO0VBRWIsUUFBUSxFQUFFLEtBQUs7RUFDZixHQUFHLEVBQUUsQ0FBQztFQUNOLElBQUksRUFBRSxDQUFDO0VBQ1AsS0FBSyxFQUFFLENBQUM7RUFDUixPQUFPLEVBQUUsR0FBRztFQUNaLE9BQU8sRUFBRSxJQUFJO0VBQ2IsZUFBZSxFQUFFLGFBQWE7RUFDOUIsV0FBVyxFQUFFLE1BQU07RUFDbkIsT0FBTyxFQUFFLE9BQU87RUFDaEIsVUFBVSxFQUFFLHdCQUF3QjtFQUNwQyxVQUFVLEVBQUUsaUJBQWlCO0VBQzdCLEtBQUssRUFBRSxXQUFXO0NBQ25COztBQUVELEFBQUEsVUFBVSxDQUFDO0VBQ1QsVUFBVSxFQUFFLElBQUk7RUFDaEIsTUFBTSxFQUFFLENBQUM7RUFDVCxPQUFPLEVBQUUsQ0FBQztFQUNWLE9BQU8sRUFBRSxJ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 */
148 |
--------------------------------------------------------------------------------
/2. navigation style on scroll with Intersection Observer/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require("gulp");
2 | const sass = require("gulp-sass");
3 | const sourcemaps = require("gulp-sourcemaps");
4 | const autoprefixer = require("gulp-autoprefixer");
5 | const browserSync = require("browser-sync").create();
6 |
7 | const sassOptions = {
8 | outputStyle: "expanded"
9 | };
10 |
11 | // compile scss into css
12 |
13 | function style() {
14 | return gulp
15 | .src("./scss/**/*.scss")
16 | .pipe(sourcemaps.init())
17 | .pipe(sass(sassOptions).on("error", sass.logError))
18 | .pipe(sourcemaps.write())
19 | .pipe(autoprefixer())
20 | .pipe(gulp.dest("./css"))
21 | .pipe(browserSync.stream());
22 | }
23 |
24 | function watch() {
25 | browserSync.init({
26 | server: ".",
27 | browser: "firefox"
28 | });
29 | gulp.watch("./scss/**/*.scss", style);
30 | gulp.watch("./*.html").on("change", browserSync.reload);
31 | gulp.watch("./js/**/*.js").on("change", browserSync.reload);
32 | }
33 |
34 | exports.style = style;
35 | exports.watch = watch;
36 |
--------------------------------------------------------------------------------
/2. navigation style on scroll with Intersection Observer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
12 |
13 |
14 |
15 |
16 |
17 | IntObs
18 |
19 |
32 |
33 |
34 |
35 |
36 | Login
37 |
38 |
39 | Join
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Intersection Observer is pretty useful
48 |
49 |
50 |
51 |
About us
52 |
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
53 |
54 |
55 |
Lorem, ipsum.
56 |
57 | Lorem ipsum dolor sit, amet consectetur adipisicing elit. Vitae maiores fuga eos
58 | provident voluptas perferendis.
59 |
60 |
61 |
62 |
A, illo!
63 |
64 | Lorem, ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus minima quo
65 | beatae eius blanditiis officiis.
66 |
67 |
68 |
69 |
Repudiandae, error?
70 |
71 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laborum quasi quis doloribus
72 | quia illum laudantium.
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
83 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
84 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
85 | cupiditate debitis facilis quibusdam magni. Eveniet.
86 |
87 |
88 |
89 |
90 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
91 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
92 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
93 | cupiditate debitis facilis quibusdam magni. Eveniet.
94 |
95 |
96 |
97 |
98 |
99 |
100 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
101 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
102 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
103 | cupiditate debitis facilis quibusdam magni. Eveniet.
104 |
105 |
106 |
107 |
108 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
109 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
110 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
111 | cupiditate debitis facilis quibusdam magni. Eveniet.
112 |
113 |
114 |
115 |
116 |
117 |
118 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
119 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
120 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
121 | cupiditate debitis facilis quibusdam magni. Eveniet.
122 |
123 |
124 |
125 |
126 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
127 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
128 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
129 | cupiditate debitis facilis quibusdam magni. Eveniet.
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/2. navigation style on scroll with Intersection Observer/js/observers.js:
--------------------------------------------------------------------------------
1 | const header = document.querySelector('header');
2 | const navBreakpoint = document.querySelector('.home-intro');
3 |
4 | const options = {
5 | root: null,
6 | threshold: 0,
7 | rootMargin: '-100px',
8 | };
9 |
10 | const observer = new IntersectionObserver((entries, observer) => {
11 | entries.forEach(entry => {
12 | if (!entry.isIntersecting) {
13 | header.classList.add('nav-scrolled');
14 | } else {
15 | header.classList.remove('nav-scrolled');
16 | }
17 | });
18 | }, options);
19 |
20 | observer.observe(navBreakpoint);
21 |
--------------------------------------------------------------------------------
/2. navigation style on scroll with Intersection Observer/scss/main.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: "Poppins", sans-serif;
4 | }
5 |
6 | .site-logo {
7 | font-weight: 900;
8 | font-size: 0.8rem;
9 | color: var(--text);
10 | text-decoration: none;
11 | }
12 |
13 | header {
14 | --text: #f4f4f4;
15 | --text-inverse: #333;
16 | --background: transparent;
17 |
18 | position: fixed;
19 | top: 0;
20 | left: 0;
21 | right: 0;
22 | z-index: 999;
23 | display: flex;
24 | justify-content: space-between;
25 | align-items: center;
26 | padding: 2em 3em;
27 | transition: background 250ms ease-in;
28 | background: var(--background);
29 | color: var(--text);
30 | }
31 |
32 | .nav__list {
33 | list-style: none;
34 | margin: 0;
35 | padding: 0;
36 | display: flex;
37 | }
38 |
39 | .nav__link {
40 | --spacing: 1em;
41 | text-decoration: none;
42 | color: inherit;
43 | display: inline-block;
44 | padding: calc(var(--spacing) / 2) var(--spacing);
45 | position: relative;
46 | text-transform: uppercase;
47 | letter-spacing: 2px;
48 | font-size: 0.9rem;
49 |
50 | &:after {
51 | content: "";
52 | position: absolute;
53 | bottom: 0;
54 | left: var(--spacing);
55 | right: var(--spacing);
56 | height: 2px;
57 | background: currentColor;
58 | transform: scaleX(0);
59 | transition: transform 150ms ease-in-out;
60 | }
61 |
62 | &:hover::after {
63 | transform: scaleX(1);
64 | }
65 |
66 | &--btn {
67 | border: 1.5px solid currentColor;
68 | border-radius: 2em;
69 | margin-left: 1em;
70 | transition: background 250ms ease-in-out;
71 | letter-spacing: 1px;
72 | padding: 0.75em 1.5em;
73 |
74 | &:hover {
75 | background: var(--text);
76 | color: var(--text-inverse);
77 | border-color: var(--text);
78 | }
79 |
80 | &::after {
81 | display: none;
82 | }
83 |
84 | &--highlight {
85 | background: limegreen;
86 | border-color: limegreen;
87 | color: #333;
88 |
89 | &:hover {
90 | background: var(--text);
91 | border-color: var(--text);
92 | }
93 | }
94 | }
95 | }
96 |
97 | .nav-scrolled {
98 | --text: #333;
99 | --text-inverse: #f4f4f4;
100 | --background: #f4f4f4;
101 |
102 | box-shadow: 0 3px 20px rgba(black, 0.2);
103 | }
104 |
105 | .home-intro {
106 | padding: 50vh 0;
107 | background: #123 url(//unsplash.it/900);
108 | background-size: cover;
109 | background-blend-mode: multiply;
110 | color: white;
111 | text-align: center;
112 | }
113 |
114 | .home-about {
115 | padding: 4em 0;
116 | max-width: 900px;
117 | margin: 0 auto;
118 | }
119 |
120 | .columns {
121 | display: flex;
122 | }
123 |
124 | .col + .col {
125 | margin-left: 1.5em;
126 | }
127 |
128 | .more-stuff-grid {
129 | background: #f4f4f4;
130 | padding: 4em 0;
131 | display: grid;
132 | grid-gap: 2em;
133 | align-items: center;
134 | grid-template-columns: minmax(1em, 1fr) repeat(2, minmax(200px, 400px)) minmax(
135 | 1em,
136 | 1fr
137 | );
138 | }
139 |
140 | .from-left {
141 | grid-column: 2 / 3;
142 | }
143 |
144 | .from-right {
145 | grid-column: 3 / 4;
146 | }
147 |
--------------------------------------------------------------------------------
/3. Fade and scroll items into view while scrolling with Intersection Observer/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: 'Poppins', sans-serif;
4 | }
5 |
6 | .site-logo {
7 | font-weight: 900;
8 | font-size: 0.8rem;
9 | color: var(--text);
10 | text-decoration: none;
11 | }
12 |
13 | header {
14 | --text: #f4f4f4;
15 | --text-inverse: #333;
16 | --background: transparent;
17 | position: fixed;
18 | top: 0;
19 | left: 0;
20 | right: 0;
21 | z-index: 999;
22 | display: flex;
23 | justify-content: space-between;
24 | align-items: center;
25 | padding: 2em 3em;
26 | transition: background 250ms ease-in;
27 | background: var(--background);
28 | color: var(--text);
29 | }
30 |
31 | .nav__list {
32 | list-style: none;
33 | margin: 0;
34 | padding: 0;
35 | display: flex;
36 | }
37 |
38 | .nav__link {
39 | --spacing: 1em;
40 | text-decoration: none;
41 | color: inherit;
42 | display: inline-block;
43 | padding: calc(var(--spacing) / 2) var(--spacing);
44 | position: relative;
45 | text-transform: uppercase;
46 | letter-spacing: 2px;
47 | font-size: 0.9rem;
48 | }
49 |
50 | .nav__link:after {
51 | content: '';
52 | position: absolute;
53 | bottom: 0;
54 | left: var(--spacing);
55 | right: var(--spacing);
56 | height: 2px;
57 | background: currentColor;
58 | -webkit-transform: scaleX(0);
59 | transform: scaleX(0);
60 | transition: -webkit-transform 150ms ease-in-out;
61 | transition: transform 150ms ease-in-out;
62 | transition: transform 150ms ease-in-out, -webkit-transform 150ms ease-in-out;
63 | }
64 |
65 | .nav__link:hover::after {
66 | -webkit-transform: scaleX(1);
67 | transform: scaleX(1);
68 | }
69 |
70 | .nav__link--btn {
71 | border: 1.5px solid currentColor;
72 | border-radius: 2em;
73 | margin-left: 1em;
74 | transition: background 250ms ease-in-out;
75 | letter-spacing: 1px;
76 | padding: 0.75em 1.5em;
77 | }
78 |
79 | .nav__link--btn:hover {
80 | background: var(--text);
81 | color: var(--text-inverse);
82 | border-color: var(--text);
83 | }
84 |
85 | .nav__link--btn::after {
86 | display: none;
87 | }
88 |
89 | .nav__link--btn--highlight {
90 | background: limegreen;
91 | border-color: limegreen;
92 | color: #333;
93 | }
94 |
95 | .nav__link--btn--highlight:hover {
96 | background: var(--text);
97 | border-color: var(--text);
98 | }
99 |
100 | .nav-scrolled {
101 | --text: #333;
102 | --text-inverse: #f4f4f4;
103 | --background: #f4f4f4;
104 | box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
105 | }
106 |
107 | .home-intro {
108 | padding: 50vh 0;
109 | background: #123 url(//unsplash.it/900);
110 | background-size: cover;
111 | background-blend-mode: multiply;
112 | color: white;
113 | text-align: center;
114 | }
115 |
116 | .home-about {
117 | padding: 4em 0;
118 | max-width: 900px;
119 | margin: 0 auto;
120 | }
121 |
122 | .columns {
123 | display: flex;
124 | }
125 |
126 | .col + .col {
127 | margin-left: 1.5em;
128 | }
129 |
130 | .fade-in {
131 | opacity: 0;
132 | transition: opacity 1s ease-in;
133 | }
134 |
135 | .fade-in.appear {
136 | opacity: 1;
137 | }
138 |
139 | .more-stuff-grid {
140 | background: #f4f4f4;
141 | padding: 4em 0;
142 | display: grid;
143 | grid-gap: 2em;
144 | align-items: center;
145 | grid-template-columns: minmax(1em, 1fr) repeat(2, minmax(200px, 400px)) minmax(1em, 1fr);
146 | }
147 |
148 | .from-left {
149 | grid-column: 2 / 3;
150 | transform: translateX(-50%);
151 | transition: transform 500ms ease-in;
152 | }
153 |
154 | .from-right {
155 | grid-column: 3 / 4;
156 | transform: translateX(50%);
157 | transition: transform 500ms ease-in;
158 | }
159 |
160 | .from-left.appear,
161 | .from-right.appear {
162 | transform: translateX(0);
163 | }
164 |
165 | /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5jc3MiLCJzb3VyY2VzIjpbIm1haW4uc2NzcyJdLCJzb3VyY2VzQ29udGVudCI6WyJib2R5IHtcclxuICBtYXJnaW46IDA7XHJcbiAgZm9udC1mYW1pbHk6IFwiUG9wcGluc1wiLCBzYW5zLXNlcmlmO1xyXG59XHJcblxyXG4uc2l0ZS1sb2dvIHtcclxuICBmb250LXdlaWdodDogOTAwO1xyXG4gIGZvbnQtc2l6ZTogMC44cmVtO1xyXG4gIGNvbG9yOiB2YXIoLS10ZXh0KTtcclxuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XHJcbn1cclxuXHJcbmhlYWRlciB7XHJcbiAgLS10ZXh0OiAjZjRmNGY0O1xyXG4gIC0tdGV4dC1pbnZlcnNlOiAjMzMzO1xyXG4gIC0tYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XHJcblxyXG4gIHBvc2l0aW9uOiBmaXhlZDtcclxuICB0b3A6IDA7XHJcbiAgbGVmdDogMDtcclxuICByaWdodDogMDtcclxuICB6LWluZGV4OiA5OTk7XHJcbiAgZGlzcGxheTogZmxleDtcclxuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XHJcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICBwYWRkaW5nOiAyZW0gM2VtO1xyXG4gIHRyYW5zaXRpb246IGJhY2tncm91bmQgMjUwbXMgZWFzZS1pbjtcclxuICBiYWNrZ3JvdW5kOiB2YXIoLS1iYWNrZ3JvdW5kKTtcclxuICBjb2xvcjogdmFyKC0tdGV4dCk7XHJcbn1cclxuXHJcbi5uYXZfX2xpc3Qge1xyXG4gIGxpc3Qtc3R5bGU6IG5vbmU7XHJcbiAgbWFyZ2luOiAwO1xyXG4gIHBhZGRpbmc6IDA7XHJcbiAgZGlzcGxheTogZmxleDtcclxufVxyXG5cclxuLm5hdl9fbGluayB7XHJcbiAgLS1zcGFjaW5nOiAxZW07XHJcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xyXG4gIGNvbG9yOiBpbmhlcml0O1xyXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcclxuICBwYWRkaW5nOiBjYWxjKHZhcigtLXNwYWNpbmcpIC8gMikgdmFyKC0tc3BhY2luZyk7XHJcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XHJcbiAgbGV0dGVyLXNwYWNpbmc6IDJweDtcclxuICBmb250LXNpemU6IDAuOXJlbTtcclxuXHJcbiAgJjphZnRlciB7XHJcbiAgICBjb250ZW50OiBcIlwiO1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgYm90dG9tOiAwO1xyXG4gICAgbGVmdDogdmFyKC0tc3BhY2luZyk7XHJcbiAgICByaWdodDogdmFyKC0tc3BhY2luZyk7XHJcbiAgICBoZWlnaHQ6IDJweDtcclxuICAgIGJhY2tncm91bmQ6IGN1cnJlbnRDb2xvcjtcclxuICAgIHRyYW5zZm9ybTogc2NhbGVYKDApO1xyXG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDE1MG1zIGVhc2UtaW4tb3V0O1xyXG4gIH1cclxuXHJcbiAgJjpob3Zlcjo6YWZ0ZXIge1xyXG4gICAgdHJhbnNmb3JtOiBzY2FsZVgoMSk7XHJcbiAgfVxyXG5cclxuICAmLS1idG4ge1xyXG4gICAgYm9yZGVyOiAxLjVweCBzb2xpZCBjdXJyZW50Q29sb3I7XHJcbiAgICBib3JkZXItcmFkaXVzOiAyZW07XHJcbiAgICBtYXJnaW4tbGVmdDogMWVtO1xyXG4gICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAyNTBtcyBlYXNlLWluLW91dDtcclxuICAgIGxldHRlci1zcGFjaW5nOiAxcHg7XHJcbiAgICBwYWRkaW5nOiAwLjc1ZW0gMS41ZW07XHJcblxyXG4gICAgJjpob3ZlciB7XHJcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXRleHQpO1xyXG4gICAgICBjb2xvcjogdmFyKC0tdGV4dC1pbnZlcnNlKTtcclxuICAgICAgYm9yZGVyLWNvbG9yOiB2YXIoLS10ZXh0KTtcclxuICAgIH1cclxuXHJcbiAgICAmOjphZnRlciB7XHJcbiAgICAgIGRpc3BsYXk6IG5vbmU7XHJcbiAgICB9XHJcblxyXG4gICAgJi0taGlnaGxpZ2h0IHtcclxuICAgICAgYmFja2dyb3VuZDogbGltZWdyZWVuO1xyXG4gICAgICBib3JkZXItY29sb3I6IGxpbWVncmVlbjtcclxuICAgICAgY29sb3I6ICMzMzM7XHJcblxyXG4gICAgICAmOmhvdmVyIHtcclxuICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS10ZXh0KTtcclxuICAgICAgICBib3JkZXItY29sb3I6IHZhcigtLXRleHQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4ubmF2LXNjcm9sbGVkIHtcclxuICAtLXRleHQ6ICMzMzM7XHJcbiAgLS10ZXh0LWludmVyc2U6ICNmNGY0ZjQ7XHJcbiAgLS1iYWNrZ3JvdW5kOiAjZjRmNGY0O1xyXG5cclxuICBib3gtc2hhZG93OiAwIDNweCAyMHB4IHJnYmEoYmxhY2ssIDAuMik7XHJcbn1cclxuXHJcbi5ob21lLWludHJvIHtcclxuICBwYWRkaW5nOiA1MHZoIDA7XHJcbiAgYmFja2dyb3VuZDogIzEyMyB1cmwoLy91bnNwbGFzaC5pdC85MDApO1xyXG4gIGJhY2tncm91bmQtc2l6ZTogY292ZXI7XHJcbiAgYmFja2dyb3VuZC1ibGVuZC1tb2RlOiBtdWx0aXBseTtcclxuICBjb2xvcjogd2hpdGU7XHJcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG59XHJcblxyXG4uaG9tZS1hYm91dCB7XHJcbiAgcGFkZGluZzogNGVtIDA7XHJcbiAgbWF4LXdpZHRoOiA5MDBweDtcclxuICBtYXJnaW46IDAgYXV0bztcclxufVxyXG5cclxuLmNvbHVtbnMge1xyXG4gIGRpc3BsYXk6IGZsZXg7XHJcbn1cclxuXHJcbi5jb2wgKyAuY29sIHtcclxuICBtYXJnaW4tbGVmdDogMS41ZW07XHJcbn1cclxuXHJcbi5tb3JlLXN0dWZmLWdyaWQge1xyXG4gIGJhY2tncm91bmQ6ICNmNGY0ZjQ7XHJcbiAgcGFkZGluZzogNGVtIDA7XHJcbiAgZGlzcGxheTogZ3JpZDtcclxuICBncmlkLWdhcDogMmVtO1xyXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBtaW5tYXgoMWVtLCAxZnIpIHJlcGVhdCgyLCBtaW5tYXgoMjAwcHgsIDQwMHB4KSkgbWlubWF4KFxyXG4gICAgICAxZW0sXHJcbiAgICAgIDFmclxyXG4gICAgKTtcclxufVxyXG5cclxuLmZyb20tbGVmdCB7XHJcbiAgZ3JpZC1jb2x1bW46IDIgLyAzO1xyXG59XHJcblxyXG4uZnJvbS1yaWdodCB7XHJcbiAgZ3JpZC1jb2x1bW46IDMgLyA0O1xyXG59XHJcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUFBLElBQUksQ0FBQztFQUNILE1BQU0sRUFBRSxDQUFDO0VBQ1QsV0FBVyxFQUFFLHFCQUFxQjtDQUNuQzs7QUFFRCxBQUFBLFVBQVUsQ0FBQztFQUNULFdBQVcsRUFBRSxHQUFHO0VBQ2hCLFNBQVMsRUFBRSxNQUFNO0VBQ2pCLEtBQUssRUFBRSxXQUFXO0VBQ2xCLGVBQWUsRUFBRSxJQUFJO0NBQ3RCOztBQUVELEFBQUEsTUFBTSxDQUFDO0VBQ0wsTUFBTSxDQUFBLFFBQUM7RUFDUCxjQUFjLENBQUEsS0FBQztFQUNmLFlBQVksQ0FBQSxZQUFDO0VBRWIsUUFBUSxFQUFFLEtBQUs7RUFDZixHQUFHLEVBQUUsQ0FBQztFQUNOLElBQUksRUFBRSxDQUFDO0VBQ1AsS0FBSyxFQUFFLENBQUM7RUFDUixPQUFPLEVBQUUsR0FBRztFQUNaLE9BQU8sRUFBRSxJQUFJO0VBQ2IsZUFBZSxFQUFFLGFBQWE7RUFDOUIsV0FBVyxFQUFFLE1BQU07RUFDbkIsT0FBTyxFQUFFLE9BQU87RUFDaEIsVUFBVSxFQUFFLHdCQUF3QjtFQUNwQyxVQUFVLEVBQUUsaUJBQWlCO0VBQzdCLEtBQUssRUFBRSxXQUFXO0NBQ25COztBQUVELEFBQUEsVUFBVSxDQUFDO0VBQ1QsVUFBVSxFQUFFLElBQUk7RUFDaEIsTUFBTSxFQUFFLENBQUM7RUFDVCxPQUFPLEVBQUUsQ0FBQztFQUNWLE9BQU8sRUFBRSxJ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 */
166 |
--------------------------------------------------------------------------------
/3. Fade and scroll items into view while scrolling with Intersection Observer/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require("gulp");
2 | const sass = require("gulp-sass");
3 | const sourcemaps = require("gulp-sourcemaps");
4 | const autoprefixer = require("gulp-autoprefixer");
5 | const browserSync = require("browser-sync").create();
6 |
7 | const sassOptions = {
8 | outputStyle: "expanded"
9 | };
10 |
11 | // compile scss into css
12 |
13 | function style() {
14 | return gulp
15 | .src("./scss/**/*.scss")
16 | .pipe(sourcemaps.init())
17 | .pipe(sass(sassOptions).on("error", sass.logError))
18 | .pipe(sourcemaps.write())
19 | .pipe(autoprefixer())
20 | .pipe(gulp.dest("./css"))
21 | .pipe(browserSync.stream());
22 | }
23 |
24 | function watch() {
25 | browserSync.init({
26 | server: ".",
27 | browser: "firefox"
28 | });
29 | gulp.watch("./scss/**/*.scss", style);
30 | gulp.watch("./*.html").on("change", browserSync.reload);
31 | gulp.watch("./js/**/*.js").on("change", browserSync.reload);
32 | }
33 |
34 | exports.style = style;
35 | exports.watch = watch;
36 |
--------------------------------------------------------------------------------
/3. Fade and scroll items into view while scrolling with Intersection Observer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
12 |
13 |
14 |
15 |
16 |
17 | IntObs
18 |
19 |
32 |
33 |
34 |
35 |
36 | Login
37 |
38 |
39 | Join
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Intersection Observer is pretty useful
48 |
49 |
50 |
51 |
About us
52 |
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
53 |
54 |
55 |
Lorem, ipsum.
56 |
57 | Lorem ipsum dolor sit, amet consectetur adipisicing elit. Vitae maiores fuga eos
58 | provident voluptas perferendis.
59 |
60 |
61 |
62 |
A, illo!
63 |
64 | Lorem, ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus minima quo
65 | beatae eius blanditiis officiis.
66 |
67 |
68 |
69 |
Repudiandae, error?
70 |
71 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laborum quasi quis doloribus
72 | quia illum laudantium.
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
83 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
84 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
85 | cupiditate debitis facilis quibusdam magni. Eveniet.
86 |
87 |
88 |
89 |
90 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
91 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
92 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
93 | cupiditate debitis facilis quibusdam magni. Eveniet.
94 |
95 |
96 |
97 |
98 |
99 |
100 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
101 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
102 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
103 | cupiditate debitis facilis quibusdam magni. Eveniet.
104 |
105 |
106 |
107 |
108 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
109 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
110 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
111 | cupiditate debitis facilis quibusdam magni. Eveniet.
112 |
113 |
114 |
115 |
116 |
117 |
118 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
119 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
120 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
121 | cupiditate debitis facilis quibusdam magni. Eveniet.
122 |
123 |
124 |
125 |
126 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
127 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
128 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
129 | cupiditate debitis facilis quibusdam magni. Eveniet.
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/3. Fade and scroll items into view while scrolling with Intersection Observer/js/observers.js:
--------------------------------------------------------------------------------
1 | const header = document.querySelector('header');
2 | const navBreakpoint = document.querySelector('.home-intro');
3 |
4 | const faders = document.querySelectorAll('.fade-in');
5 |
6 | const sliders = document.querySelectorAll('.slide-in');
7 |
8 | //* navbar Intersection observer
9 | const navbarOptions = {
10 | root: null,
11 | threshold: 0,
12 | rootMargin: '-200px 0px 0px 0px',
13 | };
14 |
15 | const navbarObserver = new IntersectionObserver((entries, navbarObserver) => {
16 | entries.forEach(entry => {
17 | if (!entry.isIntersecting) {
18 | header.classList.add('nav-scrolled');
19 | } else {
20 | header.classList.remove('nav-scrolled');
21 | }
22 | });
23 | }, navbarOptions);
24 |
25 | navbarObserver.observe(navBreakpoint);
26 |
27 | //* faders Intersection observer
28 | const fadersOptions = {
29 | root: null,
30 | threshold: 1,
31 | rootMargin: '0px',
32 | };
33 |
34 | const fadersObserver = new IntersectionObserver((entries, fadersObserver) => {
35 | entries.forEach(entry => {
36 | if (entry.isIntersecting) {
37 | console.log('appear');
38 | entry.target.classList.add('appear');
39 | fadersObserver.unobserve(entry.target);
40 | }
41 | });
42 | }, fadersOptions);
43 |
44 | faders.forEach(fader => {
45 | fadersObserver.observe(fader);
46 | });
47 |
48 | //* slide in Intersection observer
49 | const slideInOptions = {
50 | root: null,
51 | threshold: 0.25,
52 | rootMargin: '0px',
53 | };
54 |
55 | const slideInObserver = new IntersectionObserver((entries, slideInObserver) => {
56 | entries.forEach(entry => {
57 | if (entry.isIntersecting) {
58 | entry.target.classList.add('appear');
59 | slideInObserver.unobserve(entry.target);
60 | }
61 | });
62 | }, slideInOptions);
63 |
64 | sliders.forEach(slider => {
65 | slideInObserver.observe(slider);
66 | });
67 |
--------------------------------------------------------------------------------
/3. Fade and scroll items into view while scrolling with Intersection Observer/scss/main.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: "Poppins", sans-serif;
4 | }
5 |
6 | .site-logo {
7 | font-weight: 900;
8 | font-size: 0.8rem;
9 | color: var(--text);
10 | text-decoration: none;
11 | }
12 |
13 | header {
14 | --text: #f4f4f4;
15 | --text-inverse: #333;
16 | --background: transparent;
17 |
18 | position: fixed;
19 | top: 0;
20 | left: 0;
21 | right: 0;
22 | z-index: 999;
23 | display: flex;
24 | justify-content: space-between;
25 | align-items: center;
26 | padding: 2em 3em;
27 | transition: background 250ms ease-in;
28 | background: var(--background);
29 | color: var(--text);
30 | }
31 |
32 | .nav__list {
33 | list-style: none;
34 | margin: 0;
35 | padding: 0;
36 | display: flex;
37 | }
38 |
39 | .nav__link {
40 | --spacing: 1em;
41 | text-decoration: none;
42 | color: inherit;
43 | display: inline-block;
44 | padding: calc(var(--spacing) / 2) var(--spacing);
45 | position: relative;
46 | text-transform: uppercase;
47 | letter-spacing: 2px;
48 | font-size: 0.9rem;
49 |
50 | &:after {
51 | content: "";
52 | position: absolute;
53 | bottom: 0;
54 | left: var(--spacing);
55 | right: var(--spacing);
56 | height: 2px;
57 | background: currentColor;
58 | transform: scaleX(0);
59 | transition: transform 150ms ease-in-out;
60 | }
61 |
62 | &:hover::after {
63 | transform: scaleX(1);
64 | }
65 |
66 | &--btn {
67 | border: 1.5px solid currentColor;
68 | border-radius: 2em;
69 | margin-left: 1em;
70 | transition: background 250ms ease-in-out;
71 | letter-spacing: 1px;
72 | padding: 0.75em 1.5em;
73 |
74 | &:hover {
75 | background: var(--text);
76 | color: var(--text-inverse);
77 | border-color: var(--text);
78 | }
79 |
80 | &::after {
81 | display: none;
82 | }
83 |
84 | &--highlight {
85 | background: limegreen;
86 | border-color: limegreen;
87 | color: #333;
88 |
89 | &:hover {
90 | background: var(--text);
91 | border-color: var(--text);
92 | }
93 | }
94 | }
95 | }
96 |
97 | .nav-scrolled {
98 | --text: #333;
99 | --text-inverse: #f4f4f4;
100 | --background: #f4f4f4;
101 |
102 | box-shadow: 0 3px 20px rgba(black, 0.2);
103 | }
104 |
105 | .home-intro {
106 | padding: 50vh 0;
107 | background: #123 url(//unsplash.it/900);
108 | background-size: cover;
109 | background-blend-mode: multiply;
110 | color: white;
111 | text-align: center;
112 | }
113 |
114 | .home-about {
115 | padding: 4em 0;
116 | max-width: 900px;
117 | margin: 0 auto;
118 | }
119 |
120 | .columns {
121 | display: flex;
122 | }
123 |
124 | .col + .col {
125 | margin-left: 1.5em;
126 | }
127 |
128 | .more-stuff-grid {
129 | background: #f4f4f4;
130 | padding: 4em 0;
131 | display: grid;
132 | grid-gap: 2em;
133 | align-items: center;
134 | grid-template-columns: minmax(1em, 1fr) repeat(2, minmax(200px, 400px)) minmax(
135 | 1em,
136 | 1fr
137 | );
138 | }
139 |
140 | .from-left {
141 | grid-column: 2 / 3;
142 | }
143 |
144 | .from-right {
145 | grid-column: 3 / 4;
146 | }
147 |
--------------------------------------------------------------------------------
/4. How to lazy load images with Intersection Obserrver/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: 'Poppins', sans-serif;
4 | }
5 |
6 | .site-logo {
7 | font-weight: 900;
8 | font-size: 0.8rem;
9 | color: var(--text);
10 | text-decoration: none;
11 | }
12 |
13 | header {
14 | --text: #f4f4f4;
15 | --text-inverse: #333;
16 | --background: transparent;
17 | position: fixed;
18 | top: 0;
19 | left: 0;
20 | right: 0;
21 | z-index: 999;
22 | display: flex;
23 | justify-content: space-between;
24 | align-items: center;
25 | padding: 2em 3em;
26 | transition: background 250ms ease-in;
27 | background: var(--background);
28 | color: var(--text);
29 | }
30 |
31 | .nav__list {
32 | list-style: none;
33 | margin: 0;
34 | padding: 0;
35 | display: flex;
36 | }
37 |
38 | .nav__link {
39 | --spacing: 1em;
40 | text-decoration: none;
41 | color: inherit;
42 | display: inline-block;
43 | padding: calc(var(--spacing) / 2) var(--spacing);
44 | position: relative;
45 | text-transform: uppercase;
46 | letter-spacing: 2px;
47 | font-size: 0.9rem;
48 | }
49 |
50 | .nav__link:after {
51 | content: '';
52 | position: absolute;
53 | bottom: 0;
54 | left: var(--spacing);
55 | right: var(--spacing);
56 | height: 2px;
57 | background: currentColor;
58 | -webkit-transform: scaleX(0);
59 | transform: scaleX(0);
60 | transition: -webkit-transform 150ms ease-in-out;
61 | transition: transform 150ms ease-in-out;
62 | transition: transform 150ms ease-in-out, -webkit-transform 150ms ease-in-out;
63 | }
64 |
65 | .nav__link:hover::after {
66 | -webkit-transform: scaleX(1);
67 | transform: scaleX(1);
68 | }
69 |
70 | .nav__link--btn {
71 | border: 1.5px solid currentColor;
72 | border-radius: 2em;
73 | margin-left: 1em;
74 | transition: background 250ms ease-in-out;
75 | letter-spacing: 1px;
76 | padding: 0.75em 1.5em;
77 | }
78 |
79 | .nav__link--btn:hover {
80 | background: var(--text);
81 | color: var(--text-inverse);
82 | border-color: var(--text);
83 | }
84 |
85 | .nav__link--btn::after {
86 | display: none;
87 | }
88 |
89 | .nav__link--btn--highlight {
90 | background: limegreen;
91 | border-color: limegreen;
92 | color: #333;
93 | }
94 |
95 | .nav__link--btn--highlight:hover {
96 | background: var(--text);
97 | border-color: var(--text);
98 | }
99 |
100 | .nav-scrolled {
101 | --text: #333;
102 | --text-inverse: #f4f4f4;
103 | --background: #f4f4f4;
104 | box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
105 | }
106 |
107 | .home-intro {
108 | padding: 50vh 0;
109 | background: #123 url(//unsplash.it/900);
110 | background-size: cover;
111 | background-blend-mode: multiply;
112 | color: white;
113 | text-align: center;
114 | }
115 |
116 | .home-about {
117 | padding: 4em 0;
118 | max-width: 900px;
119 | margin: 0 auto;
120 | }
121 |
122 | .columns {
123 | display: flex;
124 | }
125 |
126 | .col + .col {
127 | margin-left: 1.5em;
128 | }
129 |
130 | .fade-in {
131 | opacity: 0;
132 | transition: opacity 1s ease-in;
133 | }
134 |
135 | .fade-in.appear {
136 | opacity: 1;
137 | }
138 |
139 | .more-stuff-grid {
140 | background: #f4f4f4;
141 | padding: 4em 0;
142 | display: grid;
143 | grid-gap: 2em;
144 | align-items: center;
145 | grid-template-columns: minmax(1em, 1fr) repeat(2, minmax(200px, 400px)) minmax(1em, 1fr);
146 | }
147 |
148 | .from-left {
149 | grid-column: 2 / 3;
150 | }
151 |
152 | .from-right {
153 | grid-column: 3 / 4;
154 | }
155 |
156 | /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5jc3MiLCJzb3VyY2VzIjpbIm1haW4uc2NzcyJdLCJzb3VyY2VzQ29udGVudCI6WyJib2R5IHtcclxuICBtYXJnaW46IDA7XHJcbiAgZm9udC1mYW1pbHk6IFwiUG9wcGluc1wiLCBzYW5zLXNlcmlmO1xyXG59XHJcblxyXG4uc2l0ZS1sb2dvIHtcclxuICBmb250LXdlaWdodDogOTAwO1xyXG4gIGZvbnQtc2l6ZTogMC44cmVtO1xyXG4gIGNvbG9yOiB2YXIoLS10ZXh0KTtcclxuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XHJcbn1cclxuXHJcbmhlYWRlciB7XHJcbiAgLS10ZXh0OiAjZjRmNGY0O1xyXG4gIC0tdGV4dC1pbnZlcnNlOiAjMzMzO1xyXG4gIC0tYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XHJcblxyXG4gIHBvc2l0aW9uOiBmaXhlZDtcclxuICB0b3A6IDA7XHJcbiAgbGVmdDogMDtcclxuICByaWdodDogMDtcclxuICB6LWluZGV4OiA5OTk7XHJcbiAgZGlzcGxheTogZmxleDtcclxuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XHJcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICBwYWRkaW5nOiAyZW0gM2VtO1xyXG4gIHRyYW5zaXRpb246IGJhY2tncm91bmQgMjUwbXMgZWFzZS1pbjtcclxuICBiYWNrZ3JvdW5kOiB2YXIoLS1iYWNrZ3JvdW5kKTtcclxuICBjb2xvcjogdmFyKC0tdGV4dCk7XHJcbn1cclxuXHJcbi5uYXZfX2xpc3Qge1xyXG4gIGxpc3Qtc3R5bGU6IG5vbmU7XHJcbiAgbWFyZ2luOiAwO1xyXG4gIHBhZGRpbmc6IDA7XHJcbiAgZGlzcGxheTogZmxleDtcclxufVxyXG5cclxuLm5hdl9fbGluayB7XHJcbiAgLS1zcGFjaW5nOiAxZW07XHJcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xyXG4gIGNvbG9yOiBpbmhlcml0O1xyXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcclxuICBwYWRkaW5nOiBjYWxjKHZhcigtLXNwYWNpbmcpIC8gMikgdmFyKC0tc3BhY2luZyk7XHJcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XHJcbiAgbGV0dGVyLXNwYWNpbmc6IDJweDtcclxuICBmb250LXNpemU6IDAuOXJlbTtcclxuXHJcbiAgJjphZnRlciB7XHJcbiAgICBjb250ZW50OiBcIlwiO1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgYm90dG9tOiAwO1xyXG4gICAgbGVmdDogdmFyKC0tc3BhY2luZyk7XHJcbiAgICByaWdodDogdmFyKC0tc3BhY2luZyk7XHJcbiAgICBoZWlnaHQ6IDJweDtcclxuICAgIGJhY2tncm91bmQ6IGN1cnJlbnRDb2xvcjtcclxuICAgIHRyYW5zZm9ybTogc2NhbGVYKDApO1xyXG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDE1MG1zIGVhc2UtaW4tb3V0O1xyXG4gIH1cclxuXHJcbiAgJjpob3Zlcjo6YWZ0ZXIge1xyXG4gICAgdHJhbnNmb3JtOiBzY2FsZVgoMSk7XHJcbiAgfVxyXG5cclxuICAmLS1idG4ge1xyXG4gICAgYm9yZGVyOiAxLjVweCBzb2xpZCBjdXJyZW50Q29sb3I7XHJcbiAgICBib3JkZXItcmFkaXVzOiAyZW07XHJcbiAgICBtYXJnaW4tbGVmdDogMWVtO1xyXG4gICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAyNTBtcyBlYXNlLWluLW91dDtcclxuICAgIGxldHRlci1zcGFjaW5nOiAxcHg7XHJcbiAgICBwYWRkaW5nOiAwLjc1ZW0gMS41ZW07XHJcblxyXG4gICAgJjpob3ZlciB7XHJcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXRleHQpO1xyXG4gICAgICBjb2xvcjogdmFyKC0tdGV4dC1pbnZlcnNlKTtcclxuICAgICAgYm9yZGVyLWNvbG9yOiB2YXIoLS10ZXh0KTtcclxuICAgIH1cclxuXHJcbiAgICAmOjphZnRlciB7XHJcbiAgICAgIGRpc3BsYXk6IG5vbmU7XHJcbiAgICB9XHJcblxyXG4gICAgJi0taGlnaGxpZ2h0IHtcclxuICAgICAgYmFja2dyb3VuZDogbGltZWdyZWVuO1xyXG4gICAgICBib3JkZXItY29sb3I6IGxpbWVncmVlbjtcclxuICAgICAgY29sb3I6ICMzMzM7XHJcblxyXG4gICAgICAmOmhvdmVyIHtcclxuICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS10ZXh0KTtcclxuICAgICAgICBib3JkZXItY29sb3I6IHZhcigtLXRleHQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4ubmF2LXNjcm9sbGVkIHtcclxuICAtLXRleHQ6ICMzMzM7XHJcbiAgLS10ZXh0LWludmVyc2U6ICNmNGY0ZjQ7XHJcbiAgLS1iYWNrZ3JvdW5kOiAjZjRmNGY0O1xyXG5cclxuICBib3gtc2hhZG93OiAwIDNweCAyMHB4IHJnYmEoYmxhY2ssIDAuMik7XHJcbn1cclxuXHJcbi5ob21lLWludHJvIHtcclxuICBwYWRkaW5nOiA1MHZoIDA7XHJcbiAgYmFja2dyb3VuZDogIzEyMyB1cmwoLy91bnNwbGFzaC5pdC85MDApO1xyXG4gIGJhY2tncm91bmQtc2l6ZTogY292ZXI7XHJcbiAgYmFja2dyb3VuZC1ibGVuZC1tb2RlOiBtdWx0aXBseTtcclxuICBjb2xvcjogd2hpdGU7XHJcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG59XHJcblxyXG4uaG9tZS1hYm91dCB7XHJcbiAgcGFkZGluZzogNGVtIDA7XHJcbiAgbWF4LXdpZHRoOiA5MDBweDtcclxuICBtYXJnaW46IDAgYXV0bztcclxufVxyXG5cclxuLmNvbHVtbnMge1xyXG4gIGRpc3BsYXk6IGZsZXg7XHJcbn1cclxuXHJcbi5jb2wgKyAuY29sIHtcclxuICBtYXJnaW4tbGVmdDogMS41ZW07XHJcbn1cclxuXHJcbi5tb3JlLXN0dWZmLWdyaWQge1xyXG4gIGJhY2tncm91bmQ6ICNmNGY0ZjQ7XHJcbiAgcGFkZGluZzogNGVtIDA7XHJcbiAgZGlzcGxheTogZ3JpZDtcclxuICBncmlkLWdhcDogMmVtO1xyXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBtaW5tYXgoMWVtLCAxZnIpIHJlcGVhdCgyLCBtaW5tYXgoMjAwcHgsIDQwMHB4KSkgbWlubWF4KFxyXG4gICAgICAxZW0sXHJcbiAgICAgIDFmclxyXG4gICAgKTtcclxufVxyXG5cclxuLmZyb20tbGVmdCB7XHJcbiAgZ3JpZC1jb2x1bW46IDIgLyAzO1xyXG59XHJcblxyXG4uZnJvbS1yaWdodCB7XHJcbiAgZ3JpZC1jb2x1bW46IDMgLyA0O1xyXG59XHJcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUFBLElBQUksQ0FBQztFQUNILE1BQU0sRUFBRSxDQUFDO0VBQ1QsV0FBVyxFQUFFLHFCQUFxQjtDQUNuQzs7QUFFRCxBQUFBLFVBQVUsQ0FBQztFQUNULFdBQVcsRUFBRSxHQUFHO0VBQ2hCLFNBQVMsRUFBRSxNQUFNO0VBQ2pCLEtBQUssRUFBRSxXQUFXO0VBQ2xCLGVBQWUsRUFBRSxJQUFJO0NBQ3RCOztBQUVELEFBQUEsTUFBTSxDQUFDO0VBQ0wsTUFBTSxDQUFBLFFBQUM7RUFDUCxjQUFjLENBQUEsS0FBQztFQUNmLFlBQVksQ0FBQSxZQUFDO0VBRWIsUUFBUSxFQUFFLEtBQUs7RUFDZixHQUFHLEVBQUUsQ0FBQztFQUNOLElBQUksRUFBRSxDQUFDO0VBQ1AsS0FBSyxFQUFFLENBQUM7RUFDUixPQUFPLEVBQUUsR0FBRztFQUNaLE9BQU8sRUFBRSxJQUFJO0VBQ2IsZUFBZSxFQUFFLGFBQWE7RUFDOUIsV0FBVyxFQUFFLE1BQU07RUFDbkIsT0FBTyxFQUFFLE9BQU87RUFDaEIsVUFBVSxFQUFFLHdCQUF3QjtFQUNwQyxVQUFVLEVBQUUsaUJBQWlCO0VBQzdCLEtBQUssRUFBRSxXQUFXO0NBQ25COztBQUVELEFBQUEsVUFBVSxDQUFDO0VBQ1QsVUFBVSxFQUFFLElBQUk7RUFDaEIsTUFBTSxFQUFFLENBQUM7RUFDVCxPQUFPLEVBQUUsQ0FBQztFQUNWLE9BQU8sRUFBRSxJ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 */
157 |
--------------------------------------------------------------------------------
/4. How to lazy load images with Intersection Obserrver/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require("gulp");
2 | const sass = require("gulp-sass");
3 | const sourcemaps = require("gulp-sourcemaps");
4 | const autoprefixer = require("gulp-autoprefixer");
5 | const browserSync = require("browser-sync").create();
6 |
7 | const sassOptions = {
8 | outputStyle: "expanded"
9 | };
10 |
11 | // compile scss into css
12 |
13 | function style() {
14 | return gulp
15 | .src("./scss/**/*.scss")
16 | .pipe(sourcemaps.init())
17 | .pipe(sass(sassOptions).on("error", sass.logError))
18 | .pipe(sourcemaps.write())
19 | .pipe(autoprefixer())
20 | .pipe(gulp.dest("./css"))
21 | .pipe(browserSync.stream());
22 | }
23 |
24 | function watch() {
25 | browserSync.init({
26 | server: ".",
27 | browser: "firefox"
28 | });
29 | gulp.watch("./scss/**/*.scss", style);
30 | gulp.watch("./*.html").on("change", browserSync.reload);
31 | gulp.watch("./js/**/*.js").on("change", browserSync.reload);
32 | }
33 |
34 | exports.style = style;
35 | exports.watch = watch;
36 |
--------------------------------------------------------------------------------
/4. How to lazy load images with Intersection Obserrver/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
12 |
13 |
14 |
15 |
16 |
17 | IntObs
18 |
19 |
32 |
33 |
34 |
35 |
36 | Login
37 |
38 |
39 | Join
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Intersection Observer is pretty useful
48 |
49 |
50 |
51 |
About us
52 |
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
53 |
54 |
55 |
Lorem, ipsum.
56 |
57 | Lorem ipsum dolor sit, amet consectetur adipisicing elit. Vitae maiores fuga eos
58 | provident voluptas perferendis.
59 |
60 |
61 |
62 |
A, illo!
63 |
64 | Lorem, ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus minima quo
65 | beatae eius blanditiis officiis.
66 |
67 |
68 |
69 |
Repudiandae, error?
70 |
71 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Laborum quasi quis doloribus
72 | quia illum laudantium.
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
83 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
84 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
85 | cupiditate debitis facilis quibusdam magni. Eveniet.
86 |
87 |
88 |
89 |
90 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
91 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
92 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
93 | cupiditate debitis facilis quibusdam magni. Eveniet.
94 |
95 |
96 |
97 |
98 |
99 |
100 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
101 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
102 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
103 | cupiditate debitis facilis quibusdam magni. Eveniet.
104 |
105 |
106 |
107 |
108 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
109 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
110 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
111 | cupiditate debitis facilis quibusdam magni. Eveniet.
112 |
113 |
114 |
115 |
116 |
117 |
118 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
119 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
120 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
121 | cupiditate debitis facilis quibusdam magni. Eveniet.
122 |
123 |
124 |
125 |
126 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis fugit, quae beatae vero
127 | sit magni quaerat id ratione. Dolor optio unde amet omnis sapiente neque cumque
128 | consequuntur reiciendis deserunt. Dolorem vero exercitationem consequuntur, eligendi
129 | cupiditate debitis facilis quibusdam magni. Eveniet.
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/4. How to lazy load images with Intersection Obserrver/js/lazy-loader.js:
--------------------------------------------------------------------------------
1 | const images = document.querySelectorAll('[data-src]');
2 |
3 | const imagesOption = {
4 | root: null,
5 | threshold: 0,
6 | rootMargin: '0px',
7 | };
8 |
9 | const preloadImage = element => {
10 | const src = element.getAttribute('data-src');
11 |
12 | if (src) {
13 | element.src = src;
14 | }
15 | };
16 |
17 | const imagesObserver = new IntersectionObserver((entries, imagesObserver) => {
18 | entries.forEach(entry => {
19 | if (entry.isIntersecting) {
20 | preloadImage(entry.target);
21 | imagesObserver.unobserve(entry.target);
22 | }
23 | });
24 | }, imagesOption);
25 |
26 | images.forEach(image => {
27 | imagesObserver.observe(image);
28 | });
29 |
--------------------------------------------------------------------------------
/4. How to lazy load images with Intersection Obserrver/js/observers.js:
--------------------------------------------------------------------------------
1 | const header = document.querySelector('header');
2 | const navBreakpoint = document.querySelector('.home-intro');
3 |
4 | const faders = document.querySelectorAll('.fade-in');
5 |
6 | const sliders = document.querySelectorAll('.slide-in');
7 |
8 | //* navbar Intersection observer
9 | const navbarOptions = {
10 | root: null,
11 | threshold: 0,
12 | rootMargin: '-200px 0px 0px 0px',
13 | };
14 |
15 | const navbarObserver = new IntersectionObserver((entries, navbarObserver) => {
16 | entries.forEach(entry => {
17 | if (!entry.isIntersecting) {
18 | header.classList.add('nav-scrolled');
19 | } else {
20 | header.classList.remove('nav-scrolled');
21 | }
22 | });
23 | }, navbarOptions);
24 |
25 | navbarObserver.observe(navBreakpoint);
26 |
27 | //* faders Intersection observer
28 | const fadersOptions = {
29 | root: null,
30 | threshold: 1,
31 | rootMargin: '0px',
32 | };
33 |
34 | const fadersObserver = new IntersectionObserver((entries, fadersObserver) => {
35 | entries.forEach(entry => {
36 | if (entry.isIntersecting) {
37 | console.log('appear');
38 | entry.target.classList.add('appear');
39 | fadersObserver.unobserve(entry.target);
40 | }
41 | });
42 | }, fadersOptions);
43 |
44 | faders.forEach(fader => {
45 | fadersObserver.observe(fader);
46 | });
47 |
--------------------------------------------------------------------------------
/4. How to lazy load images with Intersection Obserrver/lazy loading v2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AbdallahHemdan/Lazy-Loading/2a2d7f1cf370b525937394dd0ab551ca564fc511/4. How to lazy load images with Intersection Obserrver/lazy loading v2.gif
--------------------------------------------------------------------------------
/4. How to lazy load images with Intersection Obserrver/scss/main.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: "Poppins", sans-serif;
4 | }
5 |
6 | .site-logo {
7 | font-weight: 900;
8 | font-size: 0.8rem;
9 | color: var(--text);
10 | text-decoration: none;
11 | }
12 |
13 | header {
14 | --text: #f4f4f4;
15 | --text-inverse: #333;
16 | --background: transparent;
17 |
18 | position: fixed;
19 | top: 0;
20 | left: 0;
21 | right: 0;
22 | z-index: 999;
23 | display: flex;
24 | justify-content: space-between;
25 | align-items: center;
26 | padding: 2em 3em;
27 | transition: background 250ms ease-in;
28 | background: var(--background);
29 | color: var(--text);
30 | }
31 |
32 | .nav__list {
33 | list-style: none;
34 | margin: 0;
35 | padding: 0;
36 | display: flex;
37 | }
38 |
39 | .nav__link {
40 | --spacing: 1em;
41 | text-decoration: none;
42 | color: inherit;
43 | display: inline-block;
44 | padding: calc(var(--spacing) / 2) var(--spacing);
45 | position: relative;
46 | text-transform: uppercase;
47 | letter-spacing: 2px;
48 | font-size: 0.9rem;
49 |
50 | &:after {
51 | content: "";
52 | position: absolute;
53 | bottom: 0;
54 | left: var(--spacing);
55 | right: var(--spacing);
56 | height: 2px;
57 | background: currentColor;
58 | transform: scaleX(0);
59 | transition: transform 150ms ease-in-out;
60 | }
61 |
62 | &:hover::after {
63 | transform: scaleX(1);
64 | }
65 |
66 | &--btn {
67 | border: 1.5px solid currentColor;
68 | border-radius: 2em;
69 | margin-left: 1em;
70 | transition: background 250ms ease-in-out;
71 | letter-spacing: 1px;
72 | padding: 0.75em 1.5em;
73 |
74 | &:hover {
75 | background: var(--text);
76 | color: var(--text-inverse);
77 | border-color: var(--text);
78 | }
79 |
80 | &::after {
81 | display: none;
82 | }
83 |
84 | &--highlight {
85 | background: limegreen;
86 | border-color: limegreen;
87 | color: #333;
88 |
89 | &:hover {
90 | background: var(--text);
91 | border-color: var(--text);
92 | }
93 | }
94 | }
95 | }
96 |
97 | .nav-scrolled {
98 | --text: #333;
99 | --text-inverse: #f4f4f4;
100 | --background: #f4f4f4;
101 |
102 | box-shadow: 0 3px 20px rgba(black, 0.2);
103 | }
104 |
105 | .home-intro {
106 | padding: 50vh 0;
107 | background: #123 url(//unsplash.it/900);
108 | background-size: cover;
109 | background-blend-mode: multiply;
110 | color: white;
111 | text-align: center;
112 | }
113 |
114 | .home-about {
115 | padding: 4em 0;
116 | max-width: 900px;
117 | margin: 0 auto;
118 | }
119 |
120 | .columns {
121 | display: flex;
122 | }
123 |
124 | .col + .col {
125 | margin-left: 1.5em;
126 | }
127 |
128 | .more-stuff-grid {
129 | background: #f4f4f4;
130 | padding: 4em 0;
131 | display: grid;
132 | grid-gap: 2em;
133 | align-items: center;
134 | grid-template-columns: minmax(1em, 1fr) repeat(2, minmax(200px, 400px)) minmax(
135 | 1em,
136 | 1fr
137 | );
138 | }
139 |
140 | .from-left {
141 | grid-column: 2 / 3;
142 | }
143 |
144 | .from-right {
145 | grid-column: 3 / 4;
146 | }
147 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Abdallah Hemdan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 
5 |
6 |
7 |
8 |
9 | Lazy Loading
10 |
11 |
12 | [](https://github.com/AbdallahHemdan/Lazy-Loading/contributors)
13 | [](https://github.com/AbdallahHemdan/Lazy-Loading/issues)
14 | [](https://github.com/AbdallahHemdan/Lazy-Loading/network)
15 | [](https://github.com/AbdallahHemdan/Lazy-Loading/stargazers)
16 | [](https://github.com/AbdallahHemdan/Lazy-Loading/blob/master/LICENSE)
17 |
18 |
19 |
20 | ## About
21 | > All codes I wrote while learning about [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) and its applications and usages
22 |
23 | - [x] Introduction to the Intersection Observer JavaScript API
24 | - [x] How to change your navigation style on scroll using Intersection Observer
25 | - [x] Fade and scroll items into view while scrolling using Intersection Observer
26 | - [x] How to lazy load images using Intersection Observer
27 |
28 | ## Useful links
29 |
30 | - [w3c/IntersectionObserver](https://github.com/w3c/IntersectionObserver)
31 | - [lozad.js](https://github.com/ApoorvSaxena/lozad.js)
32 | - [lazysizes](https://github.com/aFarkas/lazysizes)
33 | - [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
34 | - [How To Defer, Lazy-Load And Act With IntersectionObserver](https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/)
35 |
36 |
37 |
38 |
39 |
40 | 
41 |
42 |
43 |
44 | 
45 |
46 |
47 |
48 |
49 | 
50 |
51 |
52 |
53 | 
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------