Sticky position not working on div element - html

I'm trying to make a div sticky positioned relative to the viewport so it sticks to the top when it gets scrolled out of view but it isn't working.
#navigation {
display: flex;
background-color: #AA1111;
width: 100%;
height: 50px;
z-index: 10;
position: sticky;
position: -webkit-sticky;
top: 0;
}
header {
height: auto;
display: flex;
}
<body>
<div class="page">
<header>
<div id="navigation">
</div>
</header>
</div>
</body>

Sticky will stick to the top while the parent element is still visible. With that said, your parent element (header) only contains the sticky element, thus will scroll out of view as the navigation would normally. If you had another element inside of the header that had some height, the navigation would stick to the top until that scrolls out of view too.
https://jsfiddle.net/1zbnr2ho/
Like others have said, sticky doesn't have great browser support, and maybe what you're looking for could just be accomplished with position: fixed?
#navigation {
display: flex;
background-color: #AA1111;
width: 100%;
height: 50px;
z-index: 10;
position: sticky;
position: -webkit-sticky;
top: 0;
}
body {
min-height: 5000px;
}
.other {
height: 500px;
background: blue;
}
<div class="page">
<header>
<div id="navigation"></div>
<div class="other">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</div>
</header>
</div>

Related

Make image take up the full height of a div that changes size?

I will try to make this sound as easy as possible.
I am trying to place 2 div containers, side by side, and have them be the same height at all times.
The right div will be regular text. The amount of text in here will vary since I plan on using this for different pages.
The left div will be composed of 2 smaller containers - a title block, and an image block beneath it.
Here is a visual example of what I'm trying to achieve. The green box is supposed to be the full photo
Example Photo
I would like the photo in the image block of the left side to take up the full height/width of the box - (similar to background-position: cover that is used in CSS). I'd prefer to use a regular img tag instead of setting it as a div background.
The issue that I am having is that the image height on the left takes priority over the text box on the right hand side, and causes both containers to appear much longer than I want. I want the text block on the right to be prioritized, and the image block changes height based on that.
I've tried using object-fit: contain, but it isn't working, unfortunately. The closest I've gotten is to use width: 100%, but then it makes the height way too big.
Here's what I have so far:
.main {
display: flex;
}
.main .left {
width: 40%;
float: left;
}
.main .left .title {
background-color: black;
text-align: center;
display: block;
height: 90px;
padding: 50px;
color: white;
font-size: 40px;
}
.photo {
height: auto;
width: 100%;
}
.photo img {
width: 100%;
}
.main .right {
width: 60%;
float: right;
}
<div class="main">
<div class="left">
<div class="title">This is my Title</div>
<div class="photo"><img src="https://image.shutterstock.com/z/stock-photo-pastoral-green-field-with-long-shadows-in-tuscany-italy-275372477.jpg"></div>
</div>
<div class="right">
<p>text goes here lalalalalala</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<style>
.main {
display: flex;
}
.main .left {
width: 40%;
display: flex;
flex-direction: column;
}
.main .left .title {
background-color: black;
text-align: center;
display: block;
height: 90px;
padding: 50px;
color: white;
font-size: 40px;
}
.photo {
width: 100%;
overflow: hidden;
position: relative;
flex-grow: 1;
}
.photo img {
width: 100%;
position: absolute;
}
.main .right {
width: 60%;
}
</style>
Notes:
I made the image absolutely positioned so its own height won't stretch our flex row.
The image is being cropped by height. If the title is taller than the text (or the same height), you won't see the image at all.
I made the left column also display flex and the photo box flex grow so that the title can stay the same height and the photo box will stretch the rest of the way to match the right column.
We don't need float left/right for flex items.

How to prevent element absolute position from overlap in css

I have a div element to show my blog post, each post have to load an image, a title and one paragraph inside it,
because I want to show title element at bottom of image with a simple background-color then I write the markup like this:
<div class="post">
<div class="thumb">
<img class="image" src="img">
<h3 class="title">title</h3>
</div>
<p class="content">Content</p>
</div>
I put the image and title element inside a div block to place them on each other(title overlap the image) and set thumb position to relative and two child element(image and title) to absolute to achieve the final result, but after that the image and title goes outside of it parent(post element) and overlap the other element above of it in the page.
.post {
.thumb {
position: relative;
.image {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%
}
.title {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background: rgba(#000, .7);
color: #fff;
padding: .5rem;
}
}
.content {
}
}
I want to know why the parent element lose it's height block space and overlap on other elements.
I read some of the similar questions but non of them answer this.
I know if I just set the title position to absolute and fixed on the bottom of image keep the space of block, or use css grid's to achieve similar things but I want to find the real reason to this problem and how to prevent it?
The complete sample code is on codepen: https://codepen.io/anon/pen/GaMegN?editors=1100#0
.post .thumb {
position: relative;
}
.post .thumb .image {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
.post .thumb .title {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background: rgba(0, 0, 0, 0.7);
color: #fff;
padding: .5rem;
}
<div class="page">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="post">
<div class="thumb">
<img class="image" src="https://picsum.photos/400/200">
<h3 class="title">just a sample title</h3>
</div>
<p class="content">
CSS output is just like HTML, only there is no special formats you need to worry about. Just add the CSS you want to output (using newlines as needed) and it will output that way.
</p>
</div>
</div>
The thumb wont have a height because elements with position: absolute; does not take up relative space in it.
I would suggest to remove the position: absolute; on the image, that would give the thumb width and height, but keep absolute on the title
.post .thumb {
position: relative;
}
.post .thumb .image {
display: block;
max-width: 100%;
max-height: 100%;
}
.post .thumb .title {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background: rgba(0, 0, 0, 0.7);
color: #fff;
padding: .5rem;
margin: 0;
}
<div class="post">
<div class="thumb">
<img class="image" src="https://picsum.photos/400/200">
<h3 class="title">title</h3>
</div>
<p class="content">Content</p>
</div>
Absolute positioned elements step out of the regular flow. The parent elements (position: relative) now don't know anything about the size of their child. For them it is just like the child has display: none. I won't affect their own size in any way.
How can you prevent this? There may be many ways.
Don't use absolute on every element: Here I set the .title to relative so that I can control the z-index. I needed the overflow: hidden on .thumb. I added some margins on .title so I can see more of the image
.post .thumb {
position: relative;
/* new */
overflow: hidden;
margin-top: 20px;
}
.post .thumb .image {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
.post .thumb .title {
display: block;
/* position: absolute; */
/* bottom: 0; */
/* left: 0; */
width: 100%;
background: rgba(0, 0, 0, 0.7);
color: #fff;
padding: .5rem;
/* new */
position: relative;
z-index: 1;
margin-bottom: 20px;
margin-top: 60px;
}
<div class="page">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="post">
<div class="thumb">
<img class="image" src="https://picsum.photos/id/990/400/200">
<h3 class="title">just a sample title</h3>
</div>
<p class="content">
CSS output is just like HTML, only there is no special formats you need to worry about. Just add the CSS you want to output (using newlines as needed) and it will output that way.
</p>
</div>
</div>
Or use a background-image instead of an <img> element
.post .thumb {
position: relative;
overflow: hidden;
margin-top: 20px;
background-repeat: no-repeat;
background-size: cover;
background-position: center 40%;
}
.post .thumb .title {
display: block;
width: 100%;
background: rgba(0, 0, 0, 0.7);
color: #fff;
padding: .5rem;
position: relative;
z-index: 1;
margin-bottom: 20px;
margin-top: 60px;
}
<div class="page">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="post">
<div class="thumb" style="background-image: url(https://picsum.photos/id/990/400/200)">
<h3 class="title">just a sample title</h3>
</div>
<p class="content">
CSS output is just like HTML, only there is no special formats you need to worry about. Just add the CSS you want to output (using newlines as needed) and it will output that way.
</p>
</div>
</div>
Change the position of the image and the title to relative and just add a top:-100px (or whatever) to your title
When you set any element to absolute they are taken out of normal document flow and thus other elements position themselves as the targeted absolute element does not exist.
*{
box-sizing:border-box;
}
.post .thumb {
position: relative;
}
.post .thumb .image {
display: block;
width: 100%;
}
.post .thumb .title {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background: rgba(0, 0, 0, 0.7);
color: #fff;
padding: .5rem;
margin:0;
}
<div class="page">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="post">
<div class="thumb">
<img class="image" src="https://picsum.photos/400/200">
<h3 class="title">just a sample title</h3>
</div>
<p class="content">
CSS output is just like HTML, only there is no special formats you need to worry about. Just add the CSS you want to output (using newlines as needed) and it will output that way.
</p>
</div>
</div>

Made aside same height as body

I would like to know how I can make the <aside> height the same height as body, even if it scrolls. The last try I did the body is always full height but the aside not. Please help me :)
html,
body {
margin: 0;
padding: 0;
overflow-x: hidden;
height: auto;
}
aside.sidebar {
position: relative;
bottom: 0;
left: 0;
float: left;
width: 20%;
height: 100%;
}
aside.sidebar ul {
width: 100%;
height: 100%;
}
<aside class="sidebar">
<ul>
<li>tag 1</li>
<li>tag 2</li>
<li>tag 3</li>
<!-- some li tags -->
</ul>
</aside>
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<!-- some content -->
</main>
Use flexbox. All flex items of a flex parent will stretch to match the parent element's height.
body {
margin: 0;
display: flex;
background-color: lightgray;
min-height: 2000px;
}
aside {
width: 20%;
background-color: gold;
}
<aside class="sidebar">
<ul>
<!-- some li tags -->
</ul>
</aside>
<main>
<!-- some content -->
</main>
Instead of height:auto on html and body, set it to 100%

Chrome 55: position: fixed; in div overflow: hidden; doesn't work

I updated my chrome to version 55 and now my position: fixed; in a div overflow: hidden; doesn't work anymore.
Here is the example:
http://codepen.io/PRDev/pen/mOvwOO
.container {
background: #d3d3d3;
}
.overflow {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
z-index: 1;
}
.parallax {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #dfdfdf;
}
.next-section {
position: relative;
z-index: 10;
height: 200vh;
}
<div class="container">
<div class="overflow">
<div class="parallax">
<h1>Headline</h1>
<p>Lorem ipsum</p>
</div>
</div>
<div class="next-section">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
When I'm scrolling to down, the text is still visible outside div overflow hidden, on safari and chrome 54 it is hidden but not in latest Chrome 55.
On chrome 54 text in .overflow hide behind text in next-section, on chrome 55 this text in overflow is visible behind next-section
I dont think this is an issue with how overflow:hidden; works. That dictates what happens to content that overflows its parent. What you are doing is moving one div over another and the reason you see the one behind is because .next-section didnt have a background.
give .next-section the same bg color background: #dfdfdf;
body {
margin: 0;
}
.container {
background: #d3d3d3;
}
.overflow {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
z-index: 1;
}
.parallax {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #dfdfdf;
}
.next-section {
background: #dfdfdf;
position: relative;
z-index: 10;
height: 200vh;
}
<div class="container">
<div class="overflow">
<div class="parallax">
<h1>Headline</h1>
<p>Lorem ipsum</p>
</div>
</div>
<div class="next-section">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>

Div with height % not collapsing into itself with overflow auto

Alright so this is the third time I've looked for help on a particular element I'm working on in an app so I apologize for the repetition.
I'm building a questionnaire for an application and I want all the questions to be contained in a div and the overflow hidden. The problem I'm currently running into is if the height doesn't exceed 80% of the window size the containing div doesn't collapse into itself and there is an unnecessary amount of whitespace left over.
I have tried to switch the questionnaire-box height style to max-height but this caused the overflow content of the .questions div to be hidden instead of scrollable.
I have a strong suspicion I may need to handle this with js but I prefer straight CSS and HTML if possible.
Anyone have any suggestions?
html, body {
height: 100%;
}
.questionnaire-container {
display: flex;
position: fixed;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 255, .1);
}
.questionnaire-box {
position: relative;
width: 80%;
height: 70%;
margin: 0 auto;
background-color: #ffffff;
overflow: hidden;
}
.questions {
height: 100%;
padding: 1rem 2rem;
overflow-y: auto;
}
<div class="questionnaire-container">
<div class="questionnaire-box">
<div class="questions">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
</div>
You have to move the padding from .questions to .questionnaire-box. Also, .questions has no (...-)width attributes set anymore, but the .questionnaire-box's max-width is calc(70vh - 2rem).
Fiddle: https://jsfiddle.net/moor131j/2/