Skip to content

Commit 7513df7

Browse files
committed
Update "Styles and classes" article
1 parent 75d4413 commit 7513df7

1 file changed

Lines changed: 35 additions & 40 deletions

File tree

2-ui/1-document/08-styles-and-classes/article.md

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,21 @@ There are generally two ways to style an element:
77
1. Create a class in CSS and add it: `<div class="...">`
88
2. Write properties directly into `style`: `<div style="...">`.
99

10-
CSS is always the preferred way -- not only for HTML, but in JavaScript as well.
10+
JavaScript can modify both classes and `style` properties.
1111

12-
We should only manipulate the `style` property if classes "can't handle it".
12+
We should always prefer CSS classes to `style`. The latter should only be used if classes "can't handle it".
1313

14-
For instance, `style` is acceptable if we calculate coordinates of an element dynamically and want to set them from JavaScript, like this:
14+
For example, `style` is acceptable if we calculate coordinates of an element dynamically and want to set them from JavaScript, like this:
1515

1616
```js
1717
let top = /* complex calculations */;
1818
let left = /* complex calculations */;
19-
elem.style.left = left; // e.g '123px'
19+
20+
elem.style.left = left; // e.g '123px', calculated at run-time
2021
elem.style.top = top; // e.g '456px'
2122
```
2223

23-
For other cases, like making the text red, adding a background icon -- describe that in CSS and then apply the class. That's more flexible and easier to support.
24+
For other cases, like making the text red, adding a background icon -- describe that in CSS and then add the class (JavaScript can do that). That's more flexible and easier to support.
2425

2526
## className and classList
2627

@@ -40,11 +41,11 @@ For instance:
4041
</body>
4142
```
4243

43-
If we assign something to `elem.className`, it replaces the whole strings of classes. Sometimes that's what we need, but often we want to add/remove a single class.
44+
If we assign something to `elem.className`, it replaces the whole string of classes. Sometimes that's what we need, but often we want to add/remove a single class.
4445

4546
There's another property for that: `elem.classList`.
4647

47-
The `elem.classList` is a special object with methods to `add/remove/toggle` classes.
48+
The `elem.classList` is a special object with methods to `add/remove/toggle` a single class.
4849

4950
For instance:
5051

@@ -66,10 +67,10 @@ So we can operate both on the full class string using `className` or on individu
6667
Methods of `classList`:
6768

6869
- `elem.classList.add/remove("class")` -- adds/removes the class.
69-
- `elem.classList.toggle("class")` -- if the class exists, then removes it, otherwise adds it.
70-
- `elem.classList.contains("class")` -- returns `true/false`, checks for the given class.
70+
- `elem.classList.toggle("class")` -- adds the class if it doesn't exist, otherwise removes it.
71+
- `elem.classList.contains("class")` -- checks for the given class, returns `true/false`.
7172

72-
Besides that, `classList` is iterable, so we can list all classes like this:
73+
Besides, `classList` is iterable, so we can list all classes with `for..of`, like this:
7374

7475
```html run
7576
<body class="main page">
@@ -83,7 +84,7 @@ Besides that, `classList` is iterable, so we can list all classes like this:
8384

8485
## Element style
8586

86-
The property `elem.style` is an object that corresponds to what's written in the `"style"` attribute. Setting `elem.style.width="100px"` works as if we had in the attribute `style="width:100px"`.
87+
The property `elem.style` is an object that corresponds to what's written in the `"style"` attribute. Setting `elem.style.width="100px"` works the same as if we had in the attribute `style` a string `width:100px`.
8788

8889
For multi-word property the camelCase is used:
8990

@@ -100,14 +101,14 @@ document.body.style.backgroundColor = prompt('background color?', 'green');
100101
```
101102

102103
````smart header="Prefixed properties"
103-
Browser-prefixed properties like `-moz-border-radius`, `-webkit-border-radius` also follow the same rule, for instance:
104+
Browser-prefixed properties like `-moz-border-radius`, `-webkit-border-radius` also follow the same rule: a dash means upper case.
105+
106+
For instance:
104107
105108
```js
106109
button.style.MozBorderRadius = '5px';
107110
button.style.WebkitBorderRadius = '5px';
108111
```
109-
110-
That is: a dash `"-"` becomes an uppercase.
111112
````
112113

113114
## Resetting the style property
@@ -119,13 +120,21 @@ For instance, to hide an element, we can set `elem.style.display = "none"`.
119120
Then later we may want to remove the `style.display` as if it were not set. Instead of `delete elem.style.display` we should assign an empty string to it: `elem.style.display = ""`.
120121

121122
```js run
122-
// if we run this code, the <body> "blinks"
123+
// if we run this code, the <body> will blink
123124
document.body.style.display = "none"; // hide
124125

