position:sticky does not leave parent - css

How can make an element sticky, so it stays at the top of the viewport? I want the element to remain sticky even if it leaves it's container.
I tried this
HTML
<div class="page">
<div class="parent">
<div class="child-sticky">
<p>i want to be sticky, even when I'm outside my parent.</p>
</div>
</div>
</div>
CSS
.child-sticky {
position:sticky;
top:20px;
}
.page {
height: 3000px;
}
Here's a pen to illustrate the problem. Scroll down to see what I mean.
https://codepen.io/pwkip/pen/OxeMao

Sticky works that way, it will remain sticky relative to its parent. You need to use fixed.
Check this codepen

Already 7 months ago, but I found a CSS only solution if the element you want to be sticky is the last one of its parent, its very simple: Just give the parent element position: sticky; and also give it top: -xx;, depending on the height of the elements before the last one.
#parent {
position: -webkit-sticky;
position: sticky;
top: -3em;
}
#some_content {
height: 3em;
}
#sticky {
background-color: red;
}
#space {
height: 200vh;
}
<div id="parent">
<div id="some_content">Some Content</div>
<div id="sticky">Sticky div</div>
</div>
<div id="space"></div>
<p>Scroll here</p>

This is how position: sticky is intended to work. If you need it to also work outside the parent than you have to change the HTML structure.
See also the official definition: https://www.w3.org/TR/css-position-3/#sticky-pos

There is a little trick you can try.
In some cases it will break your layout and in others it won't. In my case, I have a header with some buttons but when I scroll down, I want to have access to some action buttons which are inside that one-line header. The only change is to set the display property of your parent to be inline.
.parent {
display: inline;
}

Based on https://stackoverflow.com/a/46913147/2603230 and https://stackoverflow.com/a/37797978/2603230's code, here's an combined solution that does not require hard-coded height.
$(document).ready(function() {
// Get the current top location of the nav bar.
var stickyNavTop = $('nav').offset().top;
// Set the header's height to its current height in CSS
// If we don't do this, the content will jump suddenly when passing through stickyNavTop.
$('header').height($('header').height());
$(window).scroll(function(){
if ($(window).scrollTop() >= stickyNavTop) {
$('nav').addClass('fixed-header');
} else {
$('nav').removeClass('fixed-header');
}
});
});
body { margin: 0px; padding: 0px; }
nav {
width: 100%;
background-color: red;
}
.fixed-header {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 10;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<div>
<h1 style="padding-bottom: 50px; background-color: blue;">
Hello World!
</h1>
</div>
<nav>
A nav bar here!
</nav>
</header>
<main style="height: 1000px;">
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.
</main>

Like mentioned, sticky works that way. However there is a CSS hack that you can play around with.
Disclaimer
This is an ugly hack and will probably create a lot of problems with the following content. So I would not recommend it for most usecases. Having that said...
Negative margin hack
There is a hack you could play around with including negative margin. If you extend the height of the container and then give it some negative bottom margin, it could at least "visually leave" the container.
I altered your code and created a JSFiddle for demonstration.
HTML
<div class="page">
<div class="parent">
<div class="child"><p>...<br>...<br>...<br>...<br>...</p></div>
<div class="child-sticky">
<p>i want to be sticky, even when I'm outside my parent.</p>
</div>
<div class="child"><p>...<br>...<br>...<br>...<br>...</p></div>
<div class="child"><p>...<br>...<br>...<br>...<br>...</p></div>
</div>
<div class="following-content">
</div>
</div>
CSS
.child-sticky {
height: 200px;
background: #333366;
position:sticky;
top:20px;
color:#ffffff;
}
.parent {
height: 1250px;
background: #555599;
margin-bottom: -500px;
}
.following-content {
background: red;
height:500px;
}
.child {
background-color: #8888bb;
}
.page {
height: 3000px;
background: #999999;
width: 500px;
margin: 0 auto;
}
div {
padding: 20px;
}
https://jsfiddle.net/74pkgd9h/

Related

Left align div to centered container

I have a container centered with a max width as follow:
#container {
margin-left: auto;
margin-right: auto;
max-width: 900px;
}
Now I want to create a new div just below the contained one, but I want this new div to align to the left and expand beyond the right side of the container. Something like that:
|||||||||||||||||||||||||||||||||||| #container
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| #div 2
The difficulty is that #container margins are auto, so how can I force #div to follow #container left margin as the browser resizes?!
NOTE: I am looking for a pure CSS solution WITHOUT JAVASCRIPT
EDIT: It was not clear in my explanation but, my goal was to make the #div ADJACENT to the #container. Like this:
<div id="container"></div>
<div id="div"></div>
I ended up refactoring my html to use #bananabran solution with absolute positioning which simply uses parent-child structure:
<div id="container">
<div id="div"></div>
</div>
You don't have to force the div to follow its container's left margin. Divs naturally start at the top-left of their container (unless otherwise specified or affected by). You also do not need to use Grid or FlexBox. CSS3, and even CSS2 can do this natively.
See working CodePen example: https://codepen.io/bananabrann/pen/QWWdXQZ
Assuming you have no other code affecting your code...
<div id="container" />
<div id="my-div" />
#container {
background-color: blue;
position: relative;
margin: 0 auto;
width: 900px;
height: 300px;
}
#my-div {
background-color: red;
position: absolute;
bottom: 0;
width: 500px;
height: 20px;
}
CSS-Grid can do that:
.wrap {
display: grid;
grid-template-columns: 1fr minmax(auto, 400px) 1fr;
/* 400px for demo purposes */
}
.container {
padding: 1em;
background: pink;
grid-column-start: 2;
}
.wide-r {
padding: 1em;
background: lightgreen;
grid-column: 2 / span 2;
}
<div class="wrap">
<div class="container">Container
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, similique, maxime aspernatur dolorum quod recusandae possimus fuga blanditiis laudantium delectus quis magni. Veniam, consequuntur dolores facilis cupiditate fugiat ullam aspernatur!
Corporis excepturi quos esse voluptatem voluptatibus corrupti ea, tempora culpa magni, hic aspernatur pariatur molestias itaque doloremque assumenda ad fugiat!</p>
</div>
<div class="wide-r">Wide Right</div>
</div>

