Подтвердить что ты не робот

Родительский и дочерний с фиксированной позицией, родительское переполнение: скрытая ошибка

Я не знаю, есть ли проблема, но мне было интересно, почему overflow:hidden не работает в элементе fixed parent/children.

Вот пример:

CSS и HTML:

.parent{
  position:fixed;
  overflow:hidden;
  width:300px;
  height:300px;
  background:#555;
}
.children{
  position:fixed;
  top:200px;
  left:200px;
  width:150px;
  height:150px;
  background:#333;
}
<div class="parent">
  <div class="children">
  </div>
</div>
4b9b3361

Ответ 1

Поскольку элемент фиксированной позиции фиксирован относительно окна просмотра, а не другой элемент. Поэтому, поскольку окно просмотра не отключает его, переполнение становится неуместным.

В то время как положение и размеры элемента с положение: абсолютное относительно его содержащего блока, позиция и размеры элемента с положением: фиксированные всегда относительны к исходному содержащему блоку. Обычно это окно просмотра: окна браузера или страницы с документами.

ref: http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning#Fixed_positioning

Ответ 2

Вы можете использовать CSS clip: rect(top, right, bottom, left);, чтобы скопировать фиксированный позиционный элемент в родительский. См. Демонстрацию в http://jsfiddle.net/lmeurs/jf3t0fmf/.

Остерегайтесь, используйте с осторожностью!

Хотя стиль клипа широко поддерживается, основными недостатками являются:

  • Родительская позиция не может быть статичной или относительной (можно использовать абсолютно позиционированный родительский элемент внутри относительно позиционированного контейнера);
  • Прямые координаты не поддерживают проценты, хотя значение auto равно 100%, т.е. clip: rect(auto, auto, auto, auto);;
  • По возможности с дочерними элементами ограничены, по крайней мере, IE11 и Chrome34, т.е. мы не можем установить положение дочерних элементов относительно или абсолютное или использовать преобразование CSS3 подобно шкале.

Подробнее см. http://tympanus.net/codrops/2013/01/16/understanding-the-css-clip-property/.

EDIT: Chrome, похоже, обрабатывает позиционирование и преобразования CSS3 на дочерних элементах намного лучше при применении backface-visibility, поэтому, чтобы быть уверенным, мы добавили:

-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;

к основному дочернему элементу.

Также обратите внимание, что он не полностью поддерживается старыми/мобильными браузерами, или это может принести дополнительные усилия. Посмотрите нашу реализацию для меню в bellafuchsia.com.

  • IE8 хорошо отображает меню, но ссылки меню не доступны,
  • IE9 не отображает меню под сгибом;
  • iOS Safari < 5 не показывает меню хорошо;
  • iOS Safari 5+ перерисовывает обрезанное содержимое на прокрутке после прокрутки;
  • FF (как минимум 13+), IE10 +, Chrome и Chrome для Android, похоже, играют хорошо.

EDIT 2014-11-02: Демо-URL обновлен.

Ответ 3

Обновление 2016:

Вы можете создать новый контекст стекирования, как показано на Coderwall:

<div style="transform: translate3d(0,0,0);overflow:hidden">
   <img style="position:fixed; ..." />
</div>

Что относится к http://dev.w3.org/csswg/css-transforms/#transform-rendering

Для элементов, макет которых определяется моделью окна CSS, любое значение, отличное от none для преобразования, приводит к созданию как контекста стекирования, так и содержащего блока. Объект действует как содержащий блок для фиксированных позиционированных потомков.

Ответ 4

Если вы хотите скрыть переполнение элементов фиксированной позиции, самый простой подход, который я нашел, - это разместить элемент внутри элемента контейнера и применить к этому элементу position:fixed и overflow:hidden вместо содержащегося элемента ( вы должны удалить position:fixed из содержащегося элемента, чтобы это работало). Затем содержимое фиксированного контейнера следует обрезать, как ожидалось.

В моем случае у меня возникли проблемы с использованием object-fit:cover элемента фиксированной позиции (он выходил за пределы страницы, независимо от overflow:hidden). Размещение его в фиксированном контейнере с overflow:hidden на контейнере устранило проблему.

Ответ 5

Элементы фиксированной позиции расположены относительно окна браузера, поэтому родительский элемент в основном не имеет значения.

Чтобы получить желаемый эффект, где overflow в родительском клипе дочерний элемент, используйте position: absolute вместо: http://jsfiddle.net/DBHUv/1/

Ответ 6

У меня была аналогичная, довольно сложная проблема с макетом жидкости, где правая колонка имела фиксированную ширину, а левая имела гибкую ширину. Мой фиксированный контейнер должен иметь ту же ширину, что и гибкая колонка. Вот мое решение:

HTML

<div id="wrapper">
    <div id="col1">
    <div id="fixed-outer">
        <div id="fixed-inner">inner</div>
    </div>
    COL1<br />Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
    </div>
    <div id="col2">COL2</div>
</div>

CSS

    #wrapper {
    padding-left: 20px;
}

#col1 {
    background-color: grey;
    float: left;
    margin-right: -200px; /* #col2 width */
    width: 100%;
}

#col2 {
    background-color: #ddd;
    float: left;
    height: 400px;
    width: 200px;
}

#fixed-outer {
    background: yellow;
    border-right: 2px solid red;
    height: 30px;
    margin-left: -420px; /* 2x #col2 width + #wrapper padding-left */
    overflow: hidden;
    padding-right: 200px; /* #col2 width */
    position: fixed;
    width: 100%;
}

#fixed-inner {
    background: orange;
    border-left: 2px solid blue;
    border-top: 2px solid blue;
    height: 30px;
    margin-left: 420px; /* 2x #col2 width + #wrapper padding-left */
    position: absolute;
    width: 100%;
}

Live Demo: http://jsfiddle.net/hWCub/