ilyachalov (ilyachalov) wrote,
ilyachalov
ilyachalov

Category:

CSS: абсолютное позиционирование и содержащий блок

В задаче «Передвиньте мяч по полю» к подразделу 2.1 «Введение в браузерные события» второй части учебника по JavaScript вернулись к старому знакомому футбольному полю и мячу на нём (задачи с таким полем я рассматривал в предыдущих постах тут и тут).

Полный код заданной HTML-страницы можно посмотреть в песочнице.

Стиль поля, прописанный в заголовочной части заданной HTML-страницы:
<style>
  #field {
    width: 200px;
    height: 150px;
    border: 10px solid black;
    background-color: #00ff00;
    overflow: hidden;
  }
</style>

Тело заданной HTML-страницы:
Нажмите на поле для перемещения мяча.
<br>Мяч не должен выходить за границы поля.
<div id="field">
  <img src="https://ru.js.cx/clipart/ball.svg" id="ball">
  . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . .
  . . . . . . . . . . . . . . . . . . . . . . . . .
</div>

У меня в браузере («Microsoft Edge» на движке «Chromium») это выглядит так (картинка 1):



Тонкая серая линия слева и сверху — это уже часть окна браузера, а не области просмотра. Я оставил эту линию на картинке, чтобы было видно, где относительно левого верхнего угла области просмотра находится футбольное поле с мячом.

Так как я уже имел дело с этим кодом, мне подумалось, что авторы задачи забыли описать стиль мяча и в нем задать абсолютное позиционирование для него (мяч, по идее, не должен мешать точкам заполнять зеленое пространство футбольного поля). Добавим стиль мяча в секцию стилей в заголовочной части заданного HTML-документа:
<style>
  #field {                     /* стиль футбольного поля */
    width: 200px;
    height: 150px;
    border: 10px solid black;
    background-color: #00ff00;
    overflow: hidden;
  }

  #ball {                      /* стиль мяча */
    position: absolute;
  }
</style>

Теперь у меня в браузере получилось следующее (картинка 2):



Хоть всё отобразилось так, как нужно, мне такое отображение показалось не соответствующим правилам CSS-позиционирования.

По идее, если HTML-элемент имеет в стиле указание position: absolute; (абсолютное позиционирование), то он должен позиционироваться относительно одного из своих предков, имеющих не статическое позиционирование, либо (если таких предков не найдено) относительно исходного (или начального) содержащего блока (по-английски «initial containing block»). Об этом рассказано тут:

https://developer.mozilla.org/ru/docs/Learn/CSS/CSS_layout/Positioning

У нашего мяча (его представляет HTML-элемент img) есть два предка, относительно которых он может позиционироваться: более близкий — HTML-элемент div (футбольное поле) и более дальний — HTML-элемент body (тело заданной HTML-страницы). Однако, у обоих этих предков CSS-свойство position не установлено. В таких случаях по умолчанию считается, что действует указание position: static;, то есть такие элементы считаются имеющими статическое позиционирование.

Таким образом, наш мяч должен позиционироваться относительно исходного содержащего блока, который имеет размеры области просмотра в браузере, а значит, мяч должен был, по идее, в отображении быть задвинутым в левый верхний угол области просмотра и примыкать к левой и верхней границам области просмотра. Примерно так (картинка 3):



Но этого не произошло! Почему? Дело в том, что такое отображение (как на картинке 3) в данном случае получится, если CSS-свойства top и left в стиле мяча равны нулю. Но эти свойства в стиле мяча вообще не указаны. Я думал, что они по умолчанию равны нулю, но это оказалось не так.

По умолчанию (по-английски «initial value») CSS-свойства top и left равны значению auto. Об этом сказано тут:
https://developer.mozilla.org/en-US/docs/Web/CSS/top
https://developer.mozilla.org/en-US/docs/Web/CSS/left

Что такое значение auto в нашем случае? Цитата:
https://developer.mozilla.org/ru/docs/Web/CSS/top

для абсолютно спозиционированных элементов — позиция элемента опирается на свойство bottom, пока height: auto обрабатывается как высота в зависимости от содержимого; если так же и bottom: auto, то элемент располагается так же, как при статическом позиционировании


То есть в данном случае при CSS-свойствах top и left в стиле мяча, равных значению auto, мяч будет находиться в том же месте, что и при статическом позиционировании. Единственное отличие — мяч находится поверх содержимого футбольного поля (при статическом позиционировании мяча он находился бы в составе содержимого футбольного поля вместе с текстовыми точками, сдвинув их в сторону и вниз). Это ситуация на картинке 2.

Таким образом, для получения ситуации на картинке 2 стиль мяча в нашем случае должен быть следующим:
<style>
  #ball {                      /* стиль мяча */
    position: absolute;
  }
</style>
или
<style>
  #ball {                      /* стиль мяча */
    position: absolute;
    top: auto;                 /* в моём браузере по факту 54px */
    left: auto;                /* в моём браузере по факту 18px */
  }
</style>

Для получения ситуации на картинке 3:
<style>
  #ball {                      /* стиль мяча */
    position: absolute;
    top: 0;
    left: 0;
  }
</style>

Ну а для нашей задачи стили футбольного поля и мяча установим так:
<style>
  #field {                     /* стиль футбольного поля */
    width: 200px;
    height: 150px;
    border: 10px solid black;
    background-color: #00ff00;
    overflow: hidden;
    position: relative;        /* поле считать содержащим блоком */
  }

  #ball {                      /* стиль мяча */
    position: absolute;        /* позиционируем мяч относительно поля */
  }
</style>

Теперь содержащим блоком для мяча является не исходный содержащий блок (имеющий размеры области просмотра), а футбольное поле. Поэтому абсолютное позиционирование мяча будет выполняться относительно футбольного поля, а не области просмотра. CSS-свойства top и left не указываем, их будет устанавливать скрипт на языке JavaScript, который мы напишем, когда решим эту задачу.
Tags: Образование, Программирование
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments