user1936584
user1936584

Reputation:

Sticky div on the middle of the page

How can I make a div to stay on the middle of the page when scrolling?

I have something like this so far: https://jsfiddle.net/7wqk9fp0/2/

#D1{
    width: 500px;
    position: fixed;
    margin: auto;
    top: 50%; 
    left: 0;
    background-color: red;
    bottom: 0;
    right: 0;

}

The problem is that if the content of the div is bigger than the height of the container it won't be visible on the page. Also, how to make the height to match the content size?

Upvotes: 2

Views: 10735

Answers (4)

Mariusz Pawelski
Mariusz Pawelski

Reputation: 28922

This is probably not what OP wanted but this question comes up first in google when you search for "sicky div in the middle" so someone might find it useful.

I wanted to have "sticky" div in the middle of another div so when user scrolls page then it's still visible. The classic use case is showing loading animation that tells that some part of page is getting data. For example you might have big long list of items, user click button to get more data and you want to have sticky loader on this list that is always visible, when the list is visible.

You can simply set the top property to 50% and it should stick element in the middle of nearest scrolling container (it's often just browser window).

position: sticky;
top: 50%;

You can also use calc to center the element exactly if you know the element size.

  position: sticky;
  width: 60px;
  height: 60px;
  border: solid black;
  top: calc(50% - 30px);

Here are some examples:

document
  .getElementById("showLoaderOverlay")
  .addEventListener("click", function() {
    document
      .getElementsByClassName("second-example__div1-inside-overlay")[0]
      .classList.remove("hidden");
  });


document
  .getElementById("hideLoaderOverlay")
  .addEventListener("click", function() {
    document
      .getElementsByClassName("second-example__div1-inside-overlay")[0]
      .classList.add("hidden");
  });
.div1 {
  width: 200px;
  height: 500px;
  background-color: yellow;
}

.div2 {
  width: 200px;
  height: 800px;
  background-color: orange;
}

.div2inside {
  background-color: red;
  position: sticky;
  top: 50%;
}

.div3 {
  width: 200px;
  height: 1000px;
  background-color: pink;
}

.second-example__div1 {
  position: relative;
  z-index: 0;
}

.second-example__div1 {
  background-color: rebeccapurple;
  width: 500px;
}

.second-example__div1-inside-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.8);
  display: flex;
  justify-content: center;
}

