Przepełnienie CSS-x: widoczne; i przelew-y: ukryty; powodując problem z paskiem przewijania

454

Załóżmy, że masz trochę stylu i znaczników:

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>

Kiedy to obejrzysz. <ul>Ma paska przewijania na dole chociaż mam określonego widocznych i ukrytych wartości przelewowym x / y.

(obserwowane w Chrome 11 i operze (?))

Domyślam się, że musi istnieć specyfikacja W3C lub coś takiego, ale przez całe życie nie mogę zrozumieć, dlaczego.

JSFiddle

AKTUALIZACJA: - Znalazłem sposób na osiągnięcie tego samego wyniku poprzez dodanie kolejnego elementu owiniętego wokół ul. Sprawdź to.

James Khoury
źródło
Jaki jest twój pożądany wynik? jsfiddle.net/Kyle_Sevenoaks/3xv6A/2
Kyle
@kyle powinien wyglądać trochę bardziej: jsfiddle.net/3xv6A/5 Niestety, jeśli overflow-x hidden;go ustawię , usuwa on przewijanie, ale ponieważ potrzebuję elementów li, aby ukryć ramkę na dole, aby uzyskać pożądany efekt przerywany. Nie rozumiem, dlaczego overflow-x: visibletworzy pasek przewijania. Nie powinno być afaik.
James Khoury
@JamesKhoury, czy możesz trochę rozwinąć swoje rozwiązanie? Naprawdę nie mogę sprawić, żeby zadziałało
George Katsanos
1
@GeorgeKatsanos Obejście: jsfiddle.net/3xv6A/9 polega na istnieniu rodzica overflow: hidden;i dziecku wstawionym wokół <ul>istoty overflow: visible.
James Khoury,
@JamesKhoury Czy uważasz, że to może działać dla embed.plnkr.co/2rbaISwvzuKhyPEFpBKD
George Katsanos

Odpowiedzi:

679

Po poważnych poszukiwaniach wydaje się, że znalazłem odpowiedź na moje pytanie:

z: http://www.brunildo.org/test/Overflowxy2.html

W Gecko, Safari, Opera „widoczne” staje się „automatyczne” także w połączeniu z „ukrytym” (innymi słowy: „widoczne” staje się „automatyczne” w połączeniu z czymkolwiek innym niż „widoczne”). Gecko 1.8, Safari 3, Opera 9.5 są dość spójne.

również specyfikacja W3C mówi:

Obliczone wartości „overflow-x” i „overflow-y” są takie same, jak ich określone wartości, z tym wyjątkiem, że niektóre kombinacje z „widocznym” nie są możliwe: jeśli jedna jest określona jako „widoczna”, a druga to „przewiń” lub „auto”, a następnie „widoczne” jest ustawione na „auto”. Obliczona wartość „przepełnienia” jest równa obliczonej wartości „przepełnienia-x”, jeżeli „przepełnienie-y” jest takie samo; w przeciwnym razie jest to para obliczonych wartości „overflow-x” i „overflow-y”.

Krótka wersja:

Jeśli używasz visibledla jednego overflow-xlub overflow-ydrugiego i dla czegoś innego niż visibledla drugiej, visiblewartość jest interpretowana jako auto.

James Khoury
źródło
263
Rozumiem, że W3C określa to w ten sposób, ale jaka jest motywacja? Uważam to za dość dziwne i niespójne zachowanie, co powoduje bałagan w obejściu, który wymaga dodania trywialnych elementów HTML.
Erwin,
21
@Erwin Zgadzam się, mam nadzieję, że ktoś zdecyduje się zaktualizować specyfikację.
James Khoury
123
Masz rację, ale to nie ma sensu. Najczęstszym powodem, dla którego chciałbyś mieć xiy jest to, że możesz uczynić jeden ukryty, a drugi widoczny.
rescuecreative
91
To jest okaleczające. Dlaczego nie możemy pozwolić overflow-x:visibleczasie overflow-y:hiddenbez hack rodzic / dziecko? Dość piętrowa, IMO.
Slink
34
To jest całkowicie okaleczające. Próbowałem zrobić kilka linków rozwijanych na pasku nawigacyjnym Bootstrap przewijanych w poziomie, ale to łamie listy rozwijane, na których się opiera overflow-y: visible. Boo CSS!
Andy,
130

kolejny tani hack, który wydaje się załatwić:

style="padding-bottom: 250px; margin-bottom: -250px;"na elemencie, w którym odcina się pionowy przelew, 250reprezentując tyle pikseli, ile potrzeba do rozwijania itp.