125126
setTimeout(() => document.body.style.display = "", 1000); // back to normal
126127
```
127128

128-
If we set `display` to an empty string, then the browser applies CSS classes and its built-in styles normally, as if there were no such `display` property at all.
129+
If we set `style.display` to an empty string, then the browser applies CSS classes and its built-in styles normally, as if there were no such `style.display` property at all.
130+
131+
Also there is a special method for that, `elem.style.removeProperty('style property')`. So, We can remove a property like this:
132+
133+
```js run
134+
document.body.style.background = 'red'; //set background to red
135+
136+
setTimeout(() => document.body.style.removeProperty('background'), 1000); // remove background after 1 second
137+
```
129138

130139
````smart header="Full rewrite with `style.cssText`"
131140
Normally, we use `style.*` to assign individual style properties. We can't set the full style like `div.style="color: red; width: 100px"`, because `div.style` is an object, and it's read-only.
@@ -147,14 +156,14 @@ To set the full style as a string, there's a special property `style.cssText`:
147156
</script>
148157
```
149158

150-
We rarely use it, because such assignment removes all existing styles: it does not add, but replaces them. May occasionally delete something needed. But still can be done for new elements when we know we won't delete something important.
159+
This property is rarely used, because such assignment removes all existing styles: it does not add, but replaces them. May occasionally delete something needed. But we can safely use it for new elements, when we know we won't delete an existing style.
151160

152161
The same can be accomplished by setting an attribute: `div.setAttribute('style', 'color: red...')`.
153162
````
154163
155164
## Mind the units
156165
157-
CSS units must be provided in style values.
166+
Don't forget to add CSS units to values.
158167
159168
For instance, we should not set `elem.style.top` to `10`, but rather to `10px`. Otherwise it wouldn't work:
160169
@@ -177,11 +186,11 @@ For instance, we should not set `elem.style.top` to `10`, but rather to `10px`.
177186
</body>
178187
```
179188
180-
Please note how the browser "unpacks" the property `style.margin` in the last lines and infers `style.marginLeft` and `style.marginTop` (and other partial margins) from it.
189+
Please note: the browser "unpacks" the property `style.margin` in the last lines and infers `style.marginLeft` and `style.marginTop` from it.
181190
182191
## Computed styles: getComputedStyle
183192
184-
Modifying a style is easy. But how to *read* it?
193+
So, modifying a style is easy. But how to *read* it?
185194
186195
For instance, we want to know the size, margins, the color of an element. How to do it?
187196
@@ -207,14 +216,14 @@ For instance, here `style` doesn't see the margin:
207216
</body>
208217
```
209218
210-
...But what if we need, say, to increase the margin by 20px? We would want the current value of it.
219+
...But what if we need, say, to increase the margin by `20px`? We would want the current value of it.
211220
212221
There's another method for that: `getComputedStyle`.
213222
214223
The syntax is:
215224
216225
```js
217-
getComputedStyle(element[, pseudo])
226+
getComputedStyle(element, [pseudo])
218227
```
219228
220229
element
@@ -223,7 +232,7 @@ element
223232
pseudo
224233
: A pseudo-element if required, for instance `::before`. An empty string or no argument means the element itself.
225234
226-
The result is an object with style properties, like `elem.style`, but now with respect to all CSS classes.
235+
The result is an object with styles, like `elem.style`, but now with respect to all CSS classes.
227236
228237
For instance:
229238
@@ -253,30 +262,16 @@ There are two concepts in [CSS](https://drafts.csswg.org/cssom/#resolved-values)
253262
254263
A long time ago `getComputedStyle` was created to get computed values, but it turned out that resolved values are much more convenient, and the standard changed.
255264
256-
So nowadays `getComputedStyle` actually returns the resolved value of the property.
265+
So nowadays `getComputedStyle` actually returns the resolved value of the property, usually in `px` for geometry.
257266
```
258267
259268
````warn header="`getComputedStyle` requires the full property name"
260269
We should always ask for the exact property that we want, like `paddingLeft` or `marginTop` or `borderTopWidth`. Otherwise the correct result is not guaranteed.
261270
262271
For instance, if there are properties `paddingLeft/paddingTop`, then what should we get for `getComputedStyle(elem).padding`? Nothing, or maybe a "generated" value from known paddings? There's no standard rule here.
263-
264-
There are other inconsistencies. As an example, some browsers (Chrome) show `10px` in the document below, and some of them (Firefox) -- do not:
265-
266-
```html run
267-
<style>
268-
body {
269-
margin: 10px;
270-
}
271-
</style>
272-
<script>
273-
let style = getComputedStyle(document.body);
274-
alert(style.margin); // empty string in Firefox
275-
</script>
276-
```
277272
````
278273

279-
```smart header="\"Visited\" links styles are hidden!"
274+
```smart header="Styles applied to `:visited` links are hidden!"
280275
Visited links may be colored using `:visited` CSS pseudoclass.
281276

282277
But `getComputedStyle` does not give access to that color, because otherwise an arbitrary page could find out whether the user visited a link by creating it on the page and checking the styles.
@@ -299,4 +294,4 @@ To change the styles:
299294
300295
To read the resolved styles (with respect to all classes, after all CSS is applied and final values are calculated):
301296
302-
- The `getComputedStyle(elem[, pseudo])` returns the style-like object with them. Read-only.
297+
- The `getComputedStyle(elem, [pseudo])` returns the style-like object with them. Read-only.

0 commit comments

Comments
 (0)