vertical una sirve que poner personalizar personalizado pero para ocultar funcione desplazamiento como barra html css overflow css-position

html - una - ¿Cómo evitar que un elemento posicionado absolutamente afecte a la barra de desplazamiento?



scroll personalizado (9)

Considere una entrada de sugerencia automática que se encuentre en un contenedor con algo de contenido y una barra de desplazamiento vertical:

Cuando se muestran sugerencias de autosugestión, deben aparecer en la parte superior del contenido sin afectar la barra de desplazamiento del contenedor .

Espero obtener:

Tenga en cuenta que la barra de desplazamiento es exactamente la misma que la anterior.

Pero, obtengo lo siguiente:

Tenga en cuenta que la barra de desplazamiento se ve afectada y las sugerencias se cortan.

¿Por qué las sugerencias absolutamente posicionadas afectan la barra de desplazamiento del contenedor?

¿Cómo arreglarías eso?

Área de juegos aquí

Notas:

  • Al desplazarse por el contenedor, la entrada y las sugerencias deben moverse juntas.
  • Se le permite modificar el HTML, pero la entrada y la lista de sugerencias deben permanecer dentro de .autosuggest (considere .autosuggest como un componente de terceros cuyo HTML no se puede cambiar, pero puede cambiar su CSS).
  • Puedes usar flexbox, si te ayuda.
  • Estoy buscando una solución CSS única. No Javascript por favor.

.container { height: 100px; width: 300px; margin-top: 50px; overflow-y: auto; border: 1px solid black; } .autosuggest { position: relative; width: 250px; } .input { font-size: 16px; width: 230px; padding: 5px 10px; border: 0; background-color: #FFEBBF; } .suggestions { list-style-type: none; margin: 0; padding: 5px 10px; width: 230px; background-color: #85DDFF; position: absolute; } .content { width: 120px; padding: 5px 10px; }

<div class="container"> <div class="autosuggest"> <input class="input" type="text" value="input"> </div> <div class="content"> content content content content content content content content content content </div> </div> <div class="container"> <div class="autosuggest"> <input class="input" type="text" value="input"> <ul class="suggestions"> <li>suggestion 1</li> <li>suggestion 2</li> <li>suggestion 3</li> <li>suggestion 4</li> <li>suggestion 5</li> <li>suggestion 6</li> <li>suggestion 7</li> <li>suggestion 8</li> <li>suggestion 9</li> </ul> </div> <div class="content"> content content content content content content content content content content </div> </div>


  • Cuando se muestran sugerencias de sugerencia automática, deben aparecer sobre el contenido sin afectar la barra de desplazamiento del contenedor.
  • Al desplazar el contenedor, la entrada y las sugerencias deben moverse juntas.

Esto no puede hacerse solo con CSS.

Para que las suggestions aparezcan en la parte superior del container del container , sin recortar, debe tener la position: absolute y ninguno de sus elementos principales ( autosuggest y container ) puede ser position: relative .

El lado negativo es que las suggestions no se moverán en scroll.

Para que las suggestions muevan con scroll, uno de sus padres ( autosuggest o container ) debe ser position: relative .

El lado negativo es que, como el container no está overflow: visible , se recortará

Como ya se sugirió, y se supone que la input debe estar dentro del elemento autosuggest , cambiar la position: relative en el autosuggest a position: absolute , por lo que la input permanece con suggestions en desplazamiento, probablemente sea la mejor, aunque establezca z-index en Cada container será necesario para evitar superposiciones extrañas.

Pero si el proveedor del componente de terceros , ... :) ..., pudiera ser convencido de que la input podría ubicarse fuera del elemento de autosuggest , se podría obtener un poco más de control, usando solo CSS, tanto del suggestions y el content y sus diseños, basados ​​en si la input tiene un enfoque o no, ...

... donde esta muestra podría ser un buen comienzo (haga clic en la input para mostrar suggestions ).