.second-example__div1-inside-loader {
  position: sticky;
  width: 100px;
  height: 100px;
  border: solid black;
  top: calc(50% - 50px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.hidden {
  display: none;
}
<html>
<div class="div1">div1</div>
<div class="div2">
  div2
  <div class="div2inside">
    inside div 2
    <br> sticky in the middle of page
  </div>
</div>
<div class="div3">div3</div>
<h2>Other example</h2>
<button id="showLoaderOverlay">Click me and scroll</button>
<div class="second-example__div1">
  <div class="second-example__div1-inside-overlay hidden">
    <div class="second-example__div1-inside-loader">
      loading...
    </div>
  </div>
  <ul>
    <li> very</li>
    <li> big</li>
    <li> list</li>
    <li> of</li>
    <li> some</li>
    <li> items</li>
    <li>Lorem ipsum dolor sit amet consectetur adipisicing elit. Corporis, quod.</li>
    <li>Unde sed similique in laudantium doloribus obcaecati maxime debitis maiores?</li>
    <li>Nisi architecto laborum ab et ducimus non nemo tempore minima.</li>
    <li>Provident doloremque recusandae consectetur excepturi minus magnam corporis nemo dolorem!</li>
    <li>Suscipit facilis aliquam dignissimos vel nesciunt vitae, temporibus recusandae ipsam!</li>
    <li>Iste corporis ipsam in iure fuga beatae rerum expedita explicabo.</li>
    <li>Pariatur tenetur ducimus maiores, excepturi est cumque accusantium vel quia!</li>
    <li>Alias dolorem illum quisquam nihil quaerat quasi exercitationem, tenetur repudiandae!</li>
    <li>Nemo omnis enim officia incidunt consequuntur. Nesciunt illo fuga quidem?</li>
    <li>Sint fuga voluptates impedit omnis eius iusto, est assumenda at.</li>
    <li>Maiores explicabo velit facere repellat quae eveniet commodi similique aliquid!</li>
    <li>Provident saepe nostrum sit accusantium aspernatur eaque labore, asperiores ab!</li>
    <li>Veniam, quo similique accusantium cumque quasi sed officia minus ratione?</li>
    <li>Cupiditate ratione tempore magni quisquam a dolore eius aliquam itaque!</li>
    <li>Quam tenetur, nisi repellendus a harum sed molestias eius mollitia?</li>
    <li>Accusamus ipsum porro nobis natus quod delectus blanditiis cumque totam?</li>
    <li>Deleniti quia commodi porro reprehenderit voluptates cumque. Amet, minus modi.</li>
    <li>Facere beatae totam ut eaque aliquid laborum, tempora quo natus?</li>
    <li>Cumque architecto rem illo non itaque dolorum dolorem sint magnam?</li>
    <li>Necessitatibus dicta beatae ducimus ex dolores odio molestiae porro laboriosam.</li>
    <li>Alias illum iusto praesentium vitae recusandae quo, magnam error cum.</li>
    <li>Facilis, aliquam maiores soluta asperiores maxime aperiam distinctio alias assumenda?</li>
    <li>Fugit autem, corporis quasi cum cumque eos sequi molestiae quibusdam.</li>
    <li>Quisquam eveniet reiciendis cumque odio deleniti iusto nihil ratione soluta.</li>
    <li>Dignissimos recusandae quasi ipsa? Sint tempora ea delectus ullam suscipit.</li>
    <li>Repudiandae dignissimos similique quos, quaerat necessitatibus minus magnam quo commodi?</li>
    <li>Molestiae rem nemo itaque obcaecati eveniet cupiditate fugit consequuntur quibusdam.</li>
    <li>Aperiam iusto, labore asperiores dolores perferendis fugiat veritatis corrupti quis!</li>
    <li>Maiores numquam doloribus animi veritatis molestias nam voluptates fugiat voluptatibus.</li>
    <li>Fuga culpa minus nulla ex totam maxime voluptatem, perferendis labore.</li>
    <li>Dolore omnis in ipsa laboriosam dicta obcaecati fugit unde. Necessitatibus.</li>
    <li>Soluta voluptatem voluptas ullam cum ipsum repudiandae cupiditate debitis aliquam?</li>
    <li>Tempora molestias vitae adipisci id, nam voluptatibus neque perspiciatis repudiandae!</li>
    <li>Quasi iste dolorum expedita eos eaque soluta dicta ipsam quidem!</li>
    <li>Repudiandae delectus minus quas odit est nisi iusto quo atque?</li>
    <li>Voluptatibus eius expedita asperiores suscipit a rerum quis odio culpa.</li>
    <li>Consectetur dolores doloribus, tempora dolorem nemo voluptatibus! Amet, expedita nulla.</li>
    <li>Rem non aperiam porro eveniet, ex saepe voluptate molestiae. Ea!</li>
    <li>Impedit, veniam quasi beatae quaerat cupiditate hic soluta. Odio, nam!</li>
    <li>Ut non obcaecati voluptate rerum culpa aperiam! Obcaecati, voluptatibus accusamus.</li>
  </ul>

</div>
<button id="hideLoaderOverlay">Hide loader</button>
<div class="div3">div3</div>
<html>

Upvotes: 3

SidOfc
SidOfc

Reputation: 4584

I use a little trick that involves inline-block elements in a container.

It's basicly a container that spans 100% of the pages height with a :before psuedo element that also has 100% height, vertical-align: middle and display: inline-block as essential properties.

After setting up the psuedo element all you have to do is create children within that you want to center horizontally or vertically.

These children need to be display: inline-block and vertical-align: middle atleast and their positioning has to not break the flow ofcourse ;)

It's a pretty neat solution and boils down to the same one as @leoAref except this technique doesn't use tables and the nesting level is reduced by 1 thanks to the psuedo element.

Fiddle here

The downsides to this technique is that the containing element must have a height that equals 100% of the page height otherwise the :before element will not span 100% height and the effect won't work. Setting properties as min-height or max-height aren't specific enough and won't work for the child either.

This means that every parent of the container needs to have a height of 100% defined for this to work.

HTML

<div class="container">
    <div class="centered">
        <p>This is my content</p>
        <p>This is more content</p>
    </div>
    <div class="centered">
        <p>This is my content</p>    
        <p>This is more content</p>
        <p>This is my content</p>
        <p>This is more content</p>
        <p>This is even more content</p>
    </div>
</div>

CSS

html, body {
    height: 100%;
    margin: 0;
}

.container {
    position: relative;
    width: 100%;
    height: 100%;
}

.container:before {
    position: relative;
    height: 100%;
    vertical-align: middle;
    width: 0;
    display: inline-block;
    font-size: 0;
    content: " ";
}

.centered {
    box-sizing: border-box; /*not required*/
    min-width: 40%;
    min-height: 30px;
    padding: 10px;
    display: inline-block;
    vertical-align: middle;
    background: #ccc;
}

Upvotes: 0

LeoAref
LeoAref

Reputation: 154

You can achieve this by using a helper container

HTML

<div id="helper-container">
   <div id="centered-element">
      <div class="content">
          The content goes here...
      </div>
   </div>
</div>

CSS

#helper-container {
    position: fixed;
    top:0;
    left:0;
    width: 100%;
    height: 100%;
    display: table;
    text-align: center;
}

#centered-element {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

#centered-element .content {
    display: inline-block;
    width: 300px;
    max-height: 400px;
    background: gray;
    overflow-y: scroll;
}

JSFiddle: http://jsfiddle.net/LeoAref/sjn3deLw/

Upvotes: -2

Andy
Andy

Reputation: 4107

Try this: https://jsfiddle.net/7wqk9fp0/5/

I use modern flex properties.

iOS doesn't support it yet, so for better compatibility you can extend #overlay to:

#overlay {
    /* iOS */
    display: -webkit-box;
    -webkit-box-align: center;
    -webkit-box-pack: center;

    position: fixed;
    align-items: center;
    justify-content: center;
    display: flex;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
}

Upvotes: 3

Related Questions