Skip to content

Element size and scrolling #279

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 16 commits into from
Apr 5, 2021
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 soluzione è:

```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.
In altre parole: (altezza totale) meno (misura dello scorrimento dall'alto) meno (altezza dell'area di scorrimento visibile). Il risultato è esattamente la misura della parte inferiore che resta da scorrere.
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?
# Qual è la misura dello scorrimento verso il basso?

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 proprietà `elem.scrollTop` è la misura della parte superiore di un elemento fuori dall'area di scorrimento. Come ottenere la misura della parte inferiore (chiamiamola `scrollBottom`)?

Write the code that works for an arbitrary `elem`.
Scrivete il codice che funzioni per un elemento arbitrario `elem`.

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. Verificate il vostro codice: se non c'è scorrimento o è stato effettuato tutto lo scorrimento verso il basso, allora dovrebbe restituire `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.
Per ricavare la larghezza della barra di scorrimento, possiamo creare un elemento con scorrimento ma senza bordi e padding.

Then the difference between its full width `offsetWidth` and the inner content area width `clientWidth` will be exactly the scrollbar:
In quel caso la sottrazione tra la larghezza totale `offsetWidth` e la larghezza dell'area interna del contenuto `clientWidth` equivarrà esattamente alla larghezza della barra di scorrimento:

```js run
// create a div with the scroll
// creiamo un div con scorrimento
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
// dobbiamo inserirlo nel flusso del documento, altrimenti le dimensioni saranno pari a 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?
# Qual è la larghezza della barra di scorrimento?

Write the code that returns the width of a standard scrollbar.
Scrivete il codice che restituisca la larghezza di una barra di scorrimento 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`.
Per Windows solitamente varia tra `12px` e `20px`. Se il browser non le riserva alcuno spazio (capita che la barra di scorrimento appaia semi-opaca sopra il testo), allora può essere `0px`.

P.S. The code should work for any HTML document, do not depend on its content.
P.S. Il codice dovrebbe funzionare per ogni documento HTML indipendentemente dal contenuto.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
let ball = document.getElementById('ball')
let field = document.getElementById('field')

// ball.offsetWidth=0 before image loaded!
// to fix: set width
// prima che l'immagine sia caricata ball.offsetWidth=0!
// per correggere: imposta le dimensioni
ball.style.left = Math.round(field.clientWidth / 2) + 'px'
ball.style.top = Math.round(field.clientHeight / 2) + 'px'
</script>
Expand Down
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 palla ha `position:absolute`. Ciò significa che le coordinate `left/top` sono relative all'elemento posizionato più prossimo, cioè `#field` (perché ha `position:relative`).

The coordinates start from the inner left-upper corner of the field:
Le coordinate sono a partire dall'angolo interno superiore sinistro del campo:

![](field.svg)

The inner field width/height is `clientWidth/clientHeight`. So the field center has coordinates `(clientWidth/2, clientHeight/2)`.
Le dimensioni interne del campo si calcolano con `clientWidth/clientHeight`. I valori delle coordinate del centro del campo, quindi, si ottengono con `(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:
...Ma se impostiamo tali valori per `ball.style.left/top`, allora si troverebbe al centro non la palla ma il suo bordo superiore sinistro:

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

Here's how it looks:
Ecco cosa otterremmo:

[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:
Per allineare il centro della palla con il centro del campo, dovremmo spostare la palla alla metà della sua larghezza a sinistra ed alla metà della sua altezza verso l'alto:

```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.
Adesso la palla è finalmente centrata.

````warn header="Attention: the pitfall!"
````warn header="Attenzione: c'è una difficoltà imprevista!"

The code won't work reliably while `<img>` has no width/height:
Il codice non funzionerà in modo affidabile finché `<img>` non avrà larghezza ed altezza definite:

