diff --git a/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/solution.md b/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/solution.md deleted file mode 100644 index 204d4c0c..00000000 --- a/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/solution.md +++ /dev/null @@ -1,41 +0,0 @@ -Есть два варианта. - -1. Можно использовать свойство `elem.style.cssText` и присвоить стиль в текстовом виде. При этом все присвоенные ранее свойства `elem.style` будут удалены. -2. Можно назначить подсвойства `elem.style` одно за другим. Этот способ более безопасен, т.к. меняет только явно присваемые свойства. - -Мы выберем второй путь. - -**Описание CSS-свойств:** - -```css -.button { - -moz-border-radius: 8px; - -webkit-border-radius: 8px; - border-radius: 8px; - border: 2px groove green; - display: block; - height: 30px; - line-height: 30px; - width: 100px; - text-decoration: none; - text-align: center; - color: red; - font-weight: bold; -} -``` - -`*-border-radius` -: Добавляет скругленные углы. Свойство присваивается в вариантах для Firefox `-moz-...`, Chrome/Safari `-webkit-...` и стандартное CSS3-свойство для тех, кто его поддерживает (Opera). - -`display` -: По умолчанию, у `A` это свойство имеет значение `display: inline`. - -`height`, `line-height` -: Устанавливает высоту и делает текст вертикально центрированным путем установки `line-height` в значение, равное высоте. Такой способ центрирования текста работает, если он состоит из одной строки. - -`text-align` -: Центрирует текст горизонтально. - -`color`, `font-weight` -: Делает текст красным и жирным. - diff --git a/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/solution.view/index.html b/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/solution.view/index.html deleted file mode 100755 index bf487e59..00000000 --- a/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/solution.view/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - -
- Кнопка: - -
- - - - - - - \ No newline at end of file diff --git a/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/source.view/index.html b/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/source.view/index.html deleted file mode 100755 index 3492198b..00000000 --- a/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/source.view/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - -
- Кнопка: - -
- - - - - - - \ No newline at end of file diff --git a/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/task.md b/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/task.md deleted file mode 100644 index 7dcc06a4..00000000 --- a/2-ui/1-document/14-styles-and-classes/1-round-button-javascript/task.md +++ /dev/null @@ -1,33 +0,0 @@ -importance: 3 - ---- - -# Скругленая кнопка со стилями из JavaScript - -Создайте кнопку в виде элемента `` с заданным стилем, используя JavaScript. - -В примере ниже такая кнопка создана при помощи HTML/CSS. В вашем решении кнопка должна создаваться, настраиваться и добавляться в документ при помощи *только JavaScript*, без тегов ` - -Нажми меня -``` - -**Проверьте себя: вспомните, что означает каждое свойство. В чём состоит эффект его появления здесь?** - diff --git a/2-ui/1-document/14-styles-and-classes/2-create-notification/solution.view/index.css b/2-ui/1-document/14-styles-and-classes/2-create-notification/solution.view/index.css index b21a80be..e8d9160b 100755 --- a/2-ui/1-document/14-styles-and-classes/2-create-notification/solution.view/index.css +++ b/2-ui/1-document/14-styles-and-classes/2-create-notification/solution.view/index.css @@ -3,12 +3,12 @@ z-index: 1000; padding: 5px; border: 1px solid black; - font: normal 20px Georgia; + font-size: 20px; background: white; text-align: center; } .welcome { - background: red; + background: #b80000; color: yellow; -} \ No newline at end of file +} diff --git a/2-ui/1-document/14-styles-and-classes/2-create-notification/solution.view/index.html b/2-ui/1-document/14-styles-and-classes/2-create-notification/solution.view/index.html index 07ba7a03..5b8a6336 100755 --- a/2-ui/1-document/14-styles-and-classes/2-create-notification/solution.view/index.html +++ b/2-ui/1-document/14-styles-and-classes/2-create-notification/solution.view/index.html @@ -1,14 +1,12 @@ - - -

