Абсолютный элемент, переполняющий документ

Я столкнулся со странной проблемой при попытке разместить всплывающее окно position: absolute в моем проекте.

Что касается position: absolute, MDN говорит:

The element is removed from the normal document flow, and no space is created for the element in the page layout.

К сожалению, в приведенном ниже примере размещение элемента с помощью right: 0 и transform: translateX(100%) создает дополнительное пространство за пределами тела, как если бы элемент должен был быть position: relative. Этого не произойдет, если мы будем использовать left: 0 и transform: translateX(-100%).

  .parent {
    width: 100%;
    height: 100vh;
    border: 1px solid red;
    background-color: magenta;
  }
  .child {
    position: absolute;
    transform: translateX(100%);
    width: 100px;
    height: 50%;
    border: 1px solid black;
    right: 0;
    background-color: yellow;
  }
  <div class = "parent">
     <div class = "child"></div>
  </div>

Вот ссылка на пример проблемы https://jsbin.com/fikonusayi/edit?html,css,output

Это ошибка браузера или (не) ожидаемая функция?

P.S. Обнаружен в Chrome и Safari.

Чтобы добавить, это происходит справа, а не слева, потому что мы используем систему слева направо, сверху вниз. Естественно, вещи могут перетекать только вправо или вниз.

Serg Chernata 05.09.2018 21:23

Пожалуйста, добавьте свой минимальный воспроизводимый пример к самому вопросу; ссылка на JSFiddle не соответствует правилам.

TylerH 05.09.2018 21:25

PS можете найти свой ответ здесь

TylerH 05.09.2018 21:28

@TemaniAfif Ваш комментарий бесполезен.

saranc 05.09.2018 21:39

@TylerH Спасибо за источник. Обновил пост. Также интересно прочитать о матрице преобразования. Тем не менее, меня все еще путают две вещи: 1) почему того же эффекта можно достичь, удалив transform и добавив right: 100000px, и 2) почему этого эффекта нет у position: fixed? Не могли бы вы уточнить?

saranc 05.09.2018 21:41

@TylerH как он отвечает на вопрос? преобразование добавляется к абсолютному элементу, а не к родительскому элементу .. здесь речь идет о переполнении, не содержащем блока

Temani Afif 05.09.2018 21:42

@saranc он действительно создает дополнительное пространство в процентах ниже 100%, я пробовал его на 25/50/75 и 90% ..

Rachel Gallen 05.09.2018 22:14
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
4
7
249
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема здесь в overflow, а не в документообороте. Если мы обратимся к спецификация:

Generally, the content of a block box is confined to the content edges of the box. In certain cases, a box may overflow, meaning its content lies partly or entirely outside of the box, e.g.:

...

A descendant box is positioned absolutely, partly outside the box. Such boxes are not always clipped by the overflow property on their ancestors; specifically, they are not clipped by the overflow of any ancestor between themselves and their containing block

....

Вы можете заметить, что нет другого позиционированного элемента, кроме child, поэтому содержащий блокchild будет окном просмотра. И уловка здесь в том, что полоса прокрутки всегда добавляется к содержащему блоку, начиная слева (горизонтальная прокрутка) или сверху (вертикальная прокрутка), поэтому любое переполнение сверху или слева станет недоступным.

Вот иллюстрация, чтобы лучше понять проблему:

.parent {
  width: 100%;
  height: 100vh;
  border: 1px solid red;
  background-color: magenta;
  box-sizing:border-box;
}

.child {
  position: absolute;
  width: 100px;
  height: 50%;
  border: 1px solid black;
  left: 0;
  background-color: yellow;
  animation:move 3s infinite linear alternate;
}
@keyframes move{
  from {left:-100px}
  to {left:100%}
}

body {
 margin:0;
}
<div class = "parent">
  <div class = "child"></div>
</div>

Как видите, прокрутка есть только при переполнении элемента слева. Та же логика, если рассматривать верх / низ

.parent {
  width: 100%;
  height: 100vh;
  border: 1px solid red;
  background-color: magenta;
  box-sizing:border-box;
}

