You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/1-document/08-styles-and-classes/article.md
+35-40Lines changed: 35 additions & 40 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,20 +7,21 @@ There are generally two ways to style an element:
7
7
1. Create a class in CSS and add it: `<div class="...">`
8
8
2. Write properties directly into `style`: `<div style="...">`.
9
9
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.
11
11
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".
13
13
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:
15
15
16
16
```js
17
17
let top =/* complex calculations */;
18
18
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
20
21
elem.style.top= top; // e.g '456px'
21
22
```
22
23
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.
24
25
25
26
## className and classList
26
27
@@ -40,11 +41,11 @@ For instance:
40
41
</body>
41
42
```
42
43
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.
44
45
45
46
There's another property for that: `elem.classList`.
46
47
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.
48
49
49
50
For instance:
50
51
@@ -66,10 +67,10 @@ So we can operate both on the full class string using `className` or on individu
66
67
Methods of `classList`:
67
68
68
69
-`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`.
71
72
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:
73
74
74
75
```html run
75
76
<bodyclass="main page">
@@ -83,7 +84,7 @@ Besides that, `classList` is iterable, so we can list all classes like this:
83
84
84
85
## Element style
85
86
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`.
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:
104
107
105
108
```js
106
109
button.style.MozBorderRadius = '5px';
107
110
button.style.WebkitBorderRadius = '5px';
108
111
```
109
-
110
-
That is: a dash `"-"` becomes an uppercase.
111
112
````
112
113
113
114
## Resetting the style property
@@ -119,13 +120,21 @@ For instance, to hide an element, we can set `elem.style.display = "none"`.
119
120
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 = ""`.
120
121
121
122
```js run
122
-
// if we run this code, the <body> "blinks"
123
+
// if we run this code, the <body> will blink
123
124
document.body.style.display="none"; // hide
124
125
125
126
setTimeout(() =>document.body.style.display="", 1000); // back to normal
126
127
```
127
128
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
+
```
129
138
130
139
````smart header="Full rewrite with `style.cssText`"
131
140
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`:
147
156
</script>
148
157
```
149
158
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.
151
160
152
161
The same can be accomplished by setting an attribute: `div.setAttribute('style', 'color: red...')`.
153
162
````
154
163
155
164
## Mind the units
156
165
157
-
CSS units must be provided in style values.
166
+
Don't forget to add CSS units to values.
158
167
159
168
For instance, we should not set `elem.style.top` to `10`, but rather to `10px`. Otherwise it wouldn't work:
160
169
@@ -177,11 +186,11 @@ For instance, we should not set `elem.style.top` to `10`, but rather to `10px`.
177
186
</body>
178
187
```
179
188
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.
181
190
182
191
## Computed styles: getComputedStyle
183
192
184
-
Modifying a style is easy. But how to *read* it?
193
+
So, modifying a style is easy. But how to *read* it?
185
194
186
195
For instance, we want to know the size, margins, the color of an element. How to do it?
187
196
@@ -207,14 +216,14 @@ For instance, here `style` doesn't see the margin:
207
216
</body>
208
217
```
209
218
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.
211
220
212
221
There's another method for that: `getComputedStyle`.
213
222
214
223
The syntax is:
215
224
216
225
```js
217
-
getComputedStyle(element[, pseudo])
226
+
getComputedStyle(element, [pseudo])
218
227
```
219
228
220
229
element
@@ -223,7 +232,7 @@ element
223
232
pseudo
224
233
: A pseudo-element if required, for instance `::before`. An empty string or no argument means the element itself.
225
234
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.
227
236
228
237
For instance:
229
238
@@ -253,30 +262,16 @@ There are two concepts in [CSS](https://drafts.csswg.org/cssom/#resolved-values)
253
262
254
263
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.
255
264
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.
257
266
```
258
267
259
268
````warn header="`getComputedStyle` requires the full property name"
260
269
We should always ask for the exact property that we want, like `paddingLeft` or `marginTop` or `borderTopWidth`. Otherwise the correct result is not guaranteed.
261
270
262
271
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
-
```
277
272
````
278
273
279
-
```smart header="\"Visited\" links styles are hidden!"
274
+
```smart header="Styles applied to `:visited` links are hidden!"
280
275
Visited links may be colored using `:visited` CSS pseudoclass.
281
276
282
277
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:
299
294
300
295
To read the resolved styles (with respect to all classes, after all CSS is applied and final values are calculated):
301
296
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