Уведомление

+

Notification is on the right

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum aspernatur quam ex eaque inventore quod voluptatem adipisci omnis nemo nulla fugit iste numquam ducimus cumque minima porro ea quidem maxime necessitatibus beatae labore soluta voluptatum @@ -17,43 +15,30 @@

+ + + + + \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/source.view/index.html b/2-ui/1-document/15-size-and-scroll/3-div-placeholder/source.view/index.html new file mode 100755 index 00000000..69e3e504 --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/3-div-placeholder/source.view/index.html @@ -0,0 +1,37 @@ + + + + + + + + + + Before Before Before + +
+ Text Text Text +
Text Text Text +
+
+ + After After After + + + + + + \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/task.md b/2-ui/1-document/15-size-and-scroll/3-div-placeholder/task.md new file mode 100644 index 00000000..23861dd6 --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/3-div-placeholder/task.md @@ -0,0 +1,50 @@ +importance: 3 + +--- + +# Подменить div на другой с таким же размером + +Посмотрим следующий случай из жизни. Был текст, который, в частности, содержал `div` с зелеными границами: + +```html run no-beautify + + +Before Before Before + +
+Text Text Text
+Text Text Text
+
+ +After After After +``` + +Программист Валера из вашей команды написал код, который позиционирует его абсолютно и смещает в правый верхний угол. Вот этот код: + +```js +var div = document.getElementById('moving-div'); +div.style.position = 'absolute'; +div.style.right = div.style.top = 0; +``` + +Побочным результатом явилось смещение текста, который раньше шел после `DIV`. Теперь он поднялся вверх: + +[iframe height=90 src="source"] + +**Допишите код Валеры, сделав так, чтобы текст оставался на своем месте после того, как `DIV` будет смещен.** + +Сделайте это путем создания вспомогательного `DIV` с теми же `width`, `height`, `border`, `margin`, `padding`, что и у желтого `DIV`. + +Используйте только JavaScript, без CSS. + +Должно быть так (новому блоку задан фоновый цвет для демонстрации): + +[iframe height=140 src="solution"] + diff --git a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/ball-half/index.html b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/ball-half/index.html new file mode 100755 index 00000000..23b8d7b2 --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/ball-half/index.html @@ -0,0 +1,41 @@ + + + + + + + + + + +
+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +
+ + + + + + + + \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/field.png b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/field.png new file mode 100755 index 00000000..eea8c171 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/field.png differ diff --git a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.md b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.md new file mode 100644 index 00000000..10b1219e --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.md @@ -0,0 +1,50 @@ +При абсолютном позиционировании мяча внутри поля его координаты `left/top` отсчитываются от **внутреннего** угла поля, например верхнего-левого: + +![](field.png) + +Метрики для внутренней зоны поля -- это `clientWidth/Height`. + +Центр - это `(clientWidth/2, clientHeight/2)`. + +Но если мы установим мячу такие значения `ball.style.left/top`, то в центре будет не сам мяч, а его левый верхний угол: + +```js +var ball = document.getElementById('ball'); +var field = document.getElementById('field'); + +ball.style.left = Math.round(field.clientWidth / 2) + 'px'; +ball.style.top = Math.round(field.clientHeight / 2) + 'px'; +``` + +[iframe hide="Нажмите, чтобы посмотреть текущий результат" height=180 src="ball-half"] + +Для того, чтобы центр мяча находился в центре поля, нам нужно сместить мяч на половину его ширины влево и на половину его высоты вверх. + +```js +var ball = document.getElementById('ball'); +var field = document.getElementById('field'); + +ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px'; +ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px'; +``` + +**Внимание, подводный камень!** + +Код выше стабильно работать не будет, потому что `IMG` идет без ширины/высоты: + +```html + +``` + +**Высота и ширина изображения неизвестны браузеру до тех пор, пока оно не загрузится, если размер не указан явно.** + +После первой загрузки изображение уже будет в кеше браузера, и его размеры будут известны. Но когда браузер впервые видит документ -- он ничего не знает о картинке, поэтому значение `ball.offsetWidth` равно `0`. Вычислить координаты невозможно. + +Чтобы это исправить, добавим `width/height` к картинке: + +```html + +``` + +Теперь браузер всегда знает ширину и высоту, так что все работает. Тот же эффект дало бы указание размеров в CSS. + diff --git a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.view/index.html b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.view/index.html new file mode 100755 index 00000000..47694b5a --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.view/index.html @@ -0,0 +1,41 @@ + + + + + + + + + + +
+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +
+ + + + + + + + \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/source.view/index.html b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/source.view/index.html new file mode 100755 index 00000000..8b54beed --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/source.view/index.html @@ -0,0 +1,30 @@ + + + + + + + + + + +
+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +
+ + + + + \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/task.md b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/task.md new file mode 100644 index 00000000..2ccca698 --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/task.md @@ -0,0 +1,21 @@ +importance: 5 + +--- + +# Поместите мяч в центр поля + +Поместите мяч в центр поля. + +Исходный документ выглядит так: + +[iframe src="source" edit link height=180] + +**Используйте JavaScript, чтобы поместить мяч в центр:** + +[iframe src="solution" height=180] + +- Менять CSS нельзя, мяч должен переносить в центр ваш скрипт, через установку нужных стилей элемента. +- JavaScript-код должен работать при разных размерах мяча (`10`, `20`, `30` пикселей) без изменений. +- JavaScript-код должен работать при различных размерах и местоположениях поля на странице без изменений. Также он не должен зависеть от ширины рамки поля `border`. + +P.S. Да, центрирование можно сделать при помощи чистого CSS, но задача именно на JavaScript. Далее будут другие темы и более сложные ситуации, когда JavaScript будет уже точно необходим, это -- своего рода "разминка". diff --git a/2-ui/1-document/15-size-and-scroll/5-expand-element/solution.md b/2-ui/1-document/15-size-and-scroll/5-expand-element/solution.md new file mode 100644 index 00000000..bbe9a1c9 --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/5-expand-element/solution.md @@ -0,0 +1,43 @@ +# Решение через width: auto + +Вначале рассмотрим решение через "умную" установку CSS-свойства. + +Они могут быть разными. Самое простое выглядит так: + +```js +elem.style.width = 'auto'; +``` + +Такой способ работает, так как `
` по умолчанию распахивается на всю ширину. + +Конечно, такое решение не будет работать для элементов, которые сами по себе не растягиваются, например в случае со `` или при наличии `position: absolute`. + +Обратим внимание, такой вариант был бы неверен: +```js +elem.style.width = '100%'; +``` + +По умолчанию в CSS ширина `width` -- это то, что *внутри `padding`*, а проценты отсчитываются от ширины родителя. То есть, ставя ширину в `100%`, мы говорим: "внутренняя область должна занимать `100%` ширины родителя". А в элементе есть ещё `padding`, которые в итоге вылезут наружу. + +Можно бы поменять блочную модель, указав `box-sizing` через свойство `elem.style.boxSizing`, но такое изменение потенциально может затронуть много других свойств, поэтому нежелательно. + +# Точное вычисление + +Альтернатива -- вычислить ширину родителя через `clientWidth`. + +Доступную внутреннюю ширину родителя можно получить, вычитая из `clientWidth` размеры `paddingLeft/paddingRight`, и затем присвоить её элементу: + +```js +var bodyClientWidth = document.body.clientWidth; + +var style = getComputedStyle(elem); + +*!* +var bodyInnerWidth = bodyClientWidth - parseInt(style.paddingLeft) - parseInt(style.paddingRight); +*/!* + +elem.style.width = bodyInnerWidth + 'px'; +``` + +Такое решение будет работать всегда, вне зависимости от типа элемента. Конечно, при изменении размеров окна браузера ширина не адаптируется к новому размеру автоматически, как с `width:auto`. Это недостаток. Его, конечно, тоже можно обойти при помощи событий (изучим далее), но как общий рецепт -- если CSS может решить задачу -- лучше использовать CSS. + diff --git a/2-ui/1-document/15-size-and-scroll/5-expand-element/solution.view/index.html b/2-ui/1-document/15-size-and-scroll/5-expand-element/solution.view/index.html new file mode 100755 index 00000000..6c51d6ad --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/5-expand-element/solution.view/index.html @@ -0,0 +1,53 @@ + + + + + + + + + + +
+ текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст + текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст + текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст + текст текст +
+ + + + + + + \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/5-expand-element/source.view/index.html b/2-ui/1-document/15-size-and-scroll/5-expand-element/source.view/index.html new file mode 100755 index 00000000..4bfe7fee --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/5-expand-element/source.view/index.html @@ -0,0 +1,39 @@ + + + + + + + + + + +
+ текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст + текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст + текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст + текст текст +
+ + + + + + + \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/5-expand-element/task.md b/2-ui/1-document/15-size-and-scroll/5-expand-element/task.md new file mode 100644 index 00000000..48cffe9b --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/5-expand-element/task.md @@ -0,0 +1,18 @@ +importance: 4 + +--- + +# Расширить элемент + +В `` есть элемент `
` с заданной шириной `width`. + +Задача -- написать код, который "распахнет" `
` по ширине на всю страницу. + +Исходный документ (`
` содержит текст и прокрутку): + +[iframe height=220 src="source"] + +P.S. Пользоваться следует исключительно средствами JS, CSS в этой задаче менять нельзя. Также ваш код должен быть универсален и не ломаться, если цифры в CSS станут другими. + +P.P.S. При расширении элемент `
` не должен вылезти за границу ``. + diff --git a/2-ui/1-document/15-size-and-scroll/6-width-vs-clientwidth/solution.md b/2-ui/1-document/15-size-and-scroll/6-width-vs-clientwidth/solution.md new file mode 100644 index 00000000..268dc0b6 --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/6-width-vs-clientwidth/solution.md @@ -0,0 +1,10 @@ +Отличия: + +1. `getComputedStyle` не работает в IE8-. +2. `clientWidth` возвращает число, а `getComputedStyle(...).width` -- строку, на конце `px`. +3. `getComputedStyle` не всегда даст ширину, он может вернуть, к примеру, `"auto"` для инлайнового элемента. +4. `clientWidth` соответствует внутренней видимой области элемента, *включая `padding`, а CSS-ширина `width` при стандартном значении `box-sizing` соответствует зоне *внутри `padding`*. +5. Если есть полоса прокрутки, то некоторые браузеры включают её ширину в `width`, а некоторые -- нет. + + Свойство `clientWidth`, с другой стороны, полностью кросс-браузерно. Оно всегда обозначает размер *за вычетом прокрутки*, т.е. реально доступный для содержимого. + diff --git a/2-ui/1-document/15-size-and-scroll/6-width-vs-clientwidth/task.md b/2-ui/1-document/15-size-and-scroll/6-width-vs-clientwidth/task.md new file mode 100644 index 00000000..20b38f68 --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/6-width-vs-clientwidth/task.md @@ -0,0 +1,9 @@ +importance: 5 + +--- + +# В чём отличие "width" и "clientWidth" ? + +В чём отличия между `getComputedStyle(elem).width` и `elem.clientWidth`? + +Укажите хотя бы три отличия, лучше -- больше. \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/article.md b/2-ui/1-document/15-size-and-scroll/article.md new file mode 100644 index 00000000..a3dca58f --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/article.md @@ -0,0 +1,274 @@ +# Element size and scrolling + +To show elements at arbitrary places in the page we should: + +1. First, know CSS positioning. +2. Second, know how to handle "geometrical" properties in Javascript. + +[cut] + +## Sample element + +For the example we'll use the element with the border, padding and scrolling: + +```html no-beautify +
+ ...Text... +
+ +``` + +It has no margins, because they are irrelevant here for us, as they are not the part of the element itself. + +The element looks like this: + +![](metric-css.png) + +You can [open the document in the sandbox](sandbox:metric). + +```smart header="Mind the scrollbar" +The picture above demonstrates the most complex case when the element has a scrollbar. Some browsers (not all) reserve the space for it by taking it from the content. + +So, without scrollbar the content width would be `300px`, but if the scrollbar is `16px` wide (the width may vary for devices and browsers) then only `300-16 = 284px` remains. Our code should work well if the scrollbar exists and occupies some place, so we consider it the case here. +``` + +```smart header="The `padding-bottom` may be filled with text" +Usually paddings are shown empty on illustrations, but if there's a lot of text in the element and it overflows, then the browsers show it at `padding-bottom`. +``` + +## Geometry + +Element properties that provide width, height and other geometry are always numbers. They are assumed to be in pixels. + +Here's the overall picture: + +![](metric-all.png) + +All properties hardly fit in the picture, but as we'll see soon, their values are simple and easy to understand. + +Let's start exploring them from the outer side of the element. + +## offsetParent, offsetLeft/Top + +These properties are rarely needed. But still they are the "most outer" geometry properties, so we'll start with them. + +The `offsetParent` is the nearest ancestor that is: + +1. CSS-positioned (`position` is `absolute`, `relative` or `fixed`). +2. or ``, ``, ``. +2. or `` + +The `offsetParent` alone has no use. But `offsetLeft/offsetTop` provide x/y coordinates relative to it's left-upper corner. + +In the example below the inner `
` has `
` as `offsetParent` and `offsetLeft/offsetTop` are shifts from its left-upper corner (`180`): + +```html run height=10 +
+
+
...
+
+
+ +``` + +![](metric-offset-parent.png) + + +There are several occasions when `offsetParent` is `null`: + +1. For not shown elements (`display:none` or not in the document). +2. For `` and ``. +3. For elements with `position:fixed` on them. + +## offsetWidth/Height + +Now let's move to the element itself. + +These two properties are the simplest ones. They provide the "outer" width/height of the element. Or, in other words, its full size including borders. + +![](metric-offset-width-height.png) + +For our sample element: + +- `offsetWidth = 390` -- the outer width, can be calculated as inner CSS-width (`300px`) plus paddings (`2*20px`) and borders (`2*25px`). +- `offsetHeight = 290` -- the outer height. + +````smart header="Geometry properties for not shown elements are zero/null" +Geometry properties are calculated only for shown elements. + +If an element (or any of its ancestors) has `display:none` or is not in the document, then `offsetParent` is `null` and `offsetWidth`, `offsetHeight` and other numeric properties are `0`. + +We can use this to check if an element is hidden, like this: + +```js +function isHidden(elem) { + return !elem.offsetWidth && !elem.offsetHeight; +} +``` + +Should keep in mind that such `isHidden` returns `true` for elements that are on-screen, but have zero sizes (like an empty `
`). +```` + +## clientTop/Left + +Inside the element we have the borders. + +To measure them, there are properties `clientTop` and `clientLeft`. + +In our example: + +- `clientLeft = 25` -- left border width +- `clientTop = 25` -- top border width + +![](metric-client-left-top.png) + +...But to be precise -- they are not borders, but relative coordinates of the inner side from the outer side. + +What's the difference? + +It becomes visible when the document is right-to-left (OS in arabic or hebrew languages). The scrollbar is then not on the right, but on the left, and then `clientLeft` also includes the scrollbar width. + +In that case `clientLeft` in our example would be not `25`, but with the scrollbar width `25+16=41`: + +![](metric-client-left-top-rtl.png) + +## clientWidth/Height + +These properties provide the size of the area inside the element borders. + +They include the content width together with paddings, but without the scrollbar: + +![](metric-client-width-height.png) + +On the picture above let's first consider `clientHeight`: it's easier to evaluate. There's no horizontal scrollbar, so its exactly the sum of what's inside the borders: CSS-высота `200px` plus top and bottom paddings (`2*20px`) total `240px`. + +Now `clientWidth` -- here the content width is not `300px`, but `284px`, because `16px` are occupied by the scrollbbar. So the sum is `284px` plus left and right paddings, total `324px`. + +**If there are no paddings, then `clientWidth/Height` is exactly the content area, inside the borders and the scrollbar (if any).** + +![](metric-client-width-nopadding.png) + +So when there's no padding we can use `clientWidth/clientHeight` to get the content area size. + +## scrollWidth/Height + +- Properties `clientWidth/clientHeight` only account for the visible part of the element. +- Properties `scrollWidth/scrollHeight` add the scrolled out (hidden) part: + +![](metric-scroll-width-height.png) + +On the picture above: + +- `scrollHeight = 723` -- is the full inner height of the content area including the scrolled out part. +- `scrollWidth = 324` -- is the full inner width, here we have no horizontal scroll, so it equals `clientWidth`. + +We can use these properties to open the element wide to its full width/height, by the code: + +```js +element.style.height = element.scrollHeight + 'px'; +``` + +```online +Click the button to open wide the element: + +
text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
+ + +``` + +## scrollLeft/scrollTop + +Properties `scrollLeft/scrollTop` show how much is hidden behind the scroll. It's the width/height of the hidden, scrolled out part of the element. + +On the picture below we can see `scrollHeight` and `scrollTop` for a block with a vertical scroll: + +![](metric-scroll-top.png) + +````smart header="`scrollLeft/scrollTop` can be modified" +Unlike most other geometry properties that are read-only, `scrollLeft/scrollTop` can be changed, and the browser will scroll the element. + +```online +If you click the element below, the code `elem.scrollTop += 10` executes. That makes the element content scroll `10px` below. + +
Click
Me
1
2
3
4
5
6
7
8
9
+``` +```` + +## Don't take width/height from CSS + +We've just covered geometry properties of DOM elements. They are normally used to get widths, heights and distances. + +Now let's see what we should not use. + +As we know from the chapter , we can read CSS-height and width using `getComputedStyle`. + +So we can try to read the width of an element like this: + +```js run +let elem = document.body; + +alert( getComputedStyle(elem).width ); // show CSS width for elem +``` + +Why we should use geometry properties instead? + +1. First, CSS `width/height` depend on another property -- `box-sizing` that defines "what is" CSS width and height. A change in `box-sizing` for purposes of CSS may break such JavaScript. +2. Second, CSS `width/height` may be `auto`, for instance for an inline element: + + ```html run + Hello! + + + ``` + + From the CSS standpoint, `width:auto` is perfectly normal, but in JavaScript we need an exact size in `px` that we can use in calculations. So here CSS width is useless at all. + +And there's one more reason. A scrollbar is the reason of many problems. The devil is in the detail. Sometimes the code that works fine without a scrollbar starts to bug with it. + +As we've seen a scrollbar takes the space from the content in some browsers. So the real width available for the content is *less* than CSS width. And `clientWidth/clientHeight` take that into account. + +...But some browsers also take that into account in `getComputedStyle(elem).width`. That is: some of them return real inner width and some of them -- CSS width. Such cross-browser differences is a reason not to use `getComputedStyle`, but rather rely on geometry propeties. + +```online +Если ваш браузер показывает полосу прокрутки (например, под Windows почти все браузеры так делают), то вы можете протестировать это сами, нажав на кнопку в ифрейме ниже. + +[iframe src="cssWidthScroll" link border=1] + +У элемента с текстом в стилях указано `width:300px`. + +На момент написания этой главы при тестировании в Chrome под Windows `alert` выводил `283px`, а в Firefox -- `300px`. При этом оба браузера показывали прокрутку. Это из-за того, что Firefox возвращал именно CSS-ширину, а Chrome -- реальную ширину, за вычетом прокрутки. +``` + +Описанные разночтения касаются только чтения свойства `getComputedStyle(...).width` из JavaScript, визуальное отображение корректно в обоих случаях. + +## Итого + +У элементов есть следующие метрики: + +- `offsetParent` -- "родитель по дереву рендеринга" -- ближайшая ячейка таблицы, body для статического позиционирования или ближайший позиционированный элемент для других типов позиционирования. +- `offsetLeft/offsetTop` -- позиция в пикселях левого верхнего угла блока, относительно его `offsetParent`. +- `offsetWidth/offsetHeight` -- "внешняя" ширина/высота блока, включая рамки. +- `clientLeft/clientTop` -- отступ области содержимого от левого-верхнего угла элемента. Если операционная система располагает вертикальную прокрутку справа, то равны ширинам левой/верхней рамки, если же слева (ОС на иврите, арабском), то `clientLeft` включает в себя прокрутку. +- `clientWidth/clientHeight` -- ширина/высота содержимого вместе с полями `padding`, но без полосы прокрутки. +- `scrollWidth/scrollHeight` -- ширина/высота содержимого, включая прокручиваемую область. Включает в себя `padding` и не включает полосы прокрутки. +- `scrollLeft/scrollTop` -- ширина/высота прокрученной части документа, считается от верхнего левого угла. + +Все свойства, доступны только для чтения, кроме `scrollLeft/scrollTop`. Изменение этих свойств заставляет браузер прокручивать элемент. + +В этой главе мы считали, что страница находится в режиме соответствия стандартам. В режиме совместимости -- некоторые старые браузеры требуют `document.body` вместо `documentElement`, в остальном всё так же. Конечно, по возможности, стоит использовать только режим соответствия стандарту. diff --git a/2-ui/1-document/15-size-and-scroll/cssWidthScroll.view/index.html b/2-ui/1-document/15-size-and-scroll/cssWidthScroll.view/index.html new file mode 100755 index 00000000..a29f8a3a --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/cssWidthScroll.view/index.html @@ -0,0 +1,26 @@ + + + + + + + + +
+ текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст + текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст + текст текст текст текст текст текст текст текст текст текст текст текст текст текст +
+ + + + У элемента стоит style="width:300px" +
+ + + + + + \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/metric-all.png b/2-ui/1-document/15-size-and-scroll/metric-all.png new file mode 100644 index 00000000..6deec908 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-all.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-all@2x.png b/2-ui/1-document/15-size-and-scroll/metric-all@2x.png new file mode 100644 index 00000000..e084c257 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-all@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-client-left-top-rtl.png b/2-ui/1-document/15-size-and-scroll/metric-client-left-top-rtl.png new file mode 100644 index 00000000..ffb10aa1 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-client-left-top-rtl.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-client-left-top-rtl@2x.png b/2-ui/1-document/15-size-and-scroll/metric-client-left-top-rtl@2x.png new file mode 100644 index 00000000..48510e6e Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-client-left-top-rtl@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-client-left-top.png b/2-ui/1-document/15-size-and-scroll/metric-client-left-top.png new file mode 100644 index 00000000..33faf9be Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-client-left-top.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-client-left-top@2x.png b/2-ui/1-document/15-size-and-scroll/metric-client-left-top@2x.png new file mode 100644 index 00000000..a8e170ea Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-client-left-top@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-client-width-height.png b/2-ui/1-document/15-size-and-scroll/metric-client-width-height.png new file mode 100644 index 00000000..3f9c6dec Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-client-width-height.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-client-width-height@2x.png b/2-ui/1-document/15-size-and-scroll/metric-client-width-height@2x.png new file mode 100644 index 00000000..0c61fa6a Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-client-width-height@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-client-width-nopadding.png b/2-ui/1-document/15-size-and-scroll/metric-client-width-nopadding.png new file mode 100644 index 00000000..a183c6b3 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-client-width-nopadding.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-client-width-nopadding@2x.png b/2-ui/1-document/15-size-and-scroll/metric-client-width-nopadding@2x.png new file mode 100644 index 00000000..5a73f87a Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-client-width-nopadding@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-css.png b/2-ui/1-document/15-size-and-scroll/metric-css.png new file mode 100644 index 00000000..564c210a Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-css.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-css@2x.png b/2-ui/1-document/15-size-and-scroll/metric-css@2x.png new file mode 100644 index 00000000..e4fd7bb8 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-css@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-offset-parent.png b/2-ui/1-document/15-size-and-scroll/metric-offset-parent.png new file mode 100644 index 00000000..5f1e58f9 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-offset-parent.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-offset-parent@2x.png b/2-ui/1-document/15-size-and-scroll/metric-offset-parent@2x.png new file mode 100644 index 00000000..af62ebdc Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-offset-parent@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-offset-width-height.png b/2-ui/1-document/15-size-and-scroll/metric-offset-width-height.png new file mode 100644 index 00000000..4e7821b8 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-offset-width-height.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-offset-width-height@2x.png b/2-ui/1-document/15-size-and-scroll/metric-offset-width-height@2x.png new file mode 100644 index 00000000..370821e7 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-offset-width-height@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-scroll-top.png b/2-ui/1-document/15-size-and-scroll/metric-scroll-top.png new file mode 100644 index 00000000..4bc795aa Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-scroll-top.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-scroll-top@2x.png b/2-ui/1-document/15-size-and-scroll/metric-scroll-top@2x.png new file mode 100644 index 00000000..bf0cf711 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-scroll-top@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-scroll-width-height.png b/2-ui/1-document/15-size-and-scroll/metric-scroll-width-height.png new file mode 100644 index 00000000..581c2144 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-scroll-width-height.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric-scroll-width-height@2x.png b/2-ui/1-document/15-size-and-scroll/metric-scroll-width-height@2x.png new file mode 100644 index 00000000..1e2a20f5 Binary files /dev/null and b/2-ui/1-document/15-size-and-scroll/metric-scroll-width-height@2x.png differ diff --git a/2-ui/1-document/15-size-and-scroll/metric.view/index.html b/2-ui/1-document/15-size-and-scroll/metric.view/index.html new file mode 100755 index 00000000..88392ce7 --- /dev/null +++ b/2-ui/1-document/15-size-and-scroll/metric.view/index.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + +
+

