Henrik Janbell
Henrik Janbell

Reputation: 1922

Sticky top div with absolute positioning

I'm using absolute positioning to have a div fill up the entire browser window. However, I wan't to combine this with a sticky div that sometimes is there and sometimes not.

To make things a little clearer, check out this jsFiddle: http://jsfiddle.net/henrikandersson/aDdRS/

I want the "top", "left" and "subheader" to stay where they are at all times. I also want the "content" div to fill up what is left of the window. However, sometimes I want to display the "alert" div before "content". So far so good, as you can see in the jsFiddle. But, I want "alert" to stick to the "subheader" and stay there when scrolling. As you can see if you resize the window, "alert" will now be scrolled along with "content" - I don't want it to be.

Anyone got an idea of how to solve this?

EDIT: I made a change in my jsFiddle, I placed the "alert" where it should be (between subheader and content-area). As you can see ( http://jsfiddle.net/henrikandersson/aDdRS/12 ) it does not push the "content-area" down since content-area has top:20px. And I can't set top:40px for example since "alert" should be able to vary in height and I want content-area to have the same css with or without the alert above.

EDIT #2: This question deals with the same problem, but there is no solution for that question either. Seems like it's not possible without using JavaScript: variable height scrolling div, positioned relative to variable height sibling

Upvotes: 62

Views: 124967

Answers (10)

Hanho Kim
Hanho Kim

Reputation: 91

Set sticky's height as 0px and overflowing the inside child.

.sticky {
  position: sticky;
  height: 0;
  overflow: visible;
  z-index: 1; /* Probably need this */
}

.content {
  position: relative; /* Or absolute if needed */
  width: 100px;
  height: 100px;
  background: yellow;
}
<div class="sticky">
  <div class="content"></div>
</div>

Upvotes: 2

Ahmed Elbehairy
Ahmed Elbehairy

Reputation: 1

You can keep the position to absolute then create a new property called background-attachment then set it to fixed. This gives you the ability to have two elements within the same parent.

Upvotes: 0

leonheess
leonheess

Reputation: 21351

Sticky + absolute w/o parent:

html,
body {
  height: 250vh;
  color: #fff;
  position: relative;
}

.child {
  margin: 100px auto -100px;
  height: 100px;
  width: 200px;
  background-color: firebrick;
  position: sticky;
  top: 50px;
  padding: 10px;
}
<div class="child">Hi, I'm sticky AND absolutely positioned!</div>

Upvotes: -1

Facutz
Facutz

Reputation: 441

position: fixed is a combination of both absolute and sticky

Upvotes: 22

yunzen
yunzen

Reputation: 33439

edit
update with some enhancements

body {
    height: 100%;
    overflow: hidden;
}
#top{
    position: absolute;
    background: yellow;
    height: 50px;
    width: 100%;
    top: 0;
}
#left {
    background: #e3e3e3;
    position: absolute;
    bottom: 0;
    left: 0;
    top: 50px;
    width: 200px;
}

#right {
    position: absolute;
    bottom: 0;
    left: 200px;
    right: 0;
    top: 50px;
}
#sub-header {
    height: 20px;
    background: orange;
}
#content-area {
    position: absolute;
    top: 20px;
    right: 0;
    bottom: 0;
    left: 0;
}
#alert {
    background: red;
    color: white;

}
#content {
    width: 100%;
    top: 0px;
    left: 0px;
    bottom: 0px;
    right: 0px;
    overflow-y: auto;
    position: absolute;
}
#alert + #content {
    top: 20px;
}
#alert:empty + #content {
    top: 0px;
}
<body>
<div class="container">
    <div id="top">top</div>
    <div id="left">left</div>
    <div id="right">
        <div id="sub-header">subheader</div>
        <div id="content-area">
            <div id="alert">alert!</div>
            <div id="content">content<br /><br /><br />Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eget nunc magna, eget vehicula ligula. Vestibulum in massa massa, ut feugiat arcu. Suspendisse feugiat commodo tellus, id aliquam dolor cursus eu. Aliquam erat volutpat. Nulla interdum ipsum ut lectus sollicitudin blandit sodales ante malesuada. Etiam ac neque ut turpis faucibus luctus non et arcu. Maecenas ut risus ut odio fringilla sagittis. Sed nulla lorem, suscipit at condimentum quis, adipiscing eget turpis. Morbi accumsan est at tellus hendrerit sed blandit nibh sagittis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent gravida, velit id sodales bibendum, nulla leo rutrum quam, vel tempus justo mi vitae sapien. In imperdiet blandit rhoncus. Phasellus at massa nulla, ut tincidunt est. Nam viverra dui non enim semper consequat. Etiam sed libero sed ante condimentum bibendum ultrices eu nunc.

Integer massa nibh, interdum eget consectetur sed, scelerisque a ipsum. Fusce et ligula erat. Vestibulum lacus enim, facilisis id sollicitudin non, condimentum eu sem. Donec quis magna nec massa vulputate hendrerit. Nam leo nulla, fermentum eu congue quis, imperdiet sit amet orci. Aliquam ornare felis commodo est rhoncus blandit. Quisque at neque ac turpis vulputate sagittis. Donec et viverra risus. Fusce posuere lacus aliquam erat molestie sed tincidunt elit placerat. Sed pulvinar varius neque. Nullam congue adipiscing quam egestas convallis. Sed molestie massa euismod dolor facilisis laoreet.

Cras sit amet nisi sapien, non fringilla arcu. Aenean euismod gravida sem. Donec eu luctus justo. Aliquam erat volutpat. Mauris vestibulum sagittis magna, eget bibendum dolor tempor nec. Nunc rhoncus suscipit felis eu imperdiet. Sed fermentum diam non turpis tempor sit amet adipiscing leo elementum. Donec aliquam consequat elit id auctor.

Praesent vehicula, nibh a elementum imperdiet, urna nulla iaculis leo, ac hendrerit sem massa ac tortor. Suspendisse viverra consectetur libero a luctus. Maecenas iaculis mi id urna fermentum condimentum viverra tellus vulputate. Suspendisse potenti. Aliquam fermentum nulla quis dolor commodo scelerisque. Donec cursus laoreet consectetur. Praesent ultricies arcu ut ante hendrerit imperdiet. Etiam at metus lectus. Aliquam ut ligula neque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec auctor scelerisque purus non sollicitudin. Sed elementum facilisis nisl, eget commodo est congue in. Etiam tincidunt viverra felis, vel tincidunt nulla pretium vel. Phasellus commodo bibendum magna et imperdiet. Aenean euismod condimentum magna eget venenatis. Pellentesque lorem eros, ornare at egestas vel, tincidunt non nunc. Quisque non diam nisl, ut consectetur metus. Fusce ipsum tortor, viverra et lobortis et, ullamcorper non magna. Duis elementum molestie sem, et ullamcorper neque eleifend non. Nunc iaculis quam eros, in pellentesque nunc. Donec tincidunt faucibus est, porta cursus eros imperdiet volutpat.</div>
        </div>
    </div>
    
</div>
<body>


first post
Why not scroll just the .content and not the .content-area

body {
    height: 100%;
    overflow: hidden;
}
#top{
    position: absolute;
    background: yellow;
    height: 50px;
    width: 100%;
    top: 0;
}
#left {
    background: #e3e3e3;
    position: absolute;
    bottom: 0;
    left: 0;
    top: 50px;
    width: 200px;
}

#right {
    position: absolute;
    bottom: 0;
    left: 200px;
    right: 0;
    top: 50px;
}
#sub-header {
    height: 20px;
    background: orange;
}
#content-area {
    position: absolute;
    top: 20px;
    right: 0;
    bottom: 0;
    left: 0;
}
#alert {
    background: red;
    color: white;

}
#content {
    width: 100%;
    height: 100%;
    overflow-y: auto;
}
<body>
<div class="container">
    <div id="top">top</div>
    <div id="left">left</div>
    <div id="right">
        <div id="sub-header">subheader</div>
        <div id="content-area">
            <div id="alert">alert!</div>
            <div id="content">content<br /><br /><br />Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eget nunc magna, eget vehicula ligula. Vestibulum in massa massa, ut feugiat arcu. Suspendisse feugiat commodo tellus, id aliquam dolor cursus eu. Aliquam erat volutpat. Nulla interdum ipsum ut lectus sollicitudin blandit sodales ante malesuada. Etiam ac neque ut turpis faucibus luctus non et arcu. Maecenas ut risus ut odio fringilla sagittis. Sed nulla lorem, suscipit at condimentum quis, adipiscing eget turpis. Morbi accumsan est at tellus hendrerit sed blandit nibh sagittis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent gravida, velit id sodales bibendum, nulla leo rutrum quam, vel tempus justo mi vitae sapien. In imperdiet blandit rhoncus. Phasellus at massa nulla, ut tincidunt est. Nam viverra dui non enim semper consequat. Etiam sed libero sed ante condimentum bibendum ultrices eu nunc.

Integer massa nibh, interdum eget consectetur sed, scelerisque a ipsum. Fusce et ligula erat. Vestibulum lacus enim, facilisis id sollicitudin non, condimentum eu sem. Donec quis magna nec massa vulputate hendrerit. Nam leo nulla, fermentum eu congue quis, imperdiet sit amet orci. Aliquam ornare felis commodo est rhoncus blandit. Quisque at neque ac turpis vulputate sagittis. Donec et viverra risus. Fusce posuere lacus aliquam erat molestie sed tincidunt elit placerat. Sed pulvinar varius neque. Nullam congue adipiscing quam egestas convallis. Sed molestie massa euismod dolor facilisis laoreet.

Cras sit amet nisi sapien, non fringilla arcu. Aenean euismod gravida sem. Donec eu luctus justo. Aliquam erat volutpat. Mauris vestibulum sagittis magna, eget bibendum dolor tempor nec. Nunc rhoncus suscipit felis eu imperdiet. Sed fermentum diam non turpis tempor sit amet adipiscing leo elementum. Donec aliquam consequat elit id auctor.

Praesent vehicula, nibh a elementum imperdiet, urna nulla iaculis leo, ac hendrerit sem massa ac tortor. Suspendisse viverra consectetur libero a luctus. Maecenas iaculis mi id urna fermentum condimentum viverra tellus vulputate. Suspendisse potenti. Aliquam fermentum nulla quis dolor commodo scelerisque. Donec cursus laoreet consectetur. Praesent ultricies arcu ut ante hendrerit imperdiet. Etiam at metus lectus. Aliquam ut ligula neque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec auctor scelerisque purus non sollicitudin. Sed elementum facilisis nisl, eget commodo est congue in. Etiam tincidunt viverra felis, vel tincidunt nulla pretium vel. Phasellus commodo bibendum magna et imperdiet. Aenean euismod condimentum magna eget venenatis. Pellentesque lorem eros, ornare at egestas vel, tincidunt non nunc. Quisque non diam nisl, ut consectetur metus. Fusce ipsum tortor, viverra et lobortis et, ullamcorper non magna. Duis elementum molestie sem, et ullamcorper neque eleifend non. Nunc iaculis quam eros, in pellentesque nunc. Donec tincidunt faucibus est, porta cursus eros imperdiet volutpat.</div>
        </div>
    </div>
    
</div>
<body>

Upvotes: 5

Tran Tien
Tran Tien

Reputation: 75

Use float: left; and width: 0; and you can use transform: translateX(xxx); for set left position.

Problem solved :)

Upvotes: 5

ZhengCheng
ZhengCheng

Reputation: 1325

2018-6-18

I choose the CSS way with position: sticky.

that https://github.com/abouolia/sticky-sidebar .
doesn't work for me (I am using Vue.js 2.0 SPA with vue-router & vuex)

I also want the element position: absolute first,
and then position: sticky

Solution

  1. parent HTML element use position: absolute to have the right position.

(don't forget to set height for parent. for example height:100%)

  1. child HTML element position: sticky

work for me. enter image description here

enter image description here

Upvotes: 80

Henrik Janbell
Henrik Janbell

Reputation: 1922

I chose to go with a JavaScript approach after all. Would have preferred a pure CSS approach but my need for IE8 support stood in the way. This answer by Myles Gray is pretty much what I did - https://stackoverflow.com/a/4933509/940517

Upvotes: 0

James Clark
James Clark

Reputation: 1811

The alert scrolls with the content because it's inside the content-area which has overflow-y: auto.

Move it out of the content-area (put it in between subheader and content-area), and remove the position: absolute (and top/left/right/bottom) attributes from the content. In that example I see no reason for content to be absolute-positioned, normal flow will put it where it wants to be.

Upvotes: 2

ptriek
ptriek

Reputation: 9276

  • Add fixed height & width 100% to alert + position:fixed
  • Add padding-top to content
  • Only downfall is of course the extra padding if there is no alert...

See http://jsfiddle.net/aDdRS/5/

Upvotes: 1

Related Questions