From f723253f784ef4f0dab782e04dc18e62ee4df65d Mon Sep 17 00:00:00 2001 From: joaquinelio Date: Sun, 28 Mar 2021 00:08:17 -0300 Subject: [PATCH 01/81] transpiler def --- 1-js/03-code-quality/06-polyfills/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md index af38faad2..9d119132e 100644 --- a/1-js/03-code-quality/06-polyfills/article.md +++ b/1-js/03-code-quality/06-polyfills/article.md @@ -22,7 +22,7 @@ Here, in this chapter, our purpose is to get the gist of how they work, and thei ## Transpilers -A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that can parse ("read and understand") modern code, and rewrite it using older syntax constructs, so that the result would be the same. +A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that can parse ("read and understand") modern code, and rewrite it using syntax constructs that the target engine (even oudated ones) can run. E.g. JavaScript before year 2020 didn't have the "nullish coalescing operator" `??`. So, if a visitor uses an outdated browser, it may fail to understand the code like `height = height ?? 100`. From 3d88d3322e97c06c3cbd09bb58f6a025351130a6 Mon Sep 17 00:00:00 2001 From: Z Yin Date: Sun, 13 Jun 2021 16:48:40 -0400 Subject: [PATCH 02/81] Update article.md --- 1-js/05-data-types/02-number/article.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md index 6fd513f43..6f9ddd953 100644 --- a/1-js/05-data-types/02-number/article.md +++ b/1-js/05-data-types/02-number/article.md @@ -37,8 +37,8 @@ alert( 7.3e9 ); // 7.3 billions (same as 7300000000 or 7_300_000_000) In other words, `e` multiplies the number by `1` with the given zeroes count. ```js -1e3 = 1 * 1000 // e3 means *1000 -1.23e6 = 1.23 * 1000000 // e6 means *1000000 +1e3 === 1 * 1000; // e3 means *1000 +1.23e6 === 1.23 * 1000000; // e6 means *1000000 ``` Now let's write something very small. Say, 1 microsecond (one millionth of a second): @@ -59,10 +59,10 @@ In other words, a negative number after `"e"` means a division by 1 with the giv ```js // -3 divides by 1 with 3 zeroes -1e-3 = 1 / 1000 (=0.001) +1e-3 === 1 / 1000; // 0.001 // -6 divides by 1 with 6 zeroes -1.23e-6 = 1.23 / 1000000 (=0.00000123) +1.23e-6 === 1.23 / 1000000; // 0.00000123 ``` ### Hex, binary and octal numbers @@ -118,6 +118,7 @@ Please note that two dots in `123456..toString(36)` is not a typo. If we want to If we placed a single dot: `123456.toString(36)`, then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now goes the method. Also could write `(123456).toString(36)`. + ``` ## Rounding From 2dce19e3e9bc37d2e473e137157ab48c99340676 Mon Sep 17 00:00:00 2001 From: joaquinelio Date: Wed, 16 Jun 2021 02:05:38 -0300 Subject: [PATCH 03/81] "inserts into" instead of "appends to" --- 1-js/11-async/01-callbacks/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md index 344d92b74..9432e860b 100644 --- a/1-js/11-async/01-callbacks/article.md +++ b/1-js/11-async/01-callbacks/article.md @@ -28,7 +28,7 @@ function loadScript(src) { } ``` -It appends to the document the new, dynamically created, tag ` ``` +The `onkeydown` handler here uses `checkPhoneKey` to check for the key pressed. If it's valid (from `0..9` or one of `+-()`), then it returns `true`, otherwise `false`. + +As we know, the `false` value returned from the event handler, assigned using a DOM property or an attribute, such as above, prevents the default action, so nothing appears in the `` for keys that don't pass the test. (The `true` value returned doesn't affect anything, only returning `false` matters) + Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, `key:Ctrl+V`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`. Let's relax it a little bit: @@ -153,8 +157,8 @@ Let's relax it a little bit: ```html autorun height=60 run From ff53f0638b4fcf9a4ab851b175d28d32a465f42f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:48:57 +0300 Subject: [PATCH 15/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index b4b398062..d7892b683 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -151,7 +151,7 @@ As we know, the `false` value returned from the event handler, assigned using a Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, `key:Ctrl+V`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`. -Let's relax it a little bit: +Let's relax it a little bit by allowing `key:Left`, `key:Right` arrows and `key:Delete`, `key:Backspace`: ```html autorun height=60 run From cf82cc3bcedc08eeb545a9caf7a246170d23d6c6 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:49:46 +0300 Subject: [PATCH 16/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index d7892b683..6318fde21 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -149,7 +149,7 @@ The `onkeydown` handler here uses `checkPhoneKey` to check for the key pressed. As we know, the `false` value returned from the event handler, assigned using a DOM property or an attribute, such as above, prevents the default action, so nothing appears in the `` for keys that don't pass the test. (The `true` value returned doesn't affect anything, only returning `false` matters) -Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, `key:Ctrl+V`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`. +Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`. Let's relax it a little bit by allowing `key:Left`, `key:Right` arrows and `key:Delete`, `key:Backspace`: From 85282ef4ad90e33e6b0a35bdf1fe062cd262693c Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:50:12 +0300 Subject: [PATCH 17/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index 6318fde21..78c4bf1f5 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -149,9 +149,9 @@ The `onkeydown` handler here uses `checkPhoneKey` to check for the key pressed. As we know, the `false` value returned from the event handler, assigned using a DOM property or an attribute, such as above, prevents the default action, so nothing appears in the `` for keys that don't pass the test. (The `true` value returned doesn't affect anything, only returning `false` matters) -Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`. +Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`. These keys make it return `false`. -Let's relax it a little bit by allowing `key:Left`, `key:Right` arrows and `key:Delete`, `key:Backspace`: +Let's relax the filter a little bit by allowing `key:Left`, `key:Right` arrows and `key:Delete`, `key:Backspace`: ```html autorun height=60 run From a40ca9a4a3b7624ca95096df9950ea30c0853e95 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:50:41 +0300 Subject: [PATCH 18/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index 78c4bf1f5..9639239cd 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -151,8 +151,7 @@ As we know, the `false` value returned from the event handler, assigned using a Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`. These keys make it return `false`. -Let's relax the filter a little bit by allowing `key:Left`, `key:Right` arrows and `key:Delete`, `key:Backspace`: - +Let's relax the filter a little bit by allowing arrow keys `key:Left`, `key:Right` and `key:Delete`, `key:Backspace`: ```html autorun height=60 run From df6e5a4522e83a071d5c0013648d2839f5b68345 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:53:06 +0300 Subject: [PATCH 20/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index f683e1f7e..cea96a101 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -165,7 +165,7 @@ function checkPhoneKey(key) { Now arrows and deletion works well. -...But we still can enter anything by using a mouse and right-click + Paste. So the filter is not 100% reliable. We can just let it be like that, because most of time it works. Or an alternative approach would be to track the `input` event -- it triggers after any modification. There we can check the new value and highlight/modify it when it's invalid. +Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. So the filter is not 100% reliable. We can just let it be like that, because most of time it works. Or an alternative approach would be to track the `input` event -- it triggers after any modification. There we can check the new value and highlight/modify it when it's invalid. ## Legacy From e769408d640e325233fe46c2d30b83edf9b3334d Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:55:00 +0300 Subject: [PATCH 21/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index cea96a101..0af3cee42 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -165,7 +165,7 @@ function checkPhoneKey(key) { Now arrows and deletion works well. -Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. So the filter is not 100% reliable. We can just let it be like that, because most of time it works. Or an alternative approach would be to track the `input` event -- it triggers after any modification. There we can check the new value and highlight/modify it when it's invalid. +Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. So the filter is not 100% reliable. The more reliable approach would be to track the `input` event -- it triggers after any modification. There we can check the new value and highlight/modify it when it's invalid. ## Legacy From de81cb4809ca3147a6c5cede2fb60c9af1e5dc54 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:58:37 +0300 Subject: [PATCH 22/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index 0af3cee42..8a15e657a 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -165,7 +165,9 @@ function checkPhoneKey(key) { Now arrows and deletion works well. -Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. So the filter is not 100% reliable. The more reliable approach would be to track the `input` event -- it triggers after any modification. There we can check the new value and highlight/modify it when it's invalid. +Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. So the filter is not 100% reliable. + +The alternative approach would be to track the `oninput` event -- it triggers *after* any modification. There we can check the new `input.value` and highlight/modify the `` when it's invalid. Or we can use both event handlers together. ## Legacy From 7dacfd411b4d99536b02df5200a4e4f5078adff3 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:59:04 +0300 Subject: [PATCH 23/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index 8a15e657a..bdfcff308 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -167,7 +167,7 @@ Now arrows and deletion works well. Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. So the filter is not 100% reliable. -The alternative approach would be to track the `oninput` event -- it triggers *after* any modification. There we can check the new `input.value` and highlight/modify the `` when it's invalid. Or we can use both event handlers together. +The alternative approach would be to track the `oninput` event -- it triggers *after* any modification. There we can check the new `input.value` and modify it/highlight the `` when it's invalid. Or we can use both event handlers together. ## Legacy From 36613935fea17fe8e0e85dd14c9af0dd3d5b5ac8 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 19 Jun 2021 18:59:39 +0300 Subject: [PATCH 24/81] minor fixes --- 2-ui/3-event-details/7-keyboard-events/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index bdfcff308..51c1618f6 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -165,7 +165,7 @@ function checkPhoneKey(key) { Now arrows and deletion works well. -Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. So the filter is not 100% reliable. +Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. Mobile devices provide other means to enter values. So the filter is not 100% reliable. The alternative approach would be to track the `oninput` event -- it triggers *after* any modification. There we can check the new `input.value` and modify it/highlight the `` when it's invalid. Or we can use both event handlers together. From 52eaa63aaa0f7f0bdcd739cc3f7e915f32dfd249 Mon Sep 17 00:00:00 2001 From: joaquinelio Date: Sat, 19 Jun 2021 21:21:24 -0300 Subject: [PATCH 25/81] typo --- 1-js/04-object-basics/09-object-toprimitive/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/04-object-basics/09-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md index b0605d44f..3e52a1d51 100644 --- a/1-js/04-object-basics/09-object-toprimitive/article.md +++ b/1-js/04-object-basics/09-object-toprimitive/article.md @@ -9,7 +9,7 @@ In case of such operations, objects are auto-converted to primitives, and then t That's an important limitation, as the result of `obj1 + obj2` can't be another object! -E.g. we can't make objects representing vectors or matrices (or archievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board". +E.g. we can't make objects representing vectors or matrices (or achievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board". So, because we can't do much here, there's no maths with objects in real projects. When it happens, it's usually because of a coding mistake. @@ -133,7 +133,7 @@ As we can see from the code, `user` becomes a self-descriptive string or a money If there's no `Symbol.toPrimitive` then JavaScript tries to find methods `toString` and `valueOf`: -- For the "string" hint: `toString`, and if it doesn't exist, then `valueOf` (so `toString` has the priority for stirng conversions). +- For the "string" hint: `toString`, and if it doesn't exist, then `valueOf` (so `toString` has the priority for string conversions). - For other hints: `valueOf`, and if it doesn't exist, then `toString` (so `valueOf` has the priority for maths). Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion. @@ -274,4 +274,4 @@ The conversion algorithm is: In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for string conversions that should return a "human-readable" representation of an object, for logging or debugging purposes. -As for math operations, JavaScript doesn't provide a way to "override" them using methods, so real life projects rarely use them on objects. \ No newline at end of file +As for math operations, JavaScript doesn't provide a way to "override" them using methods, so real life projects rarely use them on objects. From 9847492838326ea9c161aebeb1ebb6749bd1f5cd Mon Sep 17 00:00:00 2001 From: Elena Valeeva Date: Sun, 20 Jun 2021 08:12:59 +0300 Subject: [PATCH 26/81] Typo in Ch 15 Functions --- 1-js/02-first-steps/15-function-basics/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md index ac6f1f47c..09ad90dc0 100644 --- a/1-js/02-first-steps/15-function-basics/article.md +++ b/1-js/02-first-steps/15-function-basics/article.md @@ -247,7 +247,7 @@ function showMessage(text) { showMessage(); // empty message ``` -...Or we could use the `??` operator: +...Or we could use the `||` operator: ```js function showMessage(text) { From b19a6f08039b3ba1d2712c3ab7241bf8afbb58b3 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Mon, 21 Jun 2021 23:32:07 +0300 Subject: [PATCH 27/81] minor fixes --- 1-js/02-first-steps/15-function-basics/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md index 09ad90dc0..b46f42924 100644 --- a/1-js/02-first-steps/15-function-basics/article.md +++ b/1-js/02-first-steps/15-function-basics/article.md @@ -181,7 +181,7 @@ In other words, to put these terms straight: We declare functions listing their parameters, then call them passing arguments. -In the example above, one might say: "the function `sayMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`". +In the example above, one might say: "the function `showMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`". ## Default values From 66bad3f50b54e9fb0a0805b82ec20e9556454b6f Mon Sep 17 00:00:00 2001 From: Z Yin Date: Tue, 22 Jun 2021 15:46:50 -0400 Subject: [PATCH 28/81] fix typo in 5-network/02-formdata --- 5-network/02-formdata/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5-network/02-formdata/article.md b/5-network/02-formdata/article.md index a3d924528..a73d554b1 100644 --- a/5-network/02-formdata/article.md +++ b/5-network/02-formdata/article.md @@ -168,7 +168,7 @@ The server reads form data and the file, as if it were a regular form submission [FormData](https://xhr.spec.whatwg.org/#interface-formdata) objects are used to capture HTML form and submit it using `fetch` or another network method. -We can either create `new FormData(form)` from an HTML form, or create a object without a form at all, and then append fields with methods: +We can either create `new FormData(form)` from an HTML form, or create an object without a form at all, and then append fields with methods: - `formData.append(name, value)` - `formData.append(name, blob, fileName)` From d7c2f0819ee6f1c33a34b9c7273993468f371249 Mon Sep 17 00:00:00 2001 From: Z Yin Date: Tue, 22 Jun 2021 17:57:28 -0400 Subject: [PATCH 29/81] Add one letter in 5-network/03-fetch-progress --- 5-network/03-fetch-progress/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5-network/03-fetch-progress/article.md b/5-network/03-fetch-progress/article.md index c0e3d922a..76b05d514 100644 --- a/5-network/03-fetch-progress/article.md +++ b/5-network/03-fetch-progress/article.md @@ -5,7 +5,7 @@ The `fetch` method allows to track *download* progress. Please note: there's currently no way for `fetch` to track *upload* progress. For that purpose, please use [XMLHttpRequest](info:xmlhttprequest), we'll cover it later. -To track download progress, we can use `response.body` property. It's `ReadableStream` -- a special object that provides body chunk-by-chunk, as it comes. Readable streams are described in the [Streams API](https://streams.spec.whatwg.org/#rs-class) specification. +To track download progress, we can use `response.body` property. It's a `ReadableStream` -- a special object that provides body chunk-by-chunk, as it comes. Readable streams are described in the [Streams API](https://streams.spec.whatwg.org/#rs-class) specification. Unlike `response.text()`, `response.json()` and other methods, `response.body` gives full control over the reading process, and we can count how much is consumed at any moment. From c4efc358993545b35a8f814258efe7778223d423 Mon Sep 17 00:00:00 2001 From: Z Yin Date: Wed, 23 Jun 2021 17:56:37 -0400 Subject: [PATCH 30/81] minor grammar change in webcomponents-intro --- 8-web-components/1-webcomponents-intro/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/8-web-components/1-webcomponents-intro/article.md b/8-web-components/1-webcomponents-intro/article.md index 3279cb133..c3522dea9 100644 --- a/8-web-components/1-webcomponents-intro/article.md +++ b/8-web-components/1-webcomponents-intro/article.md @@ -26,9 +26,9 @@ The International Space Station: ...And this thing flies, keeps humans alive in space! -How such complex devices are created? +How are such complex devices created? -Which principles we could borrow to make our development same-level reliable and scalable? Or, at least, close to it. +Which principles could we borrow to make our development same-level reliable and scalable? Or, at least, close to it? ## Component architecture From b855f6c9db21daa8fee761b79ceb879befb75932 Mon Sep 17 00:00:00 2001 From: Z Yin Date: Thu, 24 Jun 2021 12:06:25 -0400 Subject: [PATCH 31/81] add a section about css animation performance --- 7-animation/2-css-animations/article.md | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index 97c75da2b..f66603ac2 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -407,6 +407,53 @@ There are many articles about `@keyframes` and a [detailed specification](https: You probably won't need `@keyframes` often, unless everything is in constant motion on your sites. +## Performance of CSS animations + +Most CSS properties can be animated, because most of them are numeric values. For instance, `width`, `color`, `font-size` are all numbers. When you animate them, the browser gradually changes these numbers frame by frame, creating a smooth effect. + +However, not all animations will look as smooth as you'd like, because different CSS properties cost differently to change. Among all the properties, `transform` and `opacity` are the cheapest to animate, and produce the highest framerate, so in real life projects, you should try to only use these two to achieve your desired effects. + +The reason for this is when something is being _transformed_, the browser engine is able to only worry about changing the look of this one thing, without touching other existing things on the page. Same for opacity change. + +In more technical details, when there's a style change, the browser goes through 3 steps to render the new look: + +1. **Layout**: re-compute the geometry and position of each element, then +2. **Paint**: re-compute how everything should look like, including "layers" which is a big deal, then +3. **Composite**: render the final results into pixels on screen. + +During CSS animation, this process repeats every frame. You can check [how each CSS change triggers these steps](https://csstriggers.com/), and you'll find most changes will trigger ` 1` `2` `3`, while color change only triggers `2` `3`, and transform and opacity only trigger `3`. + +Luckily, `transform` is by far the most useful and most powerful property to animate. By using `transform` on an element, you could rotate and flip it, stretch and shrink it, move it around, and [many more](https://developer.mozilla.org/docs/Web/CSS/transform#syntax). + +Meanwhile, `opacity` can help with show / hide or fade-in / fade-out effects. By paring `transform` with `opacity` you can usually solve all your needs, for example: + +```html run height=80 autorun no-beautify +