.child {
  position: absolute;
  width: 100px;
  height: 50%;
  border: 1px solid black;
  left: 0;
  background-color: yellow;
  animation:move 3s infinite linear alternate;
}
@keyframes move{
  from {top:-100px}
  to {top:100%}
}

body {
 margin:0;
}
<div class = "parent">
  <div class = "child"></div>
</div>

И чтобы подтвердить, что ваш элемент действительно удален из потока, просто добавьте контент и удалите фиксированную высоту из родительского элемента, и вы увидите, что для вашего элемента не предусмотрено места:

.parent {
  border: 1px solid red;
  background-color: magenta;
  position: relative;
  box-sizing:border-box;
}

.child {
  position: absolute;
  width: 100px;
  height: 50%;
  border: 1px solid black;
  top:0;
  left: 0;
  background-color: yellow;
  animation:move 3s infinite linear alternate;
}
@keyframes move{
  from {left:-100px;top:-100px;}
  to {left:100%;top:100%;}
}

body {
 margin:0;
 border:2px solid red;
}
<div class = "parent">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras eget maximus nibh. Nam non libero molestie, placerat lorem sed, congue arcu. Aliquam eu ultrices nisi, sed facilisis purus. Suspendisse sit amet tincidunt massa, varius tempor mi. Suspendisse semper finibus ipsum in varius. Maecenas id commodo mi, vitae molestie diam. Nulla a risus cursus, auctor ligula sit amet, vestibulum purus. In in turpis non mi auctor viverra porta ac magna.
  <div class = "child"></div>
</div>

В отличие от position:relative:

.parent {
  border: 1px solid red;
  background-color: magenta;
  position: relative;
  box-sizing:border-box;
}

.child {
  position: relative;
  width: 100px;
  height: 50px;
  border: 1px solid black;
  top:0;
  left: 0;
  background-color: yellow;
  animation:move 3s infinite linear alternate;
}
@keyframes move{
  from {left:-100px;top:-100px;}
  to {left:100%;top:100px;}
}

body {
 margin:0;
 border:2px solid red;
}
<div class = "parent">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras eget maximus nibh. Nam non libero molestie, placerat lorem sed, congue arcu. Aliquam eu ultrices nisi, sed facilisis purus. Suspendisse sit amet tincidunt massa, varius tempor mi. Suspendisse semper finibus ipsum in varius. Maecenas id commodo mi, vitae molestie diam. Nulla a risus cursus, auctor ligula sit amet, vestibulum purus. In in turpis non mi auctor viverra porta ac magna.
  <div class = "child"></div>
</div>

Почему этого не происходит с position:fixed? просто потому, что в спецификация ничего не указано. Вот все случаи переполнения:

  • A line cannot be broken, causing the line box to be wider than the block box.
  • A block-level box is too wide for the containing block. This may happen when an element's 'width' property has a value that causes the generated block box to spill over sides of the containing block.
  • An element's height exceeds an explicit height assigned to the containing block (i.e., the containing block's height is determined by the 'height' property, not by content height).
  • A descendant box is positioned absolutely, partly outside the box. Such boxes are not always clipped by the overflow property on their ancestors; specifically, they are not clipped by the overflow of any ancestor between themselves and their containing block
  • A descendant box has negative margins, causing it to be positioned partly outside the box. The 'text-indent' property causes an inline box to hang off either the left or right edge of the block box.

Большой! Я программирую 3 года и практически никогда не обращал внимания на переполнение. Этот случай был для меня в новинку. Какие-либо архитектурные / семантические решения, которые вы бы посоветовали избежать / исправить переполнение?

Roland Jegorov 05.09.2018 22:27

@RolandJegorov Я не думаю, что переполнение - это проблема для начала ... в большинстве случаев это намеренно, особенно для какой-то анимации, где мы скрываем элементы и заставляем их появляться (используется с переполнением: скрыто, чтобы избежать прокрутки) . Но в случае, если это случайно, вам просто нужно обратить внимание, нет общих правил, но старайтесь избегать фиксированной высоты, не забывайте box-sizing:border-box при работе с заполнением / границей / шириной или высотой. с position: absolute / fixed убедитесь, что правильно установили положение и т. д.

Temani Afif 05.09.2018 22:32

Другие вопросы по теме