Introduction

+

This Ecma Standard is based on several originating technologies, the most well known being JavaScript (Netscape) and JScript (Microsoft). The language was invented by Brendan Eich at Netscape and first appeared in that company's Navigator 2.0 browser. + It has appeared in all subsequent browsers from Netscape and in all browsers from Microsoft starting with Internet Explorer 3.0. The development of this Standard started in November 1996. The first edition of this Ecma Standard was adopted by the + Ecma General Assembly of June 1997.

+ +

That Ecma Standard was submitted to ISO/IEC JTC 1 for adoption under the fast-track procedure, and approved as international standard ISO/IEC 16262, in April 1998. The Ecma General Assembly of June 1998 approved the second edition of ECMA-262 to keep + it fully aligned with ISO/IEC 16262. Changes between the first and the second edition are editorial in nature.

+ +

The third edition of the Standard introduced powerful regular expressions, better string handling, new control statements, try/catch exception handling, tighter definition of errors, formatting for numeric output and minor changes in anticipation + of forthcoming internationalisation facilities and future language growth. The third edition of the ECMAScript standard was adopted by the Ecma General Assembly of December 1999 and published as ISO/IEC 16262:2002 in June 2002.

+ +
+ + +
Координаты мыши: ...
+
+ + + + + + + \ No newline at end of file diff --git a/figures.sketch b/figures.sketch index 95586868..26530ffa 100644 Binary files a/figures.sketch and b/figures.sketch differ