click me to start / stop

+ + +``` + +In earlier examples in this chapter, we've animated `font-size`, `left`, `width`, `height`, etc. In real life projects, they could be replaced by `transform: scale()` and `transform: translate()` for better performance. + ## Summary CSS animations allow smoothly (or not) animated changes of one or multiple CSS properties. From c41361f544f233d50a4593d28d3c9454aba4c32c Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 21:49:27 +0300 Subject: [PATCH 32/81] animation --- 7-animation/2-css-animations/article.md | 62 ++++++++++++++++++++----- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index f66603ac2..4736e50dc 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -407,29 +407,67 @@ There are many articles about `@keyframes` and a [detailed specification](https: You probably won't need `@keyframes` often, unless everything is in constant motion on your sites. -## Performance of CSS animations +## Performance Most CSS properties can be animated, because most of them are numeric values. For instance, `width`, `color`, `font-size` are all numbers. When you animate them, the browser gradually changes these numbers frame by frame, creating a smooth effect. -However, not all animations will look as smooth as you'd like, because different CSS properties cost differently to change. Among all the properties, `transform` and `opacity` are the cheapest to animate, and produce the highest framerate, so in real life projects, you should try to only use these two to achieve your desired effects. - -The reason for this is when something is being _transformed_, the browser engine is able to only worry about changing the look of this one thing, without touching other existing things on the page. Same for opacity change. +However, not all animations will look as smooth as you'd like, because different CSS properties cost differently to change. In more technical details, when there's a style change, the browser goes through 3 steps to render the new look: 1. **Layout**: re-compute the geometry and position of each element, then -2. **Paint**: re-compute how everything should look like, including "layers" which is a big deal, then -3. **Composite**: render the final results into pixels on screen. +2. **Paint**: re-compute how everything should look like at their places, including background, colors, +3. **Composite**: render the final results into pixels on screen, apply CSS transforms if they exist. + +During a CSS animation, this process repeats every frame. However, CSS properties that never affect geometry or position, such as `color`, may skip the Layout step. If a `color` changes, the browser doesn't calculate any new geometry, it goes to Paint -> Composite. And there are few properties that directly go to Composite. + +The Layout step is by far the most expensive: geometry calculations take time. And the delays are actually visible on most devices, leading to a bit more "jittery", less fluid animations. + +**The general recomendation is to animate properties that don't do Layout.** + +For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser directly goes to Paint. You can find a longer list of CSS properties and which stages they trigger at . + +The `transform` property is a notable exception: +- CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it). +- CSS transforms never affect neighbour elements. + +So browsers apply `transform` "on top" of existing Layout and Paint calculations, in the Composite stage. + +In other words, the browser calculates the Layout (sizes, positions), paints it with colors, backgrounds, etc at the Paint stage, and then applies `transform` to element boxes that need it. + +Animating the `transform` property never causes Layout and Paint. More than that, the browser leverages the graphics accelerator (a special chip on the CPU or graphics card) for CSS transforms, thus making them very effecient. + +Luckily, the `transform` property is very powerful. By using `transform` on an element, you could rotate and flip it, stretch and shrink it, move it around, and [much more](https://developer.mozilla.org/docs/Web/CSS/transform#syntax). + +The `opacity` property also never causes Layout. We can use it for show / hide or fade-in / fade-out effects. + +Paring `transform` with `opacity` can usually solve most of our needs, providing fluid, good-looking animations. -During CSS animation, this process repeats every frame. You can check [how each CSS change triggers these steps](https://csstriggers.com/), and you'll find most changes will trigger ` 1` `2` `3`, while color change only triggers `2` `3`, and transform and opacity only trigger `3`. +For example, here clicking on the `#boat` element adds the class with `transform: translateX(300)` and `opacity: 0`, thus making it move `300px` to the right and fade out: -Luckily, `transform` is by far the most useful and most powerful property to animate. By using `transform` on an element, you could rotate and flip it, stretch and shrink it, move it around, and [many more](https://developer.mozilla.org/docs/Web/CSS/transform#syntax). +```html run height=260 autorun no-beautify + -Meanwhile, `opacity` can help with show / hide or fade-in / fade-out effects. By paring `transform` with `opacity` you can usually solve all your needs, for example: + + +``` + +Or a more complex example, with `@keyframes`: ```html run height=80 autorun no-beautify