Justin Krause
źródło
6
dziękuję bardzo, choć wydaje się to hacking, ale wydaje się być najlepszym sposobem na rozwiązanie problemu. Przelewy są straszne w css :(
Serge Eremeev
11
To sprawia, że ​​poziomy pasek przewijania pojawia się tak daleko w dół
nafg
2
To również blokuje zdarzenia wskaźnika dla 250px poniżej elementu. Ale znalazłem sposób na obejście tego, a tego rozwiązania używam.
Chris Chudzicki
2
2 lata później i nadal wydaje się to najlepszą odpowiedzią na ten problem ... Mam nadzieję, że dzięki kolejnej przeglądarce (Microsoft Edge) wskakującej na projekt open source Chromium zobaczymy szybszy rozwój ważnych funkcji przeglądarki, a także lepszą przeglądarkę zgodność.
Spencer O'Reilly,
W moim konkretnym scenariuszu, w którym usuwanie position: relativelub używanie opakowań nie było możliwe, było to jedyne rozwiązanie, które działało, chociaż wymagało również dodawania wielu brzydkich marginesów do elementów potomnych wewnątrz elementu, który chciałem ustawić, overflow-x: hiddenaby zrekompensować hacky wyściółka. To mnie jednak uratowało, więc dzięki!
Philip Stratford
81

Pierwotnie znalazłem sposób CSS na ominięcie tego podczas korzystania z wtyczki Cycle jQuery. Cykl używa JavaScript do ustawienia slajdu overflow: hidden, więc kiedy ustawiam moje zdjęcia, width: 100%będą wyglądały na wycięte w pionie, więc zmusiłem je do widoczności !importanti unikania pokazywania animacji slajdów z pudełka, które ustawiłem overflow: hiddenna div pojemnika ślizgać się. Mam nadzieję, że Ci się uda.

AKTUALIZACJA - Nowe rozwiązanie:

Oryginalny problem -> http://jsfiddle.net/xMddf/1/ (Nawet jeśli overflow-y: visiblego użyję, staje się „automatyczny”, a właściwie „przewijać”.)

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

Nowe rozwiązanie -> http://jsfiddle.net/xMddf/2/ (Znalazłem obejście za pomocą otoki opakowania do zastosowania overflow-xi overflow-ydo różnych elementów DOM, jak doradzał James Khoury w sprawie problemu łączenia visiblei hiddenpojedynczego elementu DOM).

#wrapper {
    height: 100px;
    overflow-y: visible;
}
#content {
    width: 200px;
    overflow-x: hidden;
}
Macumbaomuerte
źródło
12
Jak to się stosuje? Nie działa na overflow-x lub overflow-y.
James Khoury
1
@Macumbaomuetre To jest jaśniejsze, dziękuję +1. Jest podobny do „aktualizacji”, którą dodałem. Początkowo nie byłem w stanie zmienić zawijanego diva,
James Khoury
9
To rozwiązanie nie ma zastosowania. Pytanie brzmi overflow-x:visible;i overflow-y:hidden. Nie na odwrót.
Jakobovski,
1
@TomasJansson @Edward To czyni pracę, po prostu trzeba się do wymiany, w którym stosuje się overflow-xi -y: zaktualizowaną skrzypce .
Tylko student
1
to się nie udaje, gdy tylko opakowanie zyska szerokość z jakiegoś powodu - jsfiddle.net/ad1941k9/16
David Meister
10

Zabrakło mi w tej kwestii, gdy próbuje zbudować stałe umieszczony w ramce z zarówno w pionie, można przewijać zawartość i zagnieżdżonych absolutny umieszczony dzieci mają być wyświetlane poza granice bocznym .

Moje podejście polegało na zastosowaniu osobno:

  • overflow: visiblenieruchomość do elementu bocznego
  • overflow-y: autowłaściwościom sidebar wewnętrzną owijkę

Sprawdź poniższy przykład lub internetowy codepen .

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>

Andrea Carraro
źródło
2
Jestem prawie pewien, że jest to takie samo rozwiązanie, jak inni, z wyjątkiem autozamiast zamiast hidden.
James Khoury
@JamesKhoury Ale ten jedyny jestem w stanie zrozumieć, ponieważ wskazuje na użycieposition
Guichi
7

Użyłem tego content+wrapperpodejścia ... ale zrobiłem coś innego niż wspomniano do tej pory: upewniłem się, że granice mojego opakowania NIE pokrywają się z granicami treści w kierunku, w którym chciałem być widoczny .

Ważna uwaga: To było dość łatwe do uzyskania content+wrapper, same-boundspodejście do pracy na jednej przeglądarce lub inny w zależności od różnych kombinacjach css position, overflow-*itp ... ale nigdy nie może korzystać z tego podejścia, aby je wszystkie poprawne (Edge, Chrome, Safari. ..).

Ale kiedy miałem coś takiego:

  <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>

... wszystkie przeglądarki były zadowolone.

dsdsdsdsd
źródło
5

Istnieje teraz nowy sposób rozwiązania tego problemu - jeśli usuniesz pozycję: krewny z kontenera, który musi mieć widoczne przepełnienie-y, możesz ukryć przepełnienie-y i przelew-x i odwrotnie (mieć przepełnienie- x widoczny i przelew-ukryty, po prostu upewnij się, że kontener z właściwością visible nie jest odpowiednio ustawiony).

Zobacz ten post z CSS Tricks, aby uzyskać więcej informacji - zadziałało dla mnie: https://css-tricks.com/popping-hidden-overflow/

Alexandra
źródło
2
ale wymagałoby to jakiegoś javascript do prawidłowego pozycjonowania elementu, jeśli jest absolutny
gaurav5430