CSS overflow-x: видимый; и переполнение-у: скрыто; вызывая проблему полосы прокрутки

455

Предположим, у вас есть стиль и разметка:

ul
{
  white-space: nowrap;
  overflow-x: visible;
  overflow-y: hidden;
/* added width so it would work in the snippet */
  width: 100px; 
}
li
{
  display: inline-block;
}
<div>
  <ul>
    <li>1</li> <li>2</li> <li>3</li>
    <li>4</li> <li>5</li> <li>6</li>
    <li>7</li> <li>8</li> <li>9</li>
    <li>1</li> <li>2</li> <li>3</li>
    <li>4</li> <li>5</li> <li>6</li>
    <li>7</li> <li>8</li> <li>9</li>
    <li>1</li> <li>2</li> <li>3</li>
    <li>4</li> <li>5</li> <li>6</li>
    <li>7</li> <li>8</li> <li>9</li>
  </ul>
</div>

Когда вы смотрите это. <ul>Имеет полосу прокрутки в нижней части , даже если я указал видимые и скрытые значения для перелива х / у.

(наблюдается на Chrome 11 и Opera (?))

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

JSFiddle

ОБНОВЛЕНИЕ: - Я нашел способ добиться того же результата, добавив еще один элемент, обернутый вокруг ul. Проверьте это.

Джеймс Хури
источник
Какой ваш желаемый результат? jsfiddle.net/Kyle_Sevenoaks/3xv6A/2
Кайл
@kyle это должно выглядеть немного больше как: jsfiddle.net/3xv6A/5 К сожалению, если я установлю overflow-x hidden;его, он удалит прокрутку, но мне нужны элементы li, чтобы скрыть границу внизу, чтобы получить желаемый пунктирный эффект. Я не понимаю, почему overflow-x: visibleсоздает полосу прокрутки. Это не должно afaik.
Джеймс Хури
@JamesKhoury Вы можете немного рассказать о своем решении? Я не могу заставить его работать
Джордж Кацанос,
1
@GeorgeKatsanos Обходной путь: jsfiddle.net/3xv6A/9 полагается на родительское существо overflow: hidden;и ребенка, вставленного вокруг <ul>существа overflow: visible.
Джеймс Хури
@JamesKhoury Как вы думаете, это может работать для embed.plnkr.co/2rbaISwvzuKhyPEFpBKD
Джордж Кацанос

Ответы:

682

После некоторых серьезных поисков, кажется, я нашел ответ на свой вопрос:

от: http://www.brunildo.org/test/Overflowxy2.html

В Gecko, Safari, Opera «видимый» становится «автоматическим» также в сочетании со «скрытым» (другими словами: «видимый» становится «автоматическим» в сочетании с чем-либо, отличным от «видимого»). Gecko 1.8, Safari 3, Opera 9.5 довольно последовательны среди них.

также спецификация W3C гласит:

Вычисленные значения «overflow-x» и «overflow-y» совпадают с их указанными значениями, за исключением того, что некоторые комбинации с «visible» невозможны: если одно указано как «visible», а другое - «scroll» или «auto», тогда «visible» устанавливается на «auto». Вычисленное значение «переполнения» равно вычисленному значению «переполнения-x», если «переполнение-у» совпадает; в противном случае это пара вычисляемых значений 'overflow-x' и 'overflow-y'.

Укороченная версия:

Если вы используете visibleдля одного overflow-xили overflow-yи иного, чем visibleдля другого, visibleзначение интерпретируется как auto.

Джеймс Хури
источник
264
Я понимаю, что W3C определяет это таким образом, но какова мотивация этого? Я нахожу это довольно странным и противоречивым поведением, приводящим к грязным обходным путям, которые требуют добавления тривиальных HTML-элементов.
Эрвин
21
@ Эрвин Я согласен, надеюсь, кто-то решит обновить спецификацию.
Джеймс Хури
125
Ты прав, но это не имеет смысла. Самая распространенная причина, по которой вы хотите использовать x и y, заключается в том, что вы можете сделать одну скрытой, а другую видимой.
спасательно-творческое
91
Это наносит вред. Почему мы не можем позволить overflow-x:visibleво время overflow-y:hiddenбез взлома родителей / детей? Хорошая койка, ИМО.
Slink
34
Это полностью наносит вред. Я пытался сделать несколько выпадающих ссылок в навигационной панели Bootstrap по горизонтали, но это ломает выпадающие списки, на которые можно положиться overflow-y: visible. Бу CSS
Энди
131

еще один дешевый хак, который, кажется, делает свое дело:

style="padding-bottom: 250px; margin-bottom: -250px;"на элементе, где вертикальное переполнение становится обрезанным, с 250представлением столько пикселей, сколько нужно для раскрывающегося списка, и т. д.

