├── 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 |
Lazy Loaded 1
12 |
Lazy Loaded 2
13 |
Lazy Loaded 3
14 |
Lazy Loaded 4
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 | 18 | 33 | 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 | 18 | 33 | 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 | 18 | 33 | 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 | ![Lazy loading](https://user-images.githubusercontent.com/40190772/91656758-791dc700-eabb-11ea-95d7-94957917dc35.png) 5 | 6 | 7 |

8 | 9 |

Lazy Loading

10 |
11 | 12 | [![GitHub contributors](https://img.shields.io/github/contributors/AbdallahHemdan/Lazy-Loading)](https://github.com/AbdallahHemdan/Lazy-Loading/contributors) 13 | [![GitHub issues](https://img.shields.io/github/issues/AbdallahHemdan/Lazy-Loading)](https://github.com/AbdallahHemdan/Lazy-Loading/issues) 14 | [![GitHub forks](https://img.shields.io/github/forks/AbdallahHemdan/Lazy-Loading)](https://github.com/AbdallahHemdan/Lazy-Loading/network) 15 | [![GitHub stars](https://img.shields.io/github/stars/AbdallahHemdan/Lazy-Loading)](https://github.com/AbdallahHemdan/Lazy-Loading/stargazers) 16 | [![GitHub license](https://img.shields.io/github/license/AbdallahHemdan/Lazy-Loading)](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 | ![lazy-loading](https://user-images.githubusercontent.com/40190772/91657053-56d97880-eabe-11ea-9380-fb9750053138.gif) 41 | 42 |


43 | 44 | ![navigation-sroll-Intersecion-observer](https://user-images.githubusercontent.com/40190772/91657054-59d46900-eabe-11ea-81c3-488d8d9eccd7.gif) 45 | 46 | 47 |


48 | 49 | ![Fade and scroll items into view while scrolling](https://user-images.githubusercontent.com/40190772/91664100-3ffe4a80-eaed-11ea-881d-14d9f1ad829a.gif) 50 | 51 |


52 | 53 | ![lazy loading](https://user-images.githubusercontent.com/40190772/91665493-4a711200-eaf6-11ea-95b3-232718b849f3.gif) 54 | 55 |


56 | 57 | 58 | 59 |
60 | --------------------------------------------------------------------------------