align text to right of image in jqm listview

See the jsFiddle here: http://jsfiddle.net/9apNs/
I am trying to display a series of items in a listview in JQM. I am customizing it with certain behavior on taps/clicks.
What I am trying to do now should be quite simple - align an image on the left and a few chunks of text on the right. I've got it working using %ages for width, but I would much prefer that the text was immediately adjacent to the image, no matter the image size or how much the screen expands or shrinks. Images will be fairly small (~50 pixels in width and height).
It makes more sense if you look at it on jsFiddle (to see it in context with rest of JQM listview), but here is the code:
<li>
<div class="entire">
<div class="date">23 November 2013</div>
<div class="image">
<img src="http://vogelsangpeststl.com/wp-content/uploads/2013/02/House_mouse-50x50.jpg"/>
</div>
<div class="text">
<div class="first">ID - Short</div>
<div class="second">
Slightly-longer ID - may possibly be two lines.
</div>
<div class="notes">
Notes could really be quite a lot of text. Usually just a line or two,
but could be quite long. In that case, want to keep image on left and have
text fill up the rest of the space
</div>
</div>
</div>
</li>
And here's the css
.entire {
position: relative;
width: 100%;
border: 1px solid red;
}
.text {
display: inline-block;
vertical-align: middle;
width: 70%;
border: 1px solid blue;
}
.image {
display: inline-block;
vertical-align: middle;
width: 25%;
height: 100%;
border: 1px solid green;
}
.first {
font-weight: bold;
font-size: larger;
}
.date {
position: absolute;
right: 0px;
}
.second{
font-weight: normal;
}
.notes{
font-style: italic;
font-size: smaller;
}
The <div class="image"> is unnecessary. Take the <img> tag out of its container and float all elements inside the .entire container. I also recommend you change your first, second and notes div to h3, h4 and p tags respectively. this is semantically a better way to code, improving readability and SEO of the page.
HTML
<ul class='slats'>
<li class="entire">
<img src='http://placekitten.com/80/80' />
<h3>sub heading</h3>
<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.</p>
</li>
...
CSS
li{ clear:left; margin-top:1em;}
img{float:left;}
.text{float:left;}

Aligning text center and then left

Good Day
I want to align text in the center of a div. Now that is easy with text-align: center on parent div.
But If I want to left align the text inside the div to the left of the centered div, how do I do that?
See my fiddle: http://jsfiddle.net/DvXzB/5/
HTML:
<div id="aboutContent" class="row-fluid">
<div id="aboutHeaderText" class="span12"><span title="">About Us</span></div>
<div id="aboutHeaderBody" class="span12">
<p><a title="">asdasd</a> is a free mobile application available for <a href="#"
title="">iOS</a>, Androidand the Blackberry operating
systems.</p>
<p>sdefsadfsdfldflkjlj lkjlkjdlfsldfjlkj ljlsdjflj lkj ljklj lk; ;l;l; ;k;k
l;kgjh jhg gjjh jhgjhgjh jhgjh gjg jgjhgjg</p>
<div id="cities"><a title="">asdasdasd</a> currently only displays events and
specials in <strong>asdasd</strong> (our hometown), but the following locations
will be available before you know it:
<ul>
<li><span>asdg</span>
</li>
<li><span>asdwn</span>
</li>
<li><span>Pasdasdroom</span>
</li>
<li><span>Dasdaf</span>
</li>
<li><span>Bergrin</span>
</li>
<li><span>Sersch</span>
</li>
<li><span>Graergwn</span>
</li>
</ul>
</div>
<p>Visit our Facebook page for more
up to date information, and feel free to contact us with
any queries.</p>
<br />
</div>
</div>
CSS:
#aboutContent {
color: #222;
margin-top: 50px;
margin: 0 auto;
text-align: center;
}
#aboutHeaderText span {
font-family:"Kozuka Gothic Pr6N", sans-serif !important;
color: #eeeeee;
font-size: 26px;
font-weight: bold;
}
#aboutHeaderText img {
margin-top: -18px;
margin-left: 8px;
}
#aboutHeaderBody {
position: relative;
padding: 0px;
font-size: 16px;
}
#cities ul {
list-style: none;
margin-top: 10px;
}
#cities ul li {
font-family:'Open Sans', sand-serif;
padding: 3px 0px;
font-size: 20px;
color: #222;
}
I want the text in the middle of the page to be justified, but when I justify or left align it, it aligns it to the absolute left again. How do I do this without using fixed paddings or margins? Basically what I want is what they have on this page here(see the 'about us' section): http://www.villagebicycle.co.za/
Note: I am using a fluid layout, so fixed paddings etc won't work
Thank you
You need to center align the container with margin:0 auto after setting its width to a specific size like width:400px. Then align each element separately using text-align.
See this demo: http://jsfiddle.net/DvXzB/16/
If you want your container to have 100% width then do not use text-align:center to your parent div. Instead, use width:100% (optional) and again text-align each block as desired.
You've to use a wraper div to envolve all content. I've done a JsFiddle, I think is what you're looking for :)
.wraper {
position: relative;
width: 500px;
margin:0 auto;
}
Afther that you can align a <p> to the left, right, justify, etc. as you can see:
p.left{text-align:left;}
p.justify{text-align:justify;}
And the HTML for testing:
<div class="wraper">
<p class="left">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. </p>
<p class="justify">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>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>

