I have problem with a div below another div which has "position: absolute".
I need to make footer appear UNDER container div but now footer is appearing somewhere behind container.
Screen: (div with green background is footer)
HTML:
<div class="horni-panel">
<div class="logo">
Zhlednuto.cz
</div>
<div class="menu">
Home, about atd.
</div>
</div>
<!-- Mini pozadi -->
<div class="minipozadi">
ahoj
</div>
<!-- hlavni obsah -->
<div class="container">
Lorem ipsum dolor sit amet. x 40
</div>
CSS:
#font-face
{
font-family: Lato-Bold;
src: url(fonts/Lato-Bold.ttf);
}
body
{
font-family: Myriad Pro;
font-size: 17px;
color: #a1a8af;
background-color: #34495e;
}
.horni-panel
{
border-top: 8px solid #34495e;
position:absolute;
top:0;
left:0;
right:0;
height: 77px;
width: 100%;
background-color: #ffffff;
}
.logo
{
color: #34495e;
font-family: Lato-Bold;
font-size: 33px;
}
.minipozadi
{
height: 282px;
width: 100%;
background-image: url(img/bg.jpg);
background-size: cover;
background-repeat: no-repeat;
margin: 0 auto;
position:absolute;
top: 85px;
left:0;
right:0;
z-index:1;
text-align:center;
font-size:30px;
}
.container
{
padding: 20px;
margin: 0 auto;
border-radius: 5px;
z-index: 100;
position:absolute;
top:0;
right:0;
left:0;
margin-top:266px;
width: 70%;
background-color: #ffffff;
border-rder-radius: 5px;
}
.footer
{
margin: 0 auto;
width: 100%;
height: 480px;
background-color: green;
}
Absolutely positioned elements will be removed from the flow of the document. So the footer moves up because container is not part of that flow. You would need to either use relative positioning on both, or absolute positioning for both and set their specific top and left values.
Alternatively you could set a top margin on footer that makes it drop enough so it is positioned below the container.
You also need to look at your css. There are several redundant properties that are possibly conflicting.
body
{
font-family: arial;
font-size: 17px;
color: #a1a8af;
background-color: #34495e;
}
.horni-panel
{
border-top: 8px solid #34495e;
position:absolute;
top:0; left:0;
height: 77px; width: 100%;
background-color: #ffffff;
}
.logo
{
color: #34495e;
font-family: Lato-Bold;
font-size: 33px;
}
.minipozadi
{
height: 100px; width: 100%;
position:absolute;
background-color: blue;
top: 85px; left:0;
z-index:1;
text-align:center;
font-size:30px;
}
.container
{
padding: 20px;
border-radius: 5px;
z-index: 100;
position:relative;
margin: 0 auto;
top: 120px;
width: 70%;
background-color: #fea;
}
.footer
{
margin-top: 120px;
width: 100%;
height: 80px;
background-color: green;
}
Here in this fiddle I removed some of the redundant css and used position:relative on the container div instead of absolute. The margin-top property on the footer needs to be greater than or equal to the top property on the container in order for it to stay below it.
You can insert another blank div over your non-absolute div and give it height as has your absolute div:
<div class="absoluteDiv">
<p>something</p>
</div>
<div class="blankDiv">
//nothing here
</div>
<div class="myDiv">
<p>some text</p>
<p>Which is covering absolute div</p>
</div>
CSS:
.absoluteDiv {
position: absolute;
left: 0;
}
.myDiv {
position: relative;
width: auto;
padding: 10px;
}
Now we can use JavaScript code to get the height of absolute div and give it to our blank div:
let absoluteDivHeight = document.getElementByClassName('absoluteDiv')[0].offsetHeight;
let blankDiv = document.getElementByClassName('blankDiv')[0];
blankDiv.style.height = absoluteDivHeight + 5 + "px";
Instead of using position:relative, you can keep both of the div with absolute positioning using JavaScript, as that seems closer to what you are looking for.
What you need here is a function that will set the top property of the footer div to the exact value you need it to be.
Here's the code:
document.getElementByClassName("container").style.top = (266 + document.getElementByClassName("footer").offsetHeight) + "px";
Here's the explenation:
document.getElementByClassName().style.top is a HTML DOM method used to change properties through JavaScript, in this case the property is top.
The 266 is the amount of pixels you set for property margin-top for your container div.
The document.getElementByClassName().offsetHeight function gets the height of an element in pixels (including padding and borders).
Finally, we add "px" to the number, so that the top
property is given in pixels.
This method has its pros and cons:
Pros:
the offset is based on the height of the container div, so it is always positioned directly below the div. You can keep using not only position:absolute, but you can use this method also for position:fixed.
Cons: You must rewrite the code if you add another div that would affect the positioning of the footer. The alignment will not change if you resize the window without reloading the page (you can fix this by running the code every time the window height changes.).
Use a separate wrapper div with 100% height and wrap your container in it that way the wrapper is following the standard flow of the page, and the container can be positioned absolutely within that wrapper, let me know if you need code example.
Related
I often have this problem with a lot of fixed navbars i.e. when I have a fixed navbar, how do I give the element below it some margin, so that the fixed navbar is not covering that element?
I was just wondering if there is a more elegant way of doing this apart from the <br> tag and margin-top.
The sample code would be like:
HTML code :
<nav>
I AM NAVBAR
</nav>
<br><br>
<div>
</div>
CSS code :
* {
padding: 0;
margin: 0;
}
nav {
height: 50px;
width: 100%;
background: #444;
color: #fff;
text-align: center;
font-weight: bold;
font-family: verdana;
position: fixed;
top: 0;
left: 0;
}
div {
height: 500px;
width: 100%;
background: tomato;
}
Fiddle here.
Fixed position relatives to the screen's viewport. You can just set top margin or padding on the body tag, and make the value >= the navbar height.
body {
margin-top: 50px; /*or padding*/
}
http://jsfiddle.net/5k5mxcn1/1/
There's a theory in CSS that you only apply bottom margins.
http://csswizardry.com/2012/06/single-direction-margin-declarations/
So to keep things modular, you could create a wrapping class:
<nav class="nav__wrapper">
<div class="nav__content">
Navigation
</div>
</nav>
<p>Text content</p>
css:
.nav__wrapper {
height: 30px;
margin-bottom: 10px // breathing room
}
.nav__content {
background: #dadada;
height: 30px;
line-height: 30px;
position: fixed;
width: 100%;
}
fiddle: http://jsfiddle.net/wv53qLwz/
A fixed element is position relative to the viewport, meaning it stays at the same designate spot and does not leave a gap in the page where it would normally have been located.
You can apply a top margin to the element that is directly following the fixed element.
div {
margin-top: 50px;
}
However, I've found out that using the scroll-margin property does the trick. It's explained better here https://css-tricks.com/almanac/properties/s/scroll-margin/#aa-enter-scroll-margin
div {
scroll-margin-top: 50px;
}
my question is why changing padding in div.container affects div.blueBox? Since blueBox positioning is set to absolute it is taken out of normal flow, and should be positioned with relation to element.
HTML:
<body>
<div class="container">
<div class="box blueBox"></div>
</div>
<div class="box greenBox"></div>
<h1>Understanding CSS Positioning</h1>
<p><em>Absolute positioning</em> takes an element out of document flow, meaning the browser acts as if the element has no width and height, and the other elements on the page move up as if it was never there. The position of the element is then fixed relative to the top level container, or the closest parent with a set positioning.</p>
</body>
CSS:
body {
background-color: #1f1f1f;
height: 2000px;
color: #bfbfbf;
}
h1 {
font-weight: normal;
}
em {
color: #dd740b;
}
.box {
width: 100px;
height: 100px;
margin-bottom: 10px;
}
.blueBox {
background: #627da0;
position: absolute;
}
.greenBox {
background: #5b8054;
}
.container {
background: rgba(0,0,0,.4);
padding: 10px;
}
http://jsfiddle.net/pawelpodsiadly/brdc8dvy/
Absolute positioning puts an element in place with respect to its closest ancestor that also has positioning other than static.
If you want .blueBox positioned relative to the body, set top and left values:
body {
background-color: #1f1f1f;
color: #bfbfbf;
}
.box {
width: 100px;
height: 100px;
margin-bottom: 10px;
}
.blueBox {
background: #627da0;
position: absolute;
top: 0;
left: 0;
}
.container {
background: pink;
padding: 10px;
}
<body>
<div class="container">
<div class="box blueBox"></div>
</div>
<div class="box greenBox"></div>
<h1>Understanding CSS Positioning</h1>
<p><em>Absolute positioning</em> takes an element out of document flow, meaning the browser acts as if the element has no width and height, and the other elements on the page move up as if it was never there. The position of the element is then fixed relative
to the top level container, or the closest parent with a set positioning.</p>
</body>
If you wanted it positioned with respect to .container, you'll need to position .container:
body {
background-color: #1f1f1f;
color: #bfbfbf;
}
.box {
width: 100px;
height: 100px;
margin-bottom: 10px;
}
.blueBox {
background: #627da0;
position: absolute;
top: 0;
left: 0;
}
.container {
background: pink;
padding: 10px;
position: relative;
}
<body>
<div class="container">
<div class="box blueBox"></div>
</div>
<div class="box greenBox"></div>
<h1>Understanding CSS Positioning</h1>
<p><em>Absolute positioning</em> takes an element out of document flow, meaning the browser acts as if the element has no width and height, and the other elements on the page move up as if it was never there. The position of the element is then fixed relative
to the top level container, or the closest parent with a set positioning.</p>
</body>
When adding a position absolute, you need to define:
position: absolute;
left: 0;
top: 0;
You need to define the rest of the position elements. Like top or left, etc.
You may also be wanting relative and not absolute.
.blueBox {
background: #627da0;
position: absolute;
top: 0;
left: 0;
}
Fiddle updated
members,
I'm having troubles with my HTML code. I am trying to make somekind of youtube. But when I try to create this:
How it should look1
But this is how it looks when I try to make it in HTML:
http://jsfiddle.net/4u64jb5w/3/
<div class="Video">
<div class="BlackRect"></div>
<div class="Video-content">
<h2 class="Titel">This is a video title..</h2>
<div class="Video-footer">
Gebruikersnaam
</div>
</div>
</div>
.Video {
display:block;
position:relative;
margin-top: 100px;
}
.BlackRect{
Width:250px;
height:150px;
background-color:#000;
float:left;
}
.Titel {
color: #34495e;
display:block;
font-size: 25px;
float:left;
position:absolute;
top:0;
margin-left: 270px;
padding: 0;
}
.Video-content{
/*nothing to see here yet*/
}
.Video-footer {
position: absolute;
bottom: 0px;
left:0px;
}
I've noticed while inspecting the code in google chrome that the divs all have a width but no height. I think it has something to do with my positioning in CSS but I don't know exactly what I did do wrong.
How can I get this to like the picture I posted?
Any help is appreciated!
Thank you in advance
UPDATE!:
When I give the divs a static height I get the belonged result but how is it possible that I have to do so?
You've given position: absolute; for child elements like title1 and footer. But the immediate parent is position: static; so they were misaligned.
Other than that, instead of having margin-left for video-content, it's preferable to make it float left. it will be very generic and also can make it responsive easily.
.Video {
display:block;
position:relative;
margin-top: 100px;
}
.BlackRect{
Width:250px;
height:150px;
background-color:#000;
float:left;
}
.Video-content {
float: left;
position: relative;
margin-left: 10px;
height: 100%;
min-height: 150px;
}
.Titel {
color: #34495e;
display:block;
font-size: 25px;
margin-top: 0px;
}
.Video-footer {
position: absolute;
bottom: 0px;
}
DEMO
You've got compounded problems here. The first one is that elements that are position:absolute; do not create space inside their parent container. So first your a tag collapses because .Tite1 doesn't take up space, and then the .video-content container collapses because neither does .Video-footer. This equals zero height for that entire block.
Your second problem is that elements that are floated aren't by default considered in their parent's stacking context. So if all the elements in a parent are 'floated', the parent element has no height. This is the case for your .BlackRect element.
To break down:
<!-- no height because all children/grandchildren produce 0 height -->
<div class="Video">
<!-- doesn't create height because floated -->
<div class="BlackRect"></div>
<!-- doesn't create height because all children/grandchildren pos absolute -->
<div class="Video-content">
<!-- collapses because .Tite1 doesn't create height -->
<a href="#">
<!-- doesn't create height because position absolute -->
<h2 class="Titel">This is a video title..</h2>
</a>
<!-- doesn't create height because position absolute -->
<div class="Video-footer">
Gebruikersnaam
</div>
</div>
</div>
There isn't much to be done if all the elements in .Video-content are positioned absolute, but you can force .BlackRect to create space through a few different methods, the easiest is by applying overflow:hidden to the .Video wrapper.
.Video {
display:block;
position:relative;
margin-top: 100px;
overflow:hidden;
}
You do not need floats and the only absolutely positioned element should be the one you want at the bottom
.Video {
display: block;
position: relative;
margin-top: 100px;
}
.Video a {
text-decoration: none;
}
.BlackRect {
width: 250px;
height: 150px;
background-color: #000;
}
.Titel {
color: #34495e;
font-size: 25px;
font-style: italic;
}
.Video-content {
position: absolute;
left: 270px;
right: 0;
top: 0;
bottom: 0;
}
<div class="Video">
<div class="BlackRect"></div>
<div class="Video-content">
<h2 class="Titel">This is a video title..</h2>
<div class="Video-footer">
Gebruikersnaam
</div>
</div>
</div>
You're halfway there. Instead of floating .Titel you need to float the .Video-content, since it's a sibling of .BlackRect:
.Video-content{
float:left;
margin-left:20px;
height: 150px;
position:relative;
}
Notice I've given it a margin so the text stands off from the video, given it the same height as .BlackRect, and positioned it relative. I positioned it relative to do a little trick with the footer:
.Video-footer {
position:absolute;
bottom:10px;
}
This may have been where you were going with the absolute and relative positioning, but let me explain what I did anyway: When a parent div has a position of relative, any child div of the parent with a position of absolute and will be positioned absolutely within that parent container only (in other words, absolute relative to the parent, not to the page). It looks like that's what you were after, the code just needed to be simplified.
Everything else just needed to be simplified by removing unnecessary selectors:
.Video {
margin-top: 100px;
}
.BlackRect{
width:250px;
height:150px;
background-color:#000;
float:left;
}
.Titel {
color: #34495e;
font-size: 25px;
margin-top:10px;
}
/*to remove the underline*/
.Video-content a{
text-decoration:none;
}
Here's an updated jsFiddle
Did Few twerks and came up with this
Check Fiddle Fiddle
The CSS:
.Video {
position:absolute;
display:block;
background-color:gray;
width:100%;
height:60%;
}
.BlackRect{
Width:250px;
height:150px;
background-color:#000;
float:left;
}
.Titel {
color: #34495e;
display:block;
font-size: 25px;
float:left;
position:absolute;
top:0;
margin-left: 270px;
padding: 0;
}
.Video-content{
/*nothing to see here yet*/
}
.Video-footer {
margin-top:30%;
float:right;
}
I'm having trouble floating a div over an image. Here is what I am trying to accomplish:
.container {
border: 1px solid #DDDDDD;
width: 200px;
height: 200px;
}
.tag {
float: left;
position: relative;
left: 0px;
top: 0px;
z-index: 1000;
background-color: #92AD40;
padding: 5px;
color: #FFFFFF;
font-weight: bold;
}
<div class="container">
<div class="tag">Featured</div>
<img src="http://www.placehold.it/200x200">
</div>
In this image:
I want the "Featured" box to float over top of the image but instead it seems to "clear" the float and cause the image to wrap to the next line, as though it was displaying as a block element. Unfortunately, I can't figure out what I am doing wrong. Any ideas?
Never fails, once I post the question to SO, I get some enlightening "aha" moment and figure it out. The solution:
.container {
border: 1px solid #DDDDDD;
width: 200px;
height: 200px;
position: relative;
}
.tag {
float: left;
position: absolute;
left: 0px;
top: 0px;
z-index: 1000;
background-color: #92AD40;
padding: 5px;
color: #FFFFFF;
font-weight: bold;
}
<div class="container">
<div class="tag">Featured</div>
<img src="http://www.placehold.it/200x200">
</div>
The key is the container has to be positioned relative and the tag positioned absolute.
Change your positioning a bit:
.container {
border: 1px solid #DDDDDD;
width: 200px;
height: 200px;
position:relative;
}
.tag {
float: left;
position: absolute;
left: 0px;
top: 0px;
background-color: green;
}
jsFiddle example
You need to set relative positioning on the container and then absolute on the inner tag div. The inner tag's absolute positioning will be with respect to the outer relatively positioned div. You don't even need the z-index rule on the tag div.
Actually just adding margin-bottom: -20px; to the tag class fixed it right up.
http://jsfiddle.net/dChUR/7/
Being block elements, div's naturally have defined borders that they try not to violate. To get them to layer for images, which have no content beside the image because they have no closing tag, you just have to force them to do what they do not want to do, like violate their natural boundaries.
.container {
border: 1px solid #DDDDDD;
width: 200px;
height: 200px;
}
.tag {
float: left;
position: relative;
left: 0px;
top: 0px;
background-color: green;
z-index: 1000;
margin-bottom: -20px;
}
Another toue to take would be to create div's using an image as the background, and then place content where ever you like.
<div id="imgContainer" style="
background-image: url("foo.jpg");
background-repeat: no-repeat;
background-size: cover;
-webkit-background-size: cover;
-mox-background-size: cover;
-o-background-size: cover;">
<div id="theTag">BLAH BLAH BLAH</div>
</div>
You've got the right idea. Looks to me like you just need to change .tag's position:relative to position:absolute, and add position:relative to .container.
You can achieve this with relative position.
But why isn't your code working?
An element with position:relative keeps it's position and also still affects all other following elements. That's the reason why your div won't overlap the image by just using z-index.
You'll still need to position the div element with, for example: top:-28px where the amount would be the height of the element with tag class.
Note: top has no effect on non-positioned elements. It works with absolute, relative and sticky.
If you add top:-28px to the tag element it will only overlap the image if the z-index it has a higher number. This is the importance of z-index in this case.
.container {
width: 200px;
height: 200px;
}
.tag {
position: relative;
z-index: 1;
float: left;
padding: 5px;
color: #FFFFFF;
font-weight: bold;
background-color: #92AD40;
}
img{
position:relative;
z-index:0;
top:-28px;
}
<div class="container">
<div id='tag' class="tag">Featured</div>
<img id='img' src="https://i.stack.imgur.com/rUDax.png">
</div>
If you want to play a bit with this concepts
I added some JS code to toggle between different styles
const tag = document.getElementById('tag')
const img = document.getElementById('img')
const label1 = document.getElementById('label1')
const label2 = document.getElementById('label2')
function togglePosition(){
if(!tag.style.position){
tag.style.position = 'relative'
img.style.position = 'relative'
label1.innerHTML = 'Relative position added'
}
else{
tag.style.position = null
img.style.position = null
label1.innerHTML = 'Add relative position'
}
}
function toggleZindex(){
if(!tag.style.zIndex){
tag.style.zIndex = '1'
img.style.zIndex = '0'
label2.innerHTML = 'z-index (1 and 0) added to elements'
}
else{
tag.style.zIndex = null
img.style.zIndex = null
label2.innerHTML = 'Add z-index to elements'
}
}
.container {
margin-top:20px;
width: 200px;
height: 200px;
}
.tag {
float: left;
padding: 5px;
color: #FFFFFF;
font-weight: bold;
background-color: #92AD40;
}
img{
top:-28px;
}
<input type='checkbox' onclick='togglePosition()'/>
<label id='label1'>Add relative position</label>
<br/>
<input type='checkbox' onclick='toggleZindex()'/>
<label id='label2'>Add z-index to elements</label>
<div class="container">
<div id='tag' class="tag">Featured</div>
<img id='img' src="https://i.stack.imgur.com/rUDax.png">
</div>
you might consider using the Relative and Absolute positining.
`.container {
position: relative;
}
.tag {
position: absolute;
}`
I have tested it there, also if you want it to change its position use this as its margin:
top: 20px;
left: 10px;
It will place it 20 pixels from top and 10 pixels from left; but leave this one if not necessary.
I have this container which can scroll the content. I would like the header in this container to always stay in the top.
http://jsfiddle.net/z9ze5/
Container:
.lists {
width: 300px;
height: 250px;
margin: 30px auto;
background: #39C;
overflow: scroll;
position: relative;
}
Header:
.box_header {
width: 100%;
height:30px;
overflow:hidden;
position: absolute;
margin: 0;
background: #DDD;
z-index: 999;
}
If you are willing to alter your mark-up, here is one way of doing it:
<div class="lists">
<header class="box_header">
<h1>HEADER 2</h1>
<div class="setting" id="btn2"></div>
</header>
<section class="content">
<p>Lorem Ipsum ....</p>
</section>
</div>
Wrap your scroll area in a <section> (or other block level element).
For your CSS:
.lists {
width: 300px;
height: 250px;
margin: 30px auto;
background: #39C;
position: relative;
}
section.content {
width: 300px;
height: 220px;
margin: 0 auto;
background: #39C;
position: relative;
top: 30px;
overflow: scroll;
}
Please see fiddle: http://jsfiddle.net/audetwebdesign/nGGXx/
More Advanced Example
If you study the following example:
http://jsfiddle.net/audetwebdesign/fBNTP/
uou can see how your scrolling boxes could be applied in a semi-flexible layout.
I lined up two scrolling boxes side by side and made their width proportionate to the width of the page.
The height is trickier to adjust. I fixed the height of the parent container, see the following rule:
.contentWrapper {
border: 1px solid red;
margin-top: 1.00em;
padding: 30px 0;
overflow: auto;
height: 400px;
}
If you change the height from 400px to some other value, the scrolling boxes will adjust themselves.
Hopefully, these examples will give you and others some more insights into how to build these more advanced layout designs.
If you want a non-css fix, add this listener...
$('.lists').scroll(function() {
$('.box_header', this).css('top', $(this).scrollTop()+'px');
});
and then change .lists css to give relative positioning
.box_header {
width: 100%;
height:30px;
overflow:hidden;
position: relative;
margin: 0;
background: #DDD;
z-index: 999;
}
Any position absolute within a position relative is absolute to the relative container. In order to have a header that stays in position, you'd need to position it above, not within, the scrolling container.
look at adding position: fixed to your header div .box_header. You may have to add padding of the height of the box header div to section.content but as you have that set to 30px that should be fine. IE6 and lower has issues with fixed positioning but hopefully we can live with that now - less people are using that than are still listening to Moby.