Skip to content

Element size and scrolling #187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
The solution is:
La solution est :

```js
let scrollBottom = elem.scrollHeight - elem.scrollTop - elem.clientHeight;
```

In other words: (full height) minus (scrolled out top part) minus (visible part) -- that's exactly the scrolled out bottom part.
En d'autres termes : (pleine hauteur) moins (partie supérieure déroulée) moins (partie visible) -- c'est exactement la partie inférieure déroulée.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ importance: 5

---

# What's the scroll from the bottom?
# Quel est le défilement à partir du bas ?

The `elem.scrollTop` property is the size of the scrolled out part from the top. How to get the size of the bottom scroll (let's call it `scrollBottom`)?
La propriété `elem.scrollTop` est la taille de la partie déroulante à partir du haut. Comment obtenir la taille du défilement inférieur (appelons-le `scrollBottom`) ?

Write the code that works for an arbitrary `elem`.
Écrivez le code qui fonctionne pour un `element` arbitraire.

P.S. Please check your code: if there's no scroll or the element is fully scrolled down, then it should return `0`.
P.S. Veuillez vérifier votre code: s'il n'y a pas de défilement ou que l'élément est entièrement défilé vers le bas, alors il devrait retourner `0`.
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
To get the scrollbar width, we can create an element with the scroll, but without borders and paddings.
Pour obtenir la largeur de la barre de défilement, nous pouvons créer un élément avec le défilement, mais sans bordures ni paddings.

Then the difference between its full width `offsetWidth` and the inner content area width `clientWidth` will be exactly the scrollbar:
Ensuite, la différence entre sa largeur totale `offsetWidth` et la largeur de la zone de contenu interne `clientWidth` sera exactement la barre de défilement :

```js run
// create a div with the scroll
// créer une div avec le défilement
let div = document.createElement('div');

div.style.overflowY = 'scroll';
div.style.width = '50px';
div.style.height = '50px';

// must put it in the document, otherwise sizes will be 0
// doit le mettre dans le document, sinon les tailles seront 0
document.body.append(div);
let scrollWidth = div.offsetWidth - div.clientWidth;

Expand Down
8 changes: 4 additions & 4 deletions 2-ui/1-document/09-size-and-scroll/2-scrollbar-width/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ importance: 3

---

# What is the scrollbar width?
# Quelle est la largeur de la barre de défilement ?

Write the code that returns the width of a standard scrollbar.
Écrivez le code qui renvoie la largeur d'une barre de défilement standard.

For Windows it usually varies between `12px` and `20px`. If the browser doesn't reserve any space for it (the scrollbar is half-translucent over the text, also happens), then it may be `0px`.
Pour Windows, il varie généralement entre `12px` et `20px`. Si le navigateur ne lui réserve pas d'espace (la barre de défilement est à moitié translucide sur le texte, cela arrive également), alors il peut s'agir de `0px`.

P.S. The code should work for any HTML document, do not depend on its content.
P.S. Le code devrait fonctionner pour tout document HTML, ne dépend pas de son contenu.
28 changes: 14 additions & 14 deletions 2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
The ball has `position:absolute`. It means that its `left/top` coordinates are measured from the nearest positioned element, that is `#field` (because it has `position:relative`).
La balle a une `position:absolue`. Cela signifie que ses coordonnées `gauche/haut` sont mesurées à partir de l'élément positionné le plus proche, c'est-à-dire `#field` (car il a `position:relative`).

The coordinates start from the inner left-upper corner of the field:
Les coordonnées commencent à partir du coin supérieur gauche intérieur du champ :

![](field.svg)

The inner field width/height is `clientWidth/clientHeight`. So the field center has coordinates `(clientWidth/2, clientHeight/2)`.
La largeur/hauteur du champ intérieur est `clientWidth/clientHeight`. Le centre de terrain a donc les coordonnées `(clientWidth/2, clientHeight/2)`.

...But if we set `ball.style.left/top` to such values, then not the ball as a whole, but the left-upper edge of the ball would be in the center:
...Mais si nous définissons `ball.style.left/top` à de telles valeurs, alors pas la balle dans son ensemble, mais le bord supérieur gauche de la balle serait au centre :

```js
ball.style.left = Math.round(field.clientWidth / 2) + 'px';
ball.style.top = Math.round(field.clientHeight / 2) + 'px';
```

Here's how it looks:
Voici à quoi ça ressemble :

[iframe height=180 src="ball-half"]

To align the ball center with the center of the field, we should move the ball to the half of its width to the left and to the half of its height to the top:
Pour aligner le centre de la balle avec le centre du terrain, nous devons déplacer la balle sur la moitié de sa largeur à gauche et sur la moitié de sa hauteur vers le haut :

```js
ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px';
ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px';
```

Now the ball is finally centered.
Maintenant, la balle est enfin centrée.

````warn header="Attention: the pitfall!"
````warn header="Attention : l'écueil !"

The code won't work reliably while `<img>` has no width/height:
Le code ne fonctionnera pas de manière fiable tant que `<img>` n'a pas de largeur/hauteur :

```html
<img src="ball.png" id="ball">
```
````

When the browser does not know the width/height of an image (from tag attributes or CSS), then it assumes them to equal `0` until the image finishes loading.
Lorsque le navigateur ne connaît pas la largeur/hauteur d'une image (à partir des attributs de balise ou CSS), il suppose qu'ils sont égaux à `0` jusqu'à ce que le chargement de l'image soit terminé.

So the value of `ball.offsetWidth` will be `0` until the image loads. That leads to wrong coordinates in the code above.
Ainsi, la valeur de `ball.offsetWidth` sera `0` jusqu'à ce que l'image se charge. Cela conduit à de mauvaises coordonnées dans le code ci-dessus.

After the first load, the browser usually caches the image, and on reloads it will have the size immediately. But on the first load the value of `ball.offsetWidth` is `0`.
Après le premier chargement, le navigateur met généralement l'image en cache et lors des rechargements, elle aura immédiatement la taille. Mais lors du premier chargement, la valeur de `ball.offsetWidth` est `0`.

We should fix that by adding `width/height` to `<img>`:
Nous devons corriger cela en ajoutant `width/height` à `<img>` :

```html
<img src="ball.png" *!*width="40" height="40"*/!* id="ball">
```

...Or provide the size in CSS:
...Ou indiquez la taille en CSS :

```css
#ball {
Expand Down
14 changes: 7 additions & 7 deletions 2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ importance: 5

---

# Place the ball in the field center
# Placer la balle au centre du terrain

Here's how the source document looks:
Voici à quoi ressemble le document source :

[iframe src="source" edit link height=180]

What are coordinates of the field center?
Quelles sont les coordonnées du centre de terrain ?

Calculate them and use to place the ball into the center of the green field:
Calculez et utilisez-les pour placer la balle au centre du champ vert :

[iframe src="solution" height=180]

- The element should be moved by JavaScript, not CSS.
- The code should work with any ball size (`10`, `20`, `30` pixels) and any field size, not be bound to the given values.
- L'élément doit être déplacé par JavaScript, pas CSS.
- Le code doit fonctionner avec n'importe quelle taille de boule (`10`, `20`, `30` pixels) et n'importe quelle taille de champ, ne pas être lié aux valeurs données.

P.S. Sure, centering could be done with CSS, but here we want exactly JavaScript. Further we'll meet other topics and more complex situations when JavaScript must be used. Here we do a "warm-up".
P.S. Bien sûr, le centrage pourrait être effectué avec CSS, mais ici, nous voulons exactement JavaScript. De plus, nous rencontrerons d'autres sujets et des situations plus complexes lorsque JavaScript doit être utilisé. Ici, nous faisons un "échauffement".
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Differences:
Différences :

1. `clientWidth` is numeric, while `getComputedStyle(elem).width` returns a string with `px` at the end.
2. `getComputedStyle` may return non-numeric width like `"auto"` for an inline element.
3. `clientWidth` is the inner content area of the element plus paddings, while CSS width (with standard `box-sizing`) is the inner content area *without paddings*.
4. If there's a scrollbar and the browser reserves the space for it, some browser substract that space from CSS width (cause it's not available for content any more), and some do not. The `clientWidth` property is always the same: scrollbar size is substracted if reserved.
1. `clientWidth` est numérique, tandis que `getComputedStyle(elem).width` renvoie une chaîne de caractères avec `px` à la fin.
2. `getComputedStyle` peut renvoyer une largeur non numérique comme `"auto"` pour un élément inline.
3. `clientWidth` est la zone de contenu interne de l'élément plus les paddings, tandis que la largeur CSS (avec le `box-sizing` standard ) est la zone de contenu interne *sans les paddings*.
4. S'il y a une barre de défilement et que le navigateur lui réserve de l'espace, certains navigateurs soustraient cet espace de la largeur CSS (car il n'est plus disponible pour le contenu), et d'autres non. La propriété `clientWidth` est toujours la même : la taille de la barre de défilement est soustraite si elle est réservée.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ importance: 5

---

# The difference: CSS width versus clientWidth
# La différence: largeur CSS vs clientWidth

What's the difference between `getComputedStyle(elem).width` and `elem.clientWidth`?
Quelle est la différence entre `getComputedStyle(elem).width` et `elem.clientWidth` ?

Give at least 3 differences. The more the better.
Donnez au moins 3 différences. Plus c'est mieux.
Loading