CSS overflow-x: visível; e estouro-y: oculto; causando problema na barra de rolagem

455

Suponha que você tenha algum estilo e a marcação:

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>

Quando você vê isso. O <ul>possui uma barra de rolagem na parte inferior, embora eu tenha especificado valores visíveis e ocultos para o estouro x / y.

(observado no Chrome 11 e ópera (?))

Eu estou supondo que deve haver alguma especificação do w3c ou algo dizendo isso para acontecer, mas para a minha vida eu não consigo entender o porquê.

JSFiddle

UPDATE: - Encontrei uma maneira de obter o mesmo resultado adicionando outro elemento ao redor do ul. Confira.

James Khoury
fonte
Qual é o resultado desejado? jsfiddle.net/Kyle_Sevenoaks/3xv6A/2
Kyle
@ kyle deve parecer um pouco mais com: jsfiddle.net/3xv6A/5 Infelizmente, se eu definir, overflow-x hidden;ele remove o pergaminho, mas como eu preciso dos elementos li para ocultar a borda na parte inferior, para que ele tenha o efeito tracejado desejado. Não entendo por que overflow-x: visiblecria uma barra de rolagem. Não deveria afaik.
James Khoury
@JamesKhoury, você pode elaborar um pouco a sua solução? Eu realmente não posso fazê-lo funcionar
George Katsanos
1
@GeorgeKatsanos A solução alternativa: jsfiddle.net/3xv6A/9 baseia-se no pai ou na mãe overflow: hidden;e em um filho inserido ao redor do <ul>ser overflow: visible.
James Khoury
@JamesKhoury que você acha que pode trabalhar para embed.plnkr.co/2rbaISwvzuKhyPEFpBKD
George Katsanos

Respostas:

680

Depois de uma pesquisa séria, parece que encontrei a resposta para minha pergunta:

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

No Gecko, Safari, Opera, 'visível' se torna 'automático' também quando combinado com 'oculto' (em outras palavras: 'visível' se torna 'automático' quando combinado com qualquer outra coisa diferente de 'visível'). Gecko 1.8, Safari 3, Opera 9.5 são bastante consistentes entre eles.

também a especificação do W3C diz:

Os valores calculados de 'overflow-x' e 'overflow-y' são os mesmos que os valores especificados, exceto que algumas combinações com 'visible' não são possíveis: se um for especificado como 'visible' e o outro for 'scroll' ou 'automático', então 'visível' é definido como 'automático'. O valor calculado de 'overflow' é igual ao valor calculado de 'overflow-x' se 'overflow-y' for o mesmo; caso contrário, é o par de valores calculados de 'overflow-x' e 'overflow-y'.

Versão curta:

Se você estiver usando visiblepara um overflow-xou overflow-youtro algo que não seja visiblepara o outro, o visiblevalor será interpretado como auto.

James Khoury
fonte
263
Entendo que o W3C o especifique dessa maneira, mas qual é a motivação por trás disso? Acho um comportamento bastante estranho e inconsistente, resultando em soluções alternativas complicadas que exigem a adição de elementos HTML triviais.
Erwin
21
@ Erwin, eu concordo, espero que alguém decida atualizar as especificações.
22412 James Khoury
124
Você está certo, mas não faz sentido. O motivo mais comum para você querer xey é que você pode tornar um oculto e o outro visível.
Rescuecreative
91
Isso é incapacitante. Por que não podemos permitir overflow-x:visibledurante overflow-y:hiddenum hack pai / filho? Beliche bonito, IMO.
Slink
34
Isso é totalmente incapacitante. Eu estava tentando criar um monte de links suspensos em uma barra de navegação do Bootstrap horizontalmente, mas isso interrompe os menus suspensos nos quais se baseia overflow-y: visible. Boo CSS!
Andy
131

outro truque barato, que parece fazer o truque:

style="padding-bottom: 250px; margin-bottom: -250px;"no elemento em que o estouro vertical está sendo cortado, 250representando quantos pixels você precisa para o menu suspenso etc.