Parent div to match tallest child div's height?

I'm making a website with a "page" div, and inside that contains the left div "navigation" and the right div "content". I want to make the height of the "page" div (so the background matches) equal to the height of the tallest div, either "navigation" or "content".
How would I go about doing this?
write like this
html:
<div class="page">
<div class="navigation"></div>
<div class="content"></div>
</div>
css:
page{overflow:hidden}
.navigation, content{float:left}
I'm guessing you're floating the other divs, otherwise this would always be the case. You can either float the parent div as well, or add a <div style='clear: both'></div> just before the end of the parent div. Either of these techniques will cause the parent div to be as big as its children.
EDIT: whoops, missed the end tag :)
This will help you
HTML
<div class="page">
<div class="navigation">i am navigation</div>
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est maiores, ex? Mollitia assumenda veniam aliquid commodi ex, libero in quia perspiciatis sint voluptatibus soluta exercitationem quas quos repudiandae deserunt obcaecati.</div>
</div>
CSS
.page {
background-color: #000;
}
/* for clearfix*/
.page:after{
content: "";
display: table;
clear: both;
}
/* for clearfix end*/
.navigation,.content {
float: left;
}
.navigation {
width: 20%;
background-color: #cd6a51;
}
.content {
width: 80%;
background-color: #4CAF50;
}

Wrapper DIV in 100% width website

Im creating a website where the header, footer, body are all 100% width of the page, but I need all the content to be centered of the page no matter the resolution. I've tried using a wrapper but then the header and stuff are only 100% width of the wrapper and not the page.
I'm going out on a limb and guess that the background color/imagery is 100% wide, but you want the actual content to be centered (with a fixed width?). Here is sample code that uses an internal wrapper div on each item to keep internal content centered. I would recommend doing something totally different and possibly using repeating backgrounds on the html and body elements, but I don't know what your page looks like.
So.., the following will work, but will alarm HTML purists because of the extra markup :)
You can view a (super ugly) example of this method on this sample page I put together.
CSS:
.wrapper {
width: 960px; /* fixed width */
margin: 0 auto; /* center */
}
HTML:
<div id="header">
<div class="wrapper">
<h1>My Title</h1>
</div>
</div>
<div id="content">
<div class="wrapper">
<h2>Sub Title</h2>
<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.</p>
</div>
</div>
<div id="footer">
<div class="wrapper">
<p class="credits">Copyright 2009 by Your Company.com, LLC</p>
</div>
</div>
you can't do this with a div element unless it has a specified width.
for just text, you can use
<div style="text-align: center;">text content</div>
this should work for you:
The CSS:
body {
background-color: #e1ddd9;
font-size: 12px;
font-family: Verdana, Arial, Helvetica, SunSans-Regular, Sans-Serif;
color:#564b47;
margin: 20px 140px 20px 140px;
text-align: center;
}
#content {
width: 100%;
padding: 0px;
text-align: left;
background-color: #fff;
overflow: auto;
}
The HTML:
<body>
<div id="content">
<p><b>center</b><br /><br />
This BOX ist centered and adjusts itself to the browser window.<br />
The height ajusts itself to the content.<br />
</div>
</body>
This example was taken from this site, which I found a while ago and always refer to it for nice simple, clean css templates:
http://www.mycelly.com/
Have a play with this
body {
text-align: center;
position: relative;
}
#content {
width: 100%;
height: auto;
position: relative;
margin-left: auto;
margin-right: auto;
}
Then in the HTML
<html>
<body>
<div id="header"></div>
<div id="content">
<!-- place all of your content inside of here -->
</div>
</body>
</html>

Resources