.container { background-color: white; width: 300px; min-height: 100px; margin-top: 50px; border: 1px solid black; overflow: auto; position: relative; } .autosuggest { position: relative; width: 250px; z-index: 1; } .input { font-size: 16px; width: 245px; padding: 5px 10px; border: 0; background-color: #FFEBBF; position: relative; z-index: 1; } .suggestions { list-style-type: none; margin: 0; padding: 5px 10px; width: 245px; background-color: #85DDFF; display: none; } .content { position: absolute; left: 0; top: 0; right: 0; bottom: 0; padding: 35px 10px 5px 10px; overflow: auto; z-index: 0; } input:focus ~ .autosuggest .suggestions { display: block; }

<div class="container"> <input class="input" type="text" value="input"> <div class="autosuggest"> <ul class="suggestions"> <li>suggestion 1</li> <li>suggestion 2</li> <li>suggestion 3</li> <li>suggestion 4</li> <li>suggestion 5</li> <li>suggestion 6</li> <li>suggestion 7</li> <li>suggestion 8</li> <li>suggestion 9</li> </ul> </div> <div class="content"> content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content </div> </div> <div class="container"> <input class="input" type="text" value="input"> <div class="autosuggest"> <ul class="suggestions"> <li>suggestion 1</li> <li>suggestion 2</li> <li>suggestion 3</li> <li>suggestion 4</li> <li>suggestion 5</li> </ul> </div> <div class="content"> content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content </div> </div>



Agregue esto a su CSS:

.input:focus + .suggestions { position: fixed; display: block; }

Y agregue display: none; a .suggestions en tu CSS.

Violín here .


Esto parece un poco torpe y tiene una pequeña advertencia, pero se trata simplemente de modificaciones de estructura CSS / no HTML.

Esencialmente, hago que el .container el padre principal en lugar de tratar de trabajar desde un nivel inferior ( .autosuggest ). Paso a paso:

  • position: relative movimiento position: relative hasta .container
  • Haga que .autosuggest posicione absolutamente (por defecto arriba / izquierda a 0px).
    • Dale un índice z más alto para que siempre esté arriba
  • haga que .content posicione absolutamente los cuatro lados 0px para que tenga el mismo tamaño que .container
  • Mueva la barra de desplazamiento de desbordamiento a la div .content
  • (Aquí está la advertencia) Establezca el relleno superior de .content a la altura de .input + el relleno realmente deseado. De lo contrario, el .content está detrás del elemento de entrada.

Y terminas con esto:

.container { height: 100px; width: 300px; margin-top: 50px; border: 1px solid black; position: relative; } .autosuggest { width: 250px; position: absolute; z-index: 50; } .input { font-size: 16px; width: 230px; padding: 5px 10px; border: 0; background-color: #FFEBBF; } .autosuggest .input:focus ~ .suggestions{ display: block; } .suggestions { display: none; list-style-type: none; margin: 0; padding: 5px 10px; width: 230px; background-color: #85DDFF; } .content { overflow-y: auto; position: absolute; top: 0; left: 0; right: 0; bottom: 0; padding: 28px 10px 5px; }

<div class="container"> <div class="autosuggest"> <input class="input" type="text" value="input"> <ul class="suggestions"> <li>suggestion 1</li> <li>suggestion 2</li> <li>suggestion 3</li> <li>suggestion 4</li> <li>suggestion 5</li> <li>suggestion 6</li> <li>suggestion 7</li> <li>suggestion 8</li> <li>suggestion 9</li> </ul> </div> <div class="content"> content content<br >content content content content content<br ><br ><br ><br ><br ><br >content content content </div> </div>

También agregué algunos mostrando / ocultando para el cuadro autosuggest, porque se ve bien.

.autosuggest .input:focus ~ .suggestions{ display: block; } .suggestions { display: none; }

Trabajando jsFiddle.

Probado FF 43, Chrome 47

Al desplazar el contenedor, la entrada y las sugerencias deben moverse juntas.

Es muy probable que esto requiera JavaScript. Por definición, al establecer las sugerencias en posición absoluta, se eliminan del resto del flujo de contenido. Podrías establecer una altura en .suggestions div y desplazarla por separado, pero ese desplazamiento no puede (que yo sepa) estar vinculado al desplazamiento .content si está posicionado absolutamente (de nuevo, usando solo CSS).

Algo como:

$(''.content'').on(''scroll'', function () { $(''.autosuggest .suggestions'').scrollTop($(this).scrollTop()); });

¿Por qué las sugerencias absolutamente posicionadas afectan la barra de desplazamiento del contenedor?

Técnicamente hablando, los elementos absolutamente posicionados no afectan la altura de los padres. Sin embargo, todavía se ven como contenido del elemento, contenido que se desborda (al menos en este caso).

La propiedad de desbordamiento especifica si se debe recortar contenido, representar barras de desplazamiento o simplemente mostrar contenido cuando se desborda su contenedor de nivel de bloque. ( de MDN )

Como .container tiene un desbordamiento configurado para desplazarse, muestra una barra de desplazamiento porque uno de sus hijos desborda el cuadro delimitador. Si cambia el desbordamiento a oculto, ocultará todo el contenido extendido y se establecerá en visible, verá que el .autosuggest extiende más allá del .container , pero también lo hace .content (ya que también es el contenido que amplía el cuadro delimitador).

Verá una barra de desplazamiento porque el contenido .suggest se extiende visualmente más allá del bloque .container , aunque esté posicionado de forma absoluta.


Fácil, quitar

position: relative

de la clase .autosuggest y agregar a la clase .container


Qué tal esto:

  • mover contenedor exterior autosugerido
  • dé al contenido el mismo margen que la altura de entrada (si está utilizando MENOS / SASS, debería poder calcularlo)
  • soltar el autosugestión para ocupar el espacio del margen

Mis cambios en el CSS tienen un comentario al lado de ellos. Tenga en cuenta que esto solo se probó en Chrome. También es probable que pueda optimizar el HTML un poco, como eliminar el contenedor en el ejemplo, pero probablemente tenga varios elementos allí.

el HTML:

<div class="autosuggest"> <input class="input" type="text" value="input"> <ul class="suggestions"> <li>suggestion 1</li> <li>suggestion 2</li> <li>suggestion 3</li> <li>suggestion 4</li> <li>suggestion 5</li> <li>suggestion 6</li> <li>suggestion 7</li> <li>suggestion 8</li> <li>suggestion 9</li> </ul> </div> <div class="container"> <div class="content"> content content content content content content content content content content </div> </div>

el CSS:

.container { height: 100px; width: 300px; overflow-y: auto; border: 1px solid black; } .autosuggest { position: relative; top:29px; /* height of input */ left:1px; /* width of container border */ width: 250px; } .input { font-size: 16px; width: 230px; padding: 5px 10px; border: 0; background-color: #FFEBBF; } .suggestions { list-style-type: none; margin: 0; padding: 5px 10px; width: 230px; background-color: #85DDFF; position: absolute; } .content { width: 120px; margin-top: 29px; /* height of input */ padding: 5px 10px; }


Todo lo que tienes que hacer es agregar las propiedades del índice z a .autosuggest y .suggestions aquí es un ejemplo de código de codepen

http://codepen.io/HTMLNoob/pen/EPEXKN

.autosuggest { z-index: -10; width: 250px; } .suggestions { list-style-type: none; margin: 0; padding: 5px 10px; width: 230px; background-color: #85DDFF; position: absolute; z-index: 10; }

ACTUALIZAR:

creo que esto es lo que estás buscando

http://jsbin.com/fegibaboyo/1/edit?html,css,output

Nota: Desplácese sobre la entrada con sugerencias.

ACTUALIZACIÓN2:

http://jsbin.com/mojopuboku/edit?html,css,output

Aquí está la nueva respuesta.

He probado esta respuesta en la mayoría de los navegadores (Firefox, Chrome, Opera) y todos tienen los mismos resultados. (No estoy seguro acerca de Safari, porque no puedo instalar Safari en mi Windows XP)


puede hacerlo en el estilo "solo css" SOLAMENTE si los elementos de la sugerencia 1,2,3 no serán hijos del elemento "input".

por ejemplo:

<input> content content </input> suggestion1 suggestion2 suggestion3

o como ejemplo de trabajo, sugerir htmlnoob http://jsbin.com/mojopuboku/edit?html,css,output

otra solución, puede funcionar solo en navegadores antiguos, como ie5.


.autosuggest { position: fixed; /* add position:fixed */ } .suggestions { /* remove position:absolute */ }