Как предотвратить абсолютно позиционированный элемент, чтобы повлиять на полосу прокрутки?
рассмотрим вход автозаполнения, сидящий в контейнере с некоторым содержимым и вертикальной полосой прокрутки:
когда отображаются предложения автозаполнения, они должны отображаться поверх содержимого не затрагивая полосу прокрутки контейнера.
Я ожидаю получить:
обратите внимание, что полоса прокрутки точно такая же, как и выше.
но, я получаю следующий:
обратите внимание, что полоса прокрутки затронута, и предложения вырезаются.
Почему абсолютно позиционированные предложения влияют на полосу прокрутки контейнера?
как бы вы это исправить?
9 ответов
это кажется немного странным подходом и имеет небольшое предостережение, но это чистый CSS/ без изменений структуры HTML.
по сути, я делаю .container
основной родитель вместо того, чтобы пытаться работать с более низкого уровня (.autosuggest
). Шаг за шагом:
- движение
position: relative
до.container
- сделать
.autosuggest
позиционируется абсолютно (верхнее / левое значение по умолчанию 0px).- дать ему более высокий Z-индекс, чтобы всегда топ!--29-->
- сделать
.content
позиционируется абсолютно все четыре стороны 0px, так что это тот же размер, что и.container
- переместите полосу прокрутки переполнения в
.content
div - (вот предостережение) установите верхнюю прокладку
.content
на высоте.input
+ желаемому обивка. В противном случае.content
находится за входным элементом.
и вы в конечном итоге с этим:
.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>
I также добавлен показ / скрытие для окна автозаполнения, потому что он выглядит красиво.
.autosuggest .input:focus ~ .suggestions{
display: block;
}
.suggestions {
display: none;
}
протестировано FF 43, Chrome 47
при прокрутке контейнера входные данные и предложения должны перемещаться вместе.
для этого, скорее всего, потребуется JavaScript. По определению, установка предложений в абсолютное положение удаляет их из остальной части потока контента. Ты мог бы ... установите высоту на .suggestions
div и прокрутите его отдельно, но эта прокрутка не может (насколько мне известно) быть привязана к .content
прокрутите, если он расположен абсолютно (опять же, используя только CSS).
что-то типа:
$('.content').on('scroll', function () {
$('.autosuggest .suggestions').scrollTop($(this).scrollTop());
});
почему абсолютно позиционированные предложения влияют на полосу прокрутки контейнера?
Технически говоря, абсолютно позиционированные элементы не влияют на высоту родителя. Тем не менее, они по-прежнему рассматриваются как содержимое элемента-содержимое, которое переполняется (по крайней мере, в этом случае).
свойство overflow указывает, следует ли обрезать содержимое, отображать полосы прокрутки или просто отображать содержимое при переполнении контейнера уровня блока. (из MDN)
С .container
и переливом набор для прокрутки, он показывает полосу прокрутки, потому что один из детей выходит за рамку. Если вы измените overflow на hidden, он скроет все расширяющееся содержимое и установите для visible вы увидите .autosuggest
расширить за .container
, но и .content
(поскольку это также контент, который расширяет ограничивающую рамку).
вы видите полосу прокрутки, потому что .suggest
содержание визуально выходит за рамки .container
блок, хотя он расположен абсолютно.
- когда отображаются предложения автозаполнения, они должны отображаться поверх содержимого, не влияя на полосу прокрутки контейнера.
- при прокрутке контейнера входные данные и предложения должны перемещаться вместе.
это не может быть сделано только с CSS.
иметь suggestions
появляются поверх container
содержание, не обрезается, он должен иметь position: absolute
и ни один из его родителей (autosuggest
и container
) может быть position: relative
.
программа suggestions
не будет двигаться по спирали.
на suggestions
для перемещения со свитком, один из его родителей (autosuggest
или container
) должен быть position: relative
.
нижняя сторона с тем, что есть, и как container
- это не overflow: visible
, то он будет обрезан
как уже предлагалось, так и предполагалось input
должно быть в пределах autosuggest
элемент, изменяющий position: relative
на autosuggest
to position: absolute
, так что input
остается с suggestions
на прокрутке, вероятно, будет лучшим, хотя настройка z-index
в каждом container
будет необходимо, чтобы избежать нечетного перекрытия.
но если поставщик компонент третьей стороны,... :) ..., можно было бы поговорить в версию, где input
может быть размещен за пределами autosuggest
элемент, можно получить больше контроля, используя только CSS, как suggestions
и content
и их макеты, основанные на if input
фокус или не.,..
... где этот образец может быть хорошим началом (нажмите на input
показать 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>
все, что вам нужно сделать, это добавить свойства z-индекса.автозавершение и .предложения Вот пример кода из 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;
}
обновление:
Я считаю, что это то, что вы ищете
http://jsbin.com/fegibaboyo/1/edit?html, css, выход
Примечание: наведите курсор на вход с предложения.
обновление 2:
http://jsbin.com/mojopuboku/edit?html, css, выход
вот новый ответ.
я протестировал этот ответ в большинстве браузеров(Firefox, Chrome, Opera), и все они выполняют одни и те же результаты.(Я не уверен в Safari, потому что я не могу установить Safari на моем Windows XP)
.autosuggest {
position: fixed; /* add position:fixed */
}
.suggestions {
/* remove position:absolute */
}
Почему бы просто не вытащить элементы ul и li из контейнера div, а затем переместить предложения вверх, установив отрицательное верхнее положение?
http://jsbin.com/ficalu/edit?html, css, выход
обновление: Изменение.autosuggest в позицию: абсолютный
добавьте это в свой CSS:
.input:focus + .suggestions {
position: fixed;
display: block;
}
и добавить display: none;
to .suggestions
в вашем CSS.
Скрипка здесь.
Как насчет этого:
- перемещение автозаполнения вне контейнера
- дайте содержимому тот же запас, что и высота ввода (если вы используете меньше/SASS, вы должны быть в состоянии вычислить это)
- падение autosuggest вниз, чтобы занять место на полях
мои изменения в CSS имеют комментарий рядом с ними. Обратите внимание, что это был протестирован только в Chrome. Вы также можете немного оптимизировать HTML, например, удалить контейнер в Примере, но у вас, вероятно, есть несколько элементов.
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>
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;
}
вы можете сделать это в стиле "только css", только если предложение 1,2,3 элементов не будет дочерним элементом элемента" input".
например:
<input>
content
content
</input>
suggestion1
suggestion2
suggestion3
или в качестве рабочего примера Thar предложить htmlnoob url в некотором верхнем беспорядке
другое исправление, может работать только в старых браузерах, таких как ie5.