Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent an absolutely positioned element to affect the scrollbar?

Consider an autosuggest input sitting in a container with some content and a vertical scrollbar:

enter image description here

When autosuggest suggestions are shown, they should appear on top of the content without affecting container's scrollbar.

I expect to get:

enter image description here

Note that the scrollbar is exactly the same as above.

But, I get the following:

enter image description here

Note that the scrollbar is affected, and suggestions are cut.

Why absolutely positioned suggestions affect container's scrollbar?

How would you fix that?

Playground here

Notes:

  • When scrolling the container, the input and suggestions should move together.
  • You are allowed to modify the HTML, but the input and the suggestions list should stay inside .autosuggest (consider .autosuggest as a third party component whose HTML cannot be changed, but you can change its CSS).
  • You can use flexbox, if it helps.
  • I'm looking for CSS only solution. No Javascript please.

.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>
like image 218
Misha Moroshko Avatar asked Jan 26 '16 05:01

Misha Moroshko


People also ask

Which position will keep the element in the same place regardless of scrolling?

An element with position:fixed is fixed with respect to the viewport. It stays where it is, even if the document is scrolled.

How do you stop an element from scrolling?

Disabling scroll with only CSS. There's another way to disable scrolling that is commonly used when opening modals or scrollable floating elements. And it is simply by adding the CSS property overflow: hidden; on the element you want to prevent the scroll.

What happens when an element is positioned absolutely?

Setting position: absolute An absolutely positioned element no longer exists in the normal document flow. Instead, it sits on its own layer separate from everything else.


Video Answer


1 Answers

  • When autosuggest suggestions are shown, they should appear on top of the content without affecting container's scrollbar.
  • When scrolling the container, the input and suggestions should move together.

This can't be done with CSS only.

To have suggestions appear on top of the container's content, non clipped, it has to have position: absolute and none of its parents (autosuggest and container) can be position: relative.

The down side is that suggestions will not move on scroll.

For suggestions to move with scroll, one of its parents (autosuggest or container) needs to be position: relative.

The down side with that is, and as the container's is not overflow: visible, it will be clipped


As already suggested, and assumed the input has to be within the autosuggest element, changing the position: relative on the autosuggest to position: absolute, so the input stays with suggestions on scroll, will likely be the best, though setting z-index on each container will be needed to avoid odd overlapping.

But if the provider of the third party component,... :) ..., could be talked into a version where the input could be placed outside the autosuggest element, one could get some more control, using CSS only, of both the suggestions and the content and their layouts, based on if input has focus or not,...

... where this sample maybe could be a good start (click on input to show 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>
like image 162
Asons Avatar answered Sep 18 '22 22:09

Asons