```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.
Quando il browser non conosce le dimensioni di un'immagine (dagli attributi del tag o dai CSS), allora assume che siano pari a `0` finché l'immagine non completa il caricamento.

So the value of `ball.offsetWidth` will be `0` until the image loads. That leads to wrong coordinates in the code above.
Pertanto il valore di `ball.offsetWidth` sarà `0` fino al momento in cui l'immagine non viene caricata. Questo causerà coordinate errate nel codice sopra.

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`.
Dopo il primo caricamento, il browser solitamente mette in cache l'immagine, e ne ricorderà subito le dimensioni se la dovesse ricaricare. Al primo caricamento, tuttavia, il valore di `ball.offsetWidth` è `0`.

We should fix that by adding `width/height` to `<img>`:
Dovremmo correggere aggiungendo `width/height` a `<img>`:

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

...Or provide the size in CSS:
...o fornire le dimensioni nei CSS:

```css
#ball {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@


<script>
// ball.offsetWidth=0 before image loaded!
// to fix: set width
// prima che l'immagine sia caricata ball.offsetWidth=0!
// per correggere: imposta le dimensioni
ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px'
ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px'
</script>
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
# Posiziona la palla al centro del campo

Here's how the source document looks:
Ecco come si presenta il documento di partenza:

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

What are coordinates of the field center?
Quali sono le coordinate del centro del campo?

Calculate them and use to place the ball into the center of the green field:
Calcolale e usale per posizionare la palla al centro del campo verde:

[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'elemento dovrebbe essere spostato con JavaScript, non con i CSS.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- L'elemento dovrebbe essere spostato con JavaScript, non con i CSS.
- L'elemento dovrebbe essere spostato con JavaScript, non con CSS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm credo che di averlo sempre trovato con l'articolo in italiano, io lo lascerei così

- Il codice dovrebbe funzionare anche con una dimensione della palla differente (`10`, `20`, `30` pixel) e qualunque dimensione del campo: non dovrebbe essere legato a valori noti.

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. Certamente, il posizionamento al centro potrebbe essere ottenuto con i CSS, ma qui vi chiediamo di farlo proprio con JavaScript. Più avanti incontreremo altri casi e situazioni più complesse in cui JavaScript è l'unica alternativa. Ora ci stiamo solo "scaldando".
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
P.S. Certamente, il posizionamento al centro potrebbe essere ottenuto con i CSS, ma qui vi chiediamo di farlo proprio con JavaScript. Più avanti incontreremo altri casi e situazioni più complesse in cui JavaScript è l'unica alternativa. Ora ci stiamo solo "scaldando".
P.S. Certamente, il posizionamento al centro potrebbe essere ottenuto con CSS, ma qui vi chiediamo di farlo proprio con JavaScript. Più avanti incontreremo altri casi e situazioni più complesse in cui JavaScript è l'unica alternativa. Ora ci stiamo solo "scaldando".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm credo che di averlo sempre trovato con l'articolo in italiano, io lo lascerei così

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Differences:
Differenze:

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` è un valore numerico, `getComputedStyle(elem).width` invece restituisce una stringa con `px` alla fine.
2. `getComputedStyle` può restituire una larghezza non numerica come `"auto"` per un elemento inline.
3. `clientWidth` è l'area del contenuto interna di un elemento più il padding, mentre la proprietà width dei CSS (con il valore predefinito di `box-sizing`) è l'area del contenuto interna *senza il padding*.
4. Se c'è una barra di scorrimento ed il browser le riserva uno spazio, alcuni browser sottraggono quello spazio alla larghezza impostata tramite CSS (perché non è più disponibile per i contenuti), e altri invece no. La proprietà `clientWidth` è sempre la stessa: se la barra di scorrimento ha uno spazio riservato viene sottratto all'area del contenuto.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ importance: 5

---

# The difference: CSS width versus clientWidth
# Indica le differenze tra la proprietà width CSS e clientWidth

What's the difference between `getComputedStyle(elem).width` and `elem.clientWidth`?
Quali sono le differenze tra `getComputedStyle(elem).width` e `elem.clientWidth`?

Give at least 3 differences. The more the better.
Indica almeno 3 differenze. Più sono meglio è.
Loading