Justin Krause
fonte
6
muito obrigado, embora isso pareça hacky, mas parece ser a melhor maneira de resolver o problema. Estouros são terríveis em css :(
Serge Eremeev 13/03
11
Isso faz com que a barra de rolagem horizontal parecem tão longe para baixo
nafg
2
Isso também bloqueia eventos de ponteiro para 250 pixels abaixo do elemento. Mas eu encontrei uma maneira de contornar isso, e esta solução é o que estou usando.
Chris Chudzicki
2
Dois anos depois e essa ainda parece ser a melhor resposta para esse problema ... Felizmente, com mais um navegador (Microsoft Edge) entrando no projeto de código-fonte aberto Chromium, veremos um desenvolvimento mais rápido dos recursos do navegador que importam e melhor navegador compatibilidade.
Spencer O'Reilly
No meu cenário particular, onde a remoção position: relativeou o uso de wrappers não era possível, essa era a única solução que funcionava, embora também exigisse a adição de muitas margens feias aos elementos filho dentro do elemento que eu queria definir overflow-x: hiddenpara compensar o hacky preenchimento. Isso me salvou, no entanto, obrigado!
Philip Stratford
81

Originalmente, encontrei uma maneira CSS de contornar isso ao usar o plug-in Cycle jQuery. Ciclo usa JavaScript para definir meu slide como overflow: hidden, portanto, ao definir minhas fotos com width: 100%aparência de corte vertical, forço-as a ficarem visíveis !importante evitar mostrar a animação do slide fora da caixa que definioverflow: hidden para a div contêiner do deslizar. Espero que funcione para você.

UPDATE - Nova solução:

Problema original -> http://jsfiddle.net/xMddf/1/ (Mesmo se eu o usar, overflow-y: visibleele se tornará "automático" e, na verdade, "rolar").

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

A nova solução -> http://jsfiddle.net/xMddf/2/ (Encontrei uma solução alternativa usando uma div wrapper para aplicar overflow-xe overflow-ya diferentes elementos DOM, como James Khoury aconselhou sobre o problema de combinar visiblee hiddenum único elemento DOM).

#wrapper {
    height: 100px;
    overflow-y: visible;
}
#content {
    width: 200px;
    overflow-x: hidden;
}
Macumbaomuerte
fonte
12
Como isso se aplica? Parece não funcionar no estouro-x ou estouro-y.
James Khoury
1
@Macumbaomuetre Isso é mais claro, obrigado +1. É semelhante à "atualização" que adicionei. Originalmente eu não era capaz de alterar o div acondicionamento e minha solução acabou semelhante a: jsfiddle.net/3xv6A/338
James Khoury
9
Esta solução não se aplica. A questão é overflow-x:visible;e overflow-y:hidden. Não o contrário.
Jakobovski
1
@TomasJansson @Edward Ele faz o trabalho, você só tem que trocar onde você aplicar o overflow-xe -y: violino atualizados .
Apenas um aluno
1
isso falha assim que o invólucro ganha uma largura por algum motivo - jsfiddle.net/ad1941k9/16
David Meister
10

Eu me deparei com esse problema ao tentar criar uma barra lateral posicionada fixa com conteúdo rolável verticalmente e filhos posicionados absolutos aninhados para serem exibidos fora dos limites da barra lateral .

Minha abordagem consistiu em aplicar separadamente:

  • uma overflow: visiblepropriedade para o elemento da barra lateral
  • uma overflow-y: autopropriedade para o wrapper interno da barra lateral

Por favor, verifique o exemplo abaixo ou um código de acesso online .

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
fonte
2
Tenho certeza de que esta é a mesma solução que outras pessoas apresentaram, exceto em autovez de hidden.
James Khoury
@JamesKhoury Mas este é o único que eu consigo compreender porque aponta o uso deposition
Guichi
7

Usei a content+wrapperabordagem ... mas fiz algo diferente do mencionado até agora: verifiquei se os limites do meu wrapper NÃO estavam alinhados com os limites do conteúdo na direção em que eu queria estar visível .

Nota importante: Foi fácil o suficiente para obter a content+wrapper, same-boundsabordagem ao trabalho em um navegador ou outra, dependendo de várias combinações CSS position, overflow-*etc ... mas eu nunca poderia usar essa abordagem para obtê-los todos correto (Edge, Chrome, Safari,. ..)

Mas quando eu tinha algo como:

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

... todos os navegadores estavam felizes.

dsdsdsdsd
fonte
6

Agora existe uma nova maneira de resolver esse problema - se você remover a posição: relativa do contêiner que precisa ter o estouro-y visível, você poderá ter o estouro-y visível e o estouro-x oculto e vice-versa (ter o estouro- x visível e excedente-y oculto, apenas verifique se o contêiner com a propriedade visible não está relativamente posicionado).

Veja esta postagem do CSS Tricks para obter mais detalhes - funcionou para mim: https://css-tricks.com/popping-hidden-overflow/

Alexandra
fonte
2
mas isso exigiria algum javascript para posicionar o elemento corretamente se ele é absoluto
gaurav5430