Джастин Краузе
источник
6
Большое спасибо, хотя это кажется хакерским, но, похоже, это лучший способ решить проблему. Переполнения ужасны в css :(
Сергей Еремеев,
11
Это заставляет горизонтальную полосу прокрутки появляться так далеко вниз
nafg
2
Это также блокирует события указателя на 250 пикселей ниже элемента. Но я нашел способ обойти это, и этим решением я и пользуюсь.
Крис Чудзицки
2
Спустя 2 года, и это все еще кажется лучшим решением этой проблемы ... Надеюсь, с помощью еще одного браузера (Microsoft Edge), подключенного к проекту с открытым исходным кодом Chromium, мы увидим более быструю разработку важных функций браузера, а также лучший браузер совместимость.
Спенсер О'Рейли
В моем конкретном сценарии, где удаление position: relativeили использование оберток было невозможно, это было единственное решение, которое работало, хотя для этого также требовалось добавить много уродливых полей в дочерние элементы внутри элемента, который я хотел установить, overflow-x: hiddenчтобы компенсировать хакерство. обивка. Это спасло меня, хотя, так что спасибо!
Филипп Стратфорд
81

Первоначально я нашел способ обойти это при использовании плагина Cycle jQuery. Цикл использует JavaScript для установки моего слайда overflow: hidden, поэтому при установке моих изображений width: 100%на изображения они будут выглядеть вертикально обрезанными, и поэтому я заставил их быть видимыми !importantво избежание показа анимации слайда из коробки, которую я установил overflow: hiddenдля контейнера div элемента горка. Надеюсь, это работает для вас.

ОБНОВЛЕНИЕ - Новое решение:

Оригинальная проблема -> http://jsfiddle.net/xMddf/1/ (даже если я использую overflow-y: visibleэто становится «авто» и фактически «прокручивать».)

#content {
    height: 100px;
    width: 200px;
    overflow-x: hidden;
    overflow-y: visible;
}

Новое решение -> http://jsfiddle.net/xMddf/2/ (я нашел обходной путь, использующий div- обертку для применения overflow-xи overflow-yк различным элементам DOM, как Джеймс Хури советовал по проблеме объединения visibleи hiddenдля одного элемента DOM.)

#wrapper {
    height: 100px;
    overflow-y: visible;
}
#content {
    width: 200px;
    overflow-x: hidden;
}
Macumbaomuerte
источник
13
Как это применимо? Кажется, он не работает на overflow-x или overflow-y.
Джеймс Хури
1
@Macumbaomuetre Это понятнее, спасибо +1. Это похоже на "обновление", которое я добавил. Первоначально я не смог изменить упаковочный div, и мое решение оказалось похожим на: jsfiddle.net/3xv6A/338
Джеймс Хури
10
Это решение не применяется. Вопрос в том overflow-x:visible;и overflow-y:hidden. А не наоборот.
Якобовский
1
@TomasJansson @Edward Это делает работу, вы просто должны свопу , где вы применяете overflow-xи -y: обновленную скрипку .
Просто студент
1
это терпит неудачу, как только обёртка по какой-то причине набирает ширину - jsfiddle.net/ad1941k9/16
Дэвид Мейстер
10

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

Мой подход состоял в том, чтобы отдельно применять:

  • overflow: visibleсвойство элемента боковой панели
  • overflow-y: autoсвойство боковой панели внутренней обертки

Пожалуйста, проверьте пример ниже или онлайн-коде .

html {
  min-height: 100%;
}
body {
  min-height: 100%;
  background: linear-gradient(to bottom, white, DarkGray 80%);
  margin: 0;
  padding: 0;
}

.sidebar {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: 200px;
  overflow: visible;  /* Just apply overflow-x */
  background-color: DarkOrange;
}

.sidebarWrapper {
  padding: 10px;
  overflow-y: auto;   /* Just apply overflow-y */
  height: 100%;
  width: 100%;
}

.element {
  position: absolute;
  top: 0;
  right: 100%;
  background-color: CornflowerBlue;
  padding: 10px;
  width: 200px;
}
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
<div class="sidebar">
  <div class="sidebarWrapper">
    <div class="element">
      I'm a sidebar child element but I'm able to horizontally overflow its boundaries.
    </div>
    <p>This is a 200px width container with optional vertical scroll.</p>
    <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
  </div>
</div>

Андреа Карраро
источник
2
Я уверен, что это то же самое решение, что и другие, кроме как autoвместо hidden.
Джеймс Хури
@JamesKhoury Но это единственное, что я могу понять, потому что оно указывает на использованиеposition
Guichi
7

Я использовал content+wrapperподход ... но я сделал нечто иное, чем упомянуто до сих пор: я позаботился о том, чтобы границы моей оболочки не совпадали с границами содержимого в направлении, которое я хотел бы видеть .

Важное примечание: было достаточно легко заставить content+wrapper, same-boundsподход работать в одном или другом браузере в зависимости от различных комбинаций CSS position, overflow-*и т. Д., Но я никогда не мог использовать этот подход, чтобы получить их все правильно (Edge, Chrome, Safari,. ..).

Но когда у меня было что-то вроде:

  <div id="hack_wrapper" // created solely for this purpose
       style="position:absolute; width:100%; height:100%; overflow-x:hidden;">
      <div id="content_wrapper"
           style="position:absolute; width:100%; height:15%; overflow:visible;">         
          ... content with too-much horizontal content ... 
      </div>
  </div>

... все браузеры были счастливы.

dsdsdsdsd
источник
6

Теперь существует новый способ решения этой проблемы - если вы удалите position: относительный из контейнера, который должен иметь видимый overflow-y, вы можете иметь видимый overflow-y и скрытый overflow-x, и наоборот (иметь overflow- x visible и overflow-y hidden, просто убедитесь, что контейнер со свойством visible не расположен относительно.

Смотрите этот пост от CSS Tricks для более подробной информации - он работал для меня: https://css-tricks.com/popping-hidden-overflow/

Александра
источник
2
но это потребовало бы некоторого javascript для правильного позиционирования элемента, если он абсолютный
gaurav5430