click me to start / stop

- ``` -In earlier examples in this chapter, we've animated `font-size`, `left`, `width`, `height`, etc. In real life projects, they could be replaced by `transform: scale()` and `transform: translate()` for better performance. - ## Summary CSS animations allow smoothly (or not) animated changes of one or multiple CSS properties. @@ -469,6 +505,8 @@ Limitations of CSS animations compared to JavaScript animations: - Not just property changes. We can create new elements in JavaScript as part of the animation. ``` +In earlier examples in this chapter, we animate `font-size`, `left`, `width`, `height`, etc. In real life projects, we should use `transform: scale()` and `transform: translate()` for better performance. + The majority of animations can be implemented using CSS as described in this chapter. And the `transitionend` event allows JavaScript to be run after the animation, so it integrates fine with the code. But in the next chapter we'll do some JavaScript animations to cover more complex cases. From 8b3730be8919e49c42b189ecd8ba097bb873fc91 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 21:59:48 +0300 Subject: [PATCH 33/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index 4736e50dc..b0d7444d7 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -421,7 +421,7 @@ In more technical details, when there's a style change, the browser goes through During a CSS animation, this process repeats every frame. However, CSS properties that never affect geometry or position, such as `color`, may skip the Layout step. If a `color` changes, the browser doesn't calculate any new geometry, it goes to Paint -> Composite. And there are few properties that directly go to Composite. -The Layout step is by far the most expensive: geometry calculations take time. And the delays are actually visible on most devices, leading to a bit more "jittery", less fluid animations. +The Layout step is by far the most expensive: geometry calculations take time, especially on pages with many elements and a complex layout. And the delays are actually visible on most devices, leading to "jittery", less fluid animations. **The general recomendation is to animate properties that don't do Layout.** From 29615889084f6d920488e44b65e2917326b542ff Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 22:00:37 +0300 Subject: [PATCH 34/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index b0d7444d7..bf1bacbbc 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -425,7 +425,7 @@ The Layout step is by far the most expensive: geometry calculations take time, e **The general recomendation is to animate properties that don't do Layout.** -For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser directly goes to Paint. You can find a longer list of CSS properties and which stages they trigger at . +For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint. You can find a longer list of CSS properties and which stages they trigger at . The `transform` property is a notable exception: - CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it). From 753182bb3d214c3cbf622e8089157427119796fe Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 22:00:53 +0300 Subject: [PATCH 35/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index bf1bacbbc..ba4578cdb 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -425,7 +425,7 @@ The Layout step is by far the most expensive: geometry calculations take time, e **The general recomendation is to animate properties that don't do Layout.** -For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint. You can find a longer list of CSS properties and which stages they trigger at . +For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint, or event Composite step. You can find a longer list of CSS properties and which stages they trigger at . The `transform` property is a notable exception: - CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it). From 7d838b345247ffeea87c1fbc8db52046a0e36b6f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 22:00:59 +0300 Subject: [PATCH 36/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index ba4578cdb..59b939a86 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -425,7 +425,7 @@ The Layout step is by far the most expensive: geometry calculations take time, e **The general recomendation is to animate properties that don't do Layout.** -For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint, or event Composite step. You can find a longer list of CSS properties and which stages they trigger at . +For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint, or even Composite step. You can find a longer list of CSS properties and which stages they trigger at . The `transform` property is a notable exception: - CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it). From 32f01fb6b16c39dad616098a22974ace5f8bb762 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 22:41:26 +0300 Subject: [PATCH 37/81] minor fixes --- 7-animation/2-css-animations/article.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index 59b939a86..95ae2927f 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -421,9 +421,9 @@ In more technical details, when there's a style change, the browser goes through During a CSS animation, this process repeats every frame. However, CSS properties that never affect geometry or position, such as `color`, may skip the Layout step. If a `color` changes, the browser doesn't calculate any new geometry, it goes to Paint -> Composite. And there are few properties that directly go to Composite. -The Layout step is by far the most expensive: geometry calculations take time, especially on pages with many elements and a complex layout. And the delays are actually visible on most devices, leading to "jittery", less fluid animations. +The calculations may take time, especially on pages with many elements and a complex layout. And the delays are actually visible on most devices, leading to "jittery", less fluid animations. -**The general recomendation is to animate properties that don't do Layout.** +The animations of properties that skip the Layout and Paint steps are faster. For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint, or even Composite step. You can find a longer list of CSS properties and which stages they trigger at . @@ -435,11 +435,11 @@ So browsers apply `transform` "on top" of existing Layout and Paint calculations In other words, the browser calculates the Layout (sizes, positions), paints it with colors, backgrounds, etc at the Paint stage, and then applies `transform` to element boxes that need it. -Animating the `transform` property never causes Layout and Paint. More than that, the browser leverages the graphics accelerator (a special chip on the CPU or graphics card) for CSS transforms, thus making them very effecient. +Changes (animations) of the `transform` property never cause Layout and Paint steps. More than that, the browser leverages the graphics accelerator (a special chip on the CPU or graphics card) for CSS transforms, thus making them very effecient. Luckily, the `transform` property is very powerful. By using `transform` on an element, you could rotate and flip it, stretch and shrink it, move it around, and [much more](https://developer.mozilla.org/docs/Web/CSS/transform#syntax). -The `opacity` property also never causes Layout. We can use it for show / hide or fade-in / fade-out effects. +The `opacity` property also never causes Layout (also skips Paint in Gecko). We can use it for show / hide or fade-in / fade-out effects. Paring `transform` with `opacity` can usually solve most of our needs, providing fluid, good-looking animations. From 6c15ba465d645a87698a69e6d4200c6808204f0f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 22:50:01 +0300 Subject: [PATCH 38/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index 95ae2927f..424ac846c 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -423,7 +423,7 @@ During a CSS animation, this process repeats every frame. However, CSS propertie The calculations may take time, especially on pages with many elements and a complex layout. And the delays are actually visible on most devices, leading to "jittery", less fluid animations. -The animations of properties that skip the Layout and Paint steps are faster. +The animations of properties that skip the Layout step are faster. It's even better if Paint is skipped too. For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint, or even Composite step. You can find a longer list of CSS properties and which stages they trigger at . From 771aab479df8902f244ebc9b6813ac6f204114da Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 22:50:42 +0300 Subject: [PATCH 39/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index 424ac846c..ebf68c832 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -427,7 +427,7 @@ The animations of properties that skip the Layout step are faster. It's even bet For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint, or even Composite step. You can find a longer list of CSS properties and which stages they trigger at . -The `transform` property is a notable exception: +The `transform` property is special: - CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it). - CSS transforms never affect neighbour elements. From 2eb4251ce92f862f851944a7b9fa19c41f5527f0 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 22:50:53 +0300 Subject: [PATCH 40/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index ebf68c832..424ac846c 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -427,7 +427,7 @@ The animations of properties that skip the Layout step are faster. It's even bet For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser doesn't need to calculate geometry and directly goes to Paint, or even Composite step. You can find a longer list of CSS properties and which stages they trigger at . -The `transform` property is special: +The `transform` property is a notable exception: - CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it). - CSS transforms never affect neighbour elements. From 28112112bf69a253f165bec62d9748d048ac540f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 23:01:26 +0300 Subject: [PATCH 41/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index 424ac846c..671eebd3e 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -431,7 +431,7 @@ The `transform` property is a notable exception: - CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it). - CSS transforms never affect neighbour elements. -So browsers apply `transform` "on top" of existing Layout and Paint calculations, in the Composite stage. +...So browsers apply `transform` "on top" of existing Layout and Paint calculations, in the Composite stage. In other words, the browser calculates the Layout (sizes, positions), paints it with colors, backgrounds, etc at the Paint stage, and then applies `transform` to element boxes that need it. From 27af482dd85ed1d27bbf70185f55d3b4ca31600f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 23:07:35 +0300 Subject: [PATCH 42/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index 671eebd3e..d1dd3516a 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -505,7 +505,7 @@ Limitations of CSS animations compared to JavaScript animations: - Not just property changes. We can create new elements in JavaScript as part of the animation. ``` -In earlier examples in this chapter, we animate `font-size`, `left`, `width`, `height`, etc. In real life projects, we should use `transform: scale()` and `transform: translate()` for better performance. +In early examples in this chapter, we animate `font-size`, `left`, `width`, `height`, etc. In real life projects, we should use `transform: scale()` and `transform: translate()` for better performance. The majority of animations can be implemented using CSS as described in this chapter. And the `transitionend` event allows JavaScript to be run after the animation, so it integrates fine with the code. From 934d32be5b4075007bb838f04966d5063928f1b7 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 23:24:53 +0300 Subject: [PATCH 43/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index d1dd3516a..a34d83335 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -443,7 +443,7 @@ The `opacity` property also never causes Layout (also skips Paint in Gecko). We Paring `transform` with `opacity` can usually solve most of our needs, providing fluid, good-looking animations. -For example, here clicking on the `#boat` element adds the class with `transform: translateX(300)` and `opacity: 0`, thus making it move `300px` to the right and fade out: +For example, here clicking on the `#boat` element adds the class with `transform: translateX(300)` and `opacity: 0`, thus making it move `300px` to the right and disappear: ```html run height=260 autorun no-beautify From 4420427aa2103f1fc576294cbdf5efe2922b879f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 23:25:07 +0300 Subject: [PATCH 44/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index a34d83335..09327b2c6 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -464,7 +464,7 @@ For example, here clicking on the `#boat` element adds the class with `transform ``` -Or a more complex example, with `@keyframes`: +Here's a more complex example, with `@keyframes`: ```html run height=80 autorun no-beautify

click me to start / stop

From e6098157becff196bb4c0c6e85dcd7d67e23af21 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 24 Jun 2021 23:57:34 +0300 Subject: [PATCH 45/81] minor fixes --- 7-animation/2-css-animations/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md index 09327b2c6..f9721e4f1 100644 --- a/7-animation/2-css-animations/article.md +++ b/7-animation/2-css-animations/article.md @@ -467,7 +467,7 @@ For example, here clicking on the `#boat` element adds the class with `transform Here's a more complex example, with `@keyframes`: ```html run height=80 autorun no-beautify -

click me to start / stop

+

click me to start / stop