31 votes

Comment prévenir une position absolue de l'élément à affecter la barre de défilement?

Envisager une autosuggest entrée assis dans un récipient avec un contenu et d'une barre de défilement verticale:

enter image description here

Lorsque autosuggest suggestions sont affichés, ils devraient apparaître sur le dessus du contenu sans affecter le conteneur de la barre de défilement.

Je m'attends à obtenir:

enter image description here

Notez que la barre de défilement est exactement le même que ci-dessus.

Mais, je reçois le texte suivant:

enter image description here

Notez que la barre de défilement est affectée, et les suggestions sont coupés.

Pourquoi absolument positionné suggestions affecter conteneur de la barre de défilement?

Comment voulez-vous résoudre ce problème?

Aire de jeux ici

Notes:

  • Lors du défilement du conteneur, l'entrée et les suggestions doivent avancer ensemble.
  • Vous êtes autorisé à modifier le code HTML, mais l'entrée et la liste de suggestions doivent rester à l'intérieur de .autosuggest (tenir compte des .autosuggest comme un tiers de la composante dont le HTML ne peut pas être modifié, mais vous pouvez modifier son CSS).
  • Vous pouvez utiliser flexbox, si cela aide.
  • Je suis à la recherche pour le CSS seule solution. Pas de Javascript s'il vous plaît.

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

11voto

LGSon Points 1306
  • Lorsque autosuggest suggestions sont affichés, ils devraient apparaître sur le dessus du contenu sans affecter le conteneur de la barre de défilement.
  • Lors du défilement du conteneur, l'entrée et les suggestions doivent avancer ensemble.

Cela ne peut être fait avec CSS.

Pour avoir suggestions apparaît en haut de l' containers'contenu, non coupé, il doit disposer d' position: absolute et aucun de ses parents (autosuggest et container) peuvent être position: relative.

L'inconvénient c'est qu' suggestions ne se déplace pas sur de défilement.

Pour suggestions à se déplacer avec de défilement, l'un de ses parents (autosuggest ou container) doit être position: relative.

Le côté vers le bas avec ce qui est, et que l' containers'n'est pas overflow: visible, il sera découpé


Comme l'a déjà suggéré, et a assumé l' input doit être à l'intérieur de l' autosuggest élément, la modification de l' position: relative sur le autosuggest de position: absolute, de sorte que l' input séjours en suggestions sur parchemin, sera probablement le meilleur, bien que le réglage z-index sur chaque container sera nécessaire pour éviter les impairs qui se chevauchent.

Mais si le fournisseur de la troisième partie de la composante,... :) ..., peut être parlé dans une version où l' input pourraient être placés à l'extérieur de l' autosuggest élément, on pourrait obtenir un peu plus de contrôle, à l'aide de CSS, à la fois de l' suggestions et de la content et leurs mises en page, en fonction de si input a le focus ou pas,...

... où cet exemple peut-être pourrait être un bon début (cliquez sur l' input montrer 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>

7voto

DACrosby Points 3736

Cela semble un peu janky approche et a une petite mise en garde, mais c'est de la pure CSS/ HTML non modifications de la structure.

Essentiellement, je fais l' .container le parent principal au lieu d'essayer de travailler à partir d'un niveau inférieur (.autosuggest). Étape par étape:

  • Déplacer position: relative jusqu'à .container
  • Faire l' .autosuggest position absolue (haut / gauche par défaut pour 0px).
    • Donnez-lui un z-index supérieur de sorte qu'il est toujours au top
  • faire .content positionné absolument tous les quatre côtés 0px donc c'est de la même taille que .container
  • Déplacer le dépassement de la barre de défilement à l' .content div
  • (voici la mise en garde) le Jeu en haut de rembourrage .content de la hauteur de l' .input + le fait désiré rembourrage. Sinon, l' .content est derrière l'élément d'entrée.

Et on se retrouve avec ceci:

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

J'ai aussi ajouté quelques-affichage/ masquage de la autosuggest boîte, parce que c'est joli.

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

Travail jsFiddle.

Testé 43 FF, Chrome 47


Lors du défilement du conteneur, l'entrée et les suggestions doivent avancer ensemble.

Ce sera plus que probablement besoin de JavaScript. Par définition, la définition de la des suggestions de position absolue supprime le reste de l'écoulement du contenu. Vous pouvez définir une hauteur sur l' .suggestions div et faites défiler séparément, mais que le défilement ne peut pas (à ma connaissance) d'être liés à l' .content de défilement si il est en position absolue (encore une fois, à l'aide de CSS tout seul).

Quelque chose comme:

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

Pourquoi absolument positionné suggestions affecter conteneur de la barre de défilement?

Techniquement parlant, les éléments en position absolue n'affectent pas le parent de la hauteur. Cependant, ils sont toujours considérés comme contenu de l'élément de contenu qui déborde (au moins dans ce cas).

Le débordement de la propriété spécifie si le clip de contenu, de rendre les barres de défilement ou tout simplement le contenu de l'affichage quand il déborde de son bloc conteneur de niveau. (à partir de MDN)

Depuis .container a débordement mis à défiler, il affiche une barre de défilement parce que l'un de ses enfants déborde de la boîte englobante. Si vous modifiez le débordement caché ça va tout masquer l'extension de contenu et visible, vous verrez l' .autosuggest étendre au-delà de l' .container, mais le fait - .content (puisque c'est aussi de contenu qui s'étend de la boîte englobante).

Vous voyez une barre de défilement parce que l' .suggest visuellement le contenu s'étend au-delà de l' .container bloc, même s'il est en position absolue.

4voto

HTMLNoob Points 493

Tout ce que vous avez à faire est d'ajouter z-index propriétés .autosuggest et .suggestions voici un exemple de code à partir 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;
}

Mise à JOUR:

Je crois que c'est ce que vous cherchez

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

Remarque: Passez la souris sur l'entrée avec des suggestions.

UPDATE2:

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

Voici la nouvelle réponse.

J'ai testé cette réponse tout au long de la plupart des navigateurs(Firefox, Chrome, Opera) et effectuer les mêmes résultats.(Je ne suis pas sûr à propos de Safari, parce que je suis incapable d'installer Safari sur mon Windows XP)

1voto

Tate Thurston Points 327

Pourquoi ne pas simplement tirer les ul et li éléments de la div conteneur, puis déplacer des suggestions par l'un négatif de position dominante?

http://jsbin.com/ficalu/edit?html,css,sortie

Mise à jour: Changement .autosuggest position: absolute

http://jsbin.com/gezimi/edit?html,css,sortie

1voto

Jamie Paterson Points 74

Facile, enlever

position: relative

à partir de la classe .autosuggest et ajouter à la classe .conteneur

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X