diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md index 79966ecfb..57f354a90 100644 --- a/2-ui/1-document/08-styles-and-classes/article.md +++ b/2-ui/1-document/08-styles-and-classes/article.md @@ -1,35 +1,35 @@ # Стилі та класи -Перед тим як перейти до того, як JavaScript взаємодіє зі стилями й класами, є одне важливе правило. Сподіваємося, воно достатньо очевидне, проте його все одно необхідно згадати. +Перед тим як перейти до того, як JavaScript взаємодіє зі стилями та класами, є одне важливе правило. Сподіваємося, воно достатньо очевидне, проте ми все одно повинні це згадати. -Загалом існує два способи стилізувати елемент: +Загалом існує два способи стилізації елемента: -1. Створити клас в CSS і додати його до елемента: `
` +Створити клас в CSS і додати його до елемента: `
` 2. Записати правила безпосередньо в атрибут `style`: `
`. JavaScript дозволяє змінювати як класи, так і `style` властивості. -Завжди слід надавати перевагу CSS-класам замість `style`. Останній варто використовувати лише у тих випадках, які не можна обробити за допомогою класів. +Зазвичай ми маємо віддавати перевагу CSS-класам над `style`. Пряме задання стилів слід використовувати лише в тих випадках, якщо класи "не можуть з цим впоратися". -Для прикладу, допустимо використовувати `style`, якщо ми обраховуємо координати елемента динамічно, і ми хочемо встановлювати їх через JavaScript, як от: +Для прикладу, допустимо використовувати `style`, якщо ми динамічно обчислюємо координати елемента та хочемо встановлювати їх через JavaScript, як от: ```js let top = /* складні обрахунки */; let left = /* складні обрахунки */; -elem.style.left = left; // наприклад, '123px', обраховано на ходу +elem.style.left = left; // наприклад, '123px', розраховується під час виконання elem.style.top = top; // наприклад '456px' ``` -В інших випадках (зробити текст червоним, чи додати іконку на тлі тощо) -- просто опишіть це в CSS і потім додайте клас (JavaScript з цим прекрасно справиться). Такий підхід більш гнучкий, і простіший у підтримці. +В інших випадках, як-от зробити текст червоним або додати іконку на фон -- опишіть це в CSS, а потім додайте клас (JavaScript легко з цим впорається). Такий підхід більш гнучкий, і простіший у підтримці. -## Властивості className та classList +## className та classList -Зміна класу -- це одна з найчастіше вживаних дій у скриптах. +Зміна класу є однією з найчастіше використовуваних дій у скриптах. -В давні часи JavaScript мав певні обмеження: зарезервоване слово, таке як `"class"`, не могло бути властивістю об’єкта. Цього обмеження наразі більше не існує, проте на той час було неможливо мати властивість `"class"`, як от `elem.class`. +В давні часи JavaScript мав певні обмеження: зарезервоване слово, таке як `"class"`, не могло бути властивістю об’єкта. Цього обмеження наразі більше немає, проте на той час було неможливо мати властивість `"class"`, як от `elem.class`. -Тому для класів було додано схожу властивість `"className"`: `elem.className` відповідає атрибуту `"class"`. +Тому для класів було додано схожу на вигляд властивість `"className"`: `elem.className` відповідає атрибуту `"class"`. Наприклад: @@ -41,7 +41,7 @@ elem.style.top = top; // наприклад '456px' ``` -Коли ми присвоюємо щось властивості `elem.className`, це значення замінює весь рядок з класами. Інколи це саме те, що потрібно, проте значно частіше ми хочемо просто додати чи видалити один клас. +Коли ми присвоюємо щось властивості `elem.className`, це значення замінює весь рядок класів. Інколи це саме те, що нам потрібно, проте значно частіше ми хочемо просто додати чи видалити один клас. Для цього існує інша властивість, а саме `elem.classList`. @@ -67,8 +67,8 @@ elem.style.top = top; // наприклад '456px' Методи `classList`: - `elem.classList.add/remove("class")` -- додати/видалити клас. -- `elem.classList.toggle("class")` -- додає клас, якщо він не існує, а інакше -- видаляє його. -- `elem.classList.contains("class")` -- перевіряє, чи переданий клас існує, відповідно повертає `true/false`. +- `elem.classList.toggle("class")` -- додає клас, якщо він не існує, інакше видаляє його. +- `elem.classList.contains("class")` -- перевіряє, чи існує переданий клас, відповідно повертає `true/false`. Крім того, `classList` -- це ітерований об’єкт, тому можна легко вивести перелік всіх класів циклом `for..of`, як показано далі: @@ -82,11 +82,11 @@ elem.style.top = top; // наприклад '456px' ``` -## Стиль елементу +## Стилі елемента Властивість `elem.style` -- це об’єкт, вміст якого відповідає тому, що записано в атрибуті `"style"`. Встановлення `elem.style.width="100px"` працює точнісінько так само, як рядок `width:100px` записаний в атрибут `style`. -Для властивостей, які називаються кількома словами, використовується верблюдячийРегістр: +Для властивостей, які називаються кількома словами, використовується верблюдячий регістр (camelCase): ```js no-beautify background-color => elem.style.backgroundColor @@ -101,7 +101,7 @@ document.body.style.backgroundColor = prompt('background color?', 'green'); ``` ````smart header="Властивості з префіксами" -Властивості з браузерними префіксами -- наприклад, `-moz-border-radius`, `-webkit-border-radius` -- також підпорядковуються цьому правилу: дефіс означає верхній регістр. +Властивості з браузерними префіксами -- наприклад, `-moz-border-radius`, `-webkit-border-radius` також підпорядковуються цьому правилу: дефіс означає верхній регістр. Наприклад: @@ -111,13 +111,13 @@ button.style.WebkitBorderRadius = '5px'; ``` ```` -## Скидання значення стильової властивості +## Скидання властивості в elem.style -Інколи потрібно призначити певну стильову властивість, а пізніше видалити її. +Інколи ми хочемо призначити певну стильову властивість, а пізніше видалити її. -Наприклад, щоб сховати елемент, можна встановити властивість `elem.style.display = "none"`. +Наприклад, щоб приховати елемент, ми можемо встановити властивість `elem.style.display = "none"`. -Потім може виникнути потреба видалити `style.display` так, як наче вона не була встановлена. Замість використання інструкції `delete elem.style.display` слід присвоїти їй порожній рядок: `elem.style.display = ""`. +Потім може виникнути потреба видалити `style.display` так, як наче вона не була встановлена. Замість `delete elem.style.display` ми повинні присвоїти їй порожній рядок: `elem.style.display = ""`. ```js run // якщо ми запустимо цей код, елемент "моргне" @@ -126,9 +126,9 @@ document.body.style.display = "none"; // сховати setTimeout(() => document.body.style.display = "", 1000); // назад до нормального стану ``` -Якщо ми встановлюємо порожній рядок значенням властивості `style.display`, то браузер звичайним чином застосовує CSS-класи і його вбудовані стилі, так, наче тут взагалі не було такої властивості `style.display`. +Якщо ми встановлюємо для `style.display` порожній рядок, то браузер застосовує CSS-класи та свої вбудовані стилі нормально, ніби такої властивості як `style.display` взагалі не було. -Також для цього є спеціальний метод, `elem.style.removeProperty('style property')`. Отже, ми можемо видалити таку властивість: +Також для цього існує спеціальний метод `elem.style.removeProperty('style property')`. Отже, ми можемо видалити таку властивість наступним чином: ```js run document.body.style.background = 'red'; // ставить колір red до background @@ -137,7 +137,7 @@ setTimeout(() => document.body.style.removeProperty('background'), 1000); // в ``` ````smart header="Повний перезапис за допомогою `style.cssText`" -Зазвичай, `style.*` використовується для встановлення окремих властивостей стилю. Немає можливості задати весь стиль, як от `div.style="color: red; width: 100px"`, оскільки `div.style` -- це об’єкт, і він придатний лише для читання. +Зазвичай, `style.*` використовується для встановлення окремих властивостей стилю. Немає можливості задати весь стиль, як от `div.style="color: red; width: 100px"`, оскільки `div.style` -- це об’єкт, і він доступний лише для читання. Існує спеціальна властивість `style.cssText`, яка дає змогу встановлювати повний стиль елемента як рядок: @@ -156,7 +156,7 @@ setTimeout(() => document.body.style.removeProperty('background'), 1000); // в ``` -Ця властивість рідко використовується, оскільки присвоєння стилів у такий спосіб видаляє всі наявні стилі: тобто воно не додає стилі, а радше заміняє їх. Може випадково видалити щось важливе. Однак можна спокійно використовувати її для нових елементів, коли наперед відомо, що там немає ніяких наявних стилів, які можна було б випадково видалити. +Ця властивість рідко використовується, оскільки присвоєння стилів у такий спосіб видаляє всі наявні стилі: тобто воно не додає, а замінює їх. Може випадково видалити щось потрібне. Однак можна спокійно використовувати її для нових елементів, коли наперед відомо, що там немає ніяких наявних стилів, які можна було б випадково видалити. Того самого можна досягнути шляхом встановлення значення атрибута: `div.setAttribute('style', 'color: red...')`. ```` @@ -165,7 +165,7 @@ setTimeout(() => document.body.style.removeProperty('background'), 1000); // в Не забувайте додавати одиниці вимірювання CSS до значень. -Наприклад, не слід встановлювати значення `10` властивості `elem.style.top`, проте радше `10px`. Інакше воно не працюватиме: +Наприклад, ми повинні встановлювати `elem.style.top` не на `10`, а на `10px`. Інакше воно не працюватиме: ```html run height=100 @@ -190,13 +190,13 @@ setTimeout(() => document.body.style.removeProperty('background'), 1000); // в ## Обчислені стилі: getComputedStyle -Отже, змінити стиль -- це легко. Проте як його *прочитати*? +Отже, змінити стиль легко. Проте як його *прочитати*? Уявімо собі, що ми хочемо дізнатися розміри, зовнішні відступи, та колір елементу. Як це зробити? -**Властивість `style` працює лише зі значенням атрибута `"style"`, без врахування каскадності CSS.** +**Властивість `style` працює лише зі значенням атрибута `"style"`, без врахування CSS-каскаду.** -Тобто за допомогою `elem.style` неможливо прочитати щось, що прийшло з CSS-класів. +Тобто за допомогою `elem.style` неможливо прочитати щось, що прийшло з CSS-класів. Наприклад, ось тут властивість `style` не бачить зовнішніх відступів: @@ -218,7 +218,7 @@ setTimeout(() => document.body.style.removeProperty('background'), 1000); // в ...Але що робити, якщо ми хочемо, скажімо, збільшити розмір зовнішнього відступу на `20px`? Для цього нам потрібно знати актуальне значення. -Для цього існує інший метод, а саме -- `getComputedStyle`. +Для цього існує інший метод: `getComputedStyle`. Синтаксис виглядає так: @@ -254,25 +254,25 @@ pseudo ``` -```smart header="Обчислені (computed) і вирішені (resolved) значення властивостей" +```smart header="Обчислені (computed) і кінцеві (resolved) значення властивостей" [CSS](https://drafts.csswg.org/cssom/#resolved-values) має дві концепції: 1. *Обчислене* (*computed*) значення стилю -- це значення після застосування всіх CSS-правил і наслідування, результат CSS-каскаду. Воно може виглядати як `height:1em` чи `font-size:125%`. -2. *Вирішене* (*resolved*) значення стилю -- це значення, яке безпосередньо застосовується до елементу. Такі значення, як `1em` чи `125%` -- відносні. Браузер бере обчислене значення, і перераховує все у фіксованих і абсолютних одиницях, наприклад: `height:20px` чи `font-size:16px`. Для геометричних властивостей вирішені значення можуть бути числами з рухомою комою, як от `width:50.5px`. +2. *Кінцеве* (*resolved*) значення стилю -- це значення, яке безпосередньо застосовується до елементу. Такі значення, як `1em` чи `125%` -- відносні. Браузер бере обчислене значення, і перераховує все у фіксованих і абсолютних одиницях, наприклад: `height:20px` чи `font-size:16px`. Для геометричних властивостей кінцеві значення можуть бути числами з рухомою комою, як от `width:50.5px`. -Колись давно метод `getComputedStyle` був створений саме для отримання обчислених значень, проте вирішені значення виявились значно зручнішими, тому стандарт було змінено. +Колись давно метод `getComputedStyle` був створений саме для отримання обчислених значень, проте кінцеві значення виявились значно зручнішими, тому стандарт було змінено. -Тому станом на сьогодні метод `getComputedStyle` насправді повертає вирішене значення властивості, для геометрії зазвичай виражене в `px`. +Тому станом на сьогодні метод `getComputedStyle` насправді повертає кінцеве значення властивості, для геометрії зазвичай виражене в `px`. ``` ````warn header="`getComputedStyle` вимагає повної назви властивості" Слід завжди запитувати точну назву властивості, значення якої потрібно отримати, як `paddingLeft`, `marginTop` чи `borderTopWidth`. Інакше коректний результат не гарантовано. -Наприклад, якщо на елементі задано властивості `paddingLeft/paddingTop`, що ми отримаємо, запитавши значення `getComputedStyle(elem).padding`? Нічого, чи може якесь "згенероване" значення наявних полів? Тут немає жодного стандартного правила. +Наприклад, якщо на елементі задано властивості `paddingLeft/paddingTop`, що ми отримаємо, запитавши значення `getComputedStyle(elem).padding`? Нічого, чи може якесь "згенероване" значення наявних полів? Стандарту для цього не існує. ```` ```smart header="Стилі, які застосовані на `:visited` (відвідані) посилання -- приховуються!" -Відвідані посилання можна забарвлювати, використовуючи CSS-псевдоклас `:visited`. +Відвідані посилання можна пофарбувати, використовуючи CSS-псевдоклас `:visited`. Проте метод `getComputedStyle` не дає доступу до цього кольору, бо інакше будь-яка вебсторінка могла б визначити, чи користувач відвідував якесь посилання, просто створивши це посилання на сторінці та перевіривши його стилі. @@ -288,10 +288,10 @@ JavaScript не бачить стилі, застосовані через се Для зміни стилів: -- Властивість `style` -- об’єкт зі стилями, записаними верблюдячимРегістром. Читання і запис у неї має такий самий зміст, як і модифікація окремих властивостей в атрибуті `"style"`. Щоб побачити, як застосовується `important` та інші рідкісні речі -- на [MDN](mdn:api/CSSStyleDeclaration) описано перелік методів. +- Властивість `style` -- об’єкт зі стилями, записаними верблюдячим регістром (camelCase). Читання і запис у неї має такий самий зміст, як і модифікація окремих властивостей в атрибуті `"style"`. Щоб побачити, як застосовується `important` та інші рідкісні речі -- на [MDN](mdn:api/CSSStyleDeclaration) описано перелік методів. - Властивість `style.cssText` показує атрибут `"style"` в цілому, весь рядок стилів. -Для зчитування вирішених стилів (з врахуванням всіх класів, після застосування всього CSS і обчислення остаточних значень): +Для зчитування кінцевих стилів (з врахуванням всіх класів, після застосування всього CSS і обчислення остаточних значень): -- Метод `getComputedStyle(elem, [pseudo])` повертає об’єкт, подібний до властивості `style`, з вирішеними значеннями. Виключно для читання. +- Метод `getComputedStyle(elem, [pseudo])` повертає об’єкт, подібний до властивості `style`, з кінцевими значеннями. Виключно для читання.