I have:
.event {
float:left;
position:relative;
top: 50px;
width: 100%;
height: 100px;
background-color: #FFFFFF;
border-top: 1px solid #D6D6D6;
border-bottom: 1px solid #D6D6D6;
}
It works to my liking in firefox & safari. Mainly float against another element, but be offset against it. I know I can use margin-top:50px for the float, but for whatever reason top makes more semantic sense to me.
Firstly I would try not to combine floats and relative/absolute positioning where possible. Just because of the added complexity and additional chance of cross-browser issues.
Secondly, there are valid use cases for position: relative on a float. The most obvious is to use relative+absolute positioning (where the internal elements of the float are absolutely positioned with respect to the container).
That doesn't seem to be what you're doing so I'd recommend using margin-top. You'll probably have less headaches that way. That being said, I'm not even sure top: 50 will do what you expect here.
I found that I sometimes need float:left AND position:relative, because the floated div contains elements that use position:absolute.
The "position:relative" makes sure that child elements are positioned correctly within their own div. Without "relative" in their parent, they would be placed outside.
When using top, the containing element also has to be positioned (relative or absolute) or else you won't always get the result wanted. Does that answer your question?
Nothing wrong with that. float refers to what flow the element is rendered in. position refers to the anchor element against which this element is offset. If they were mutually exclusive the W3C recommendation would have rolled the possible options into a single property.
Bad idea because its position is still in the same place, but you're offsetting it from its original position and you will run into this
You should use margin:50px 0 0; in this case because it will shift any elements coming afterwards down properly. You shouldn't need to explicitly set a width:100% either.
There's nothing "wrong" with the way you did it. In many circumstances, that could be considered the "right" way to do it.
With that said, you should know that there's nothing more or less semantic about position: relative; top: 50px; than margin-top: 50px;. You should get comfortable doing it both ways, and I'd recommend using margin in this case and as your first approach in general.
Relative positioning messes with how elements flow in relation to each other. If you later decide you want to have another element floated left and stacked below the .event element, you'll find that .event is overlapping the top 50px of the new element. When you offset an element with relative positioning, its box remains in the layout where it would have rendered without the positioning, so it will interact weirdly with nearby elements.
Related
When working with position:fixed; this is the expected result one would get:
What I actually want to achive is:
as in this result when working with two position: relative; elements
Don't get me wrong, I know how position: fixed or position: absolute works and should behave, how I haven't come around how to get both properties for the same div...
One approach wich works, but isn't a satisfying solution is that I put a position: relative -div below my fixed element, not allowing the second element moving below the fixed element because it is already taken by the extra div.
So I have tried to get this second relative div working with :after or :before pseudo-elements. This doesn't quite seem to work
div:after, div:before { position: relative; }
it somehow get's mixed up because the element itself is
div { position: fixed }
and turning fixed and relative around obviously also doesn't work because fixed will be bound to the relative - element.
Any ideas?
And if somebody is wondering why I need to use fixed and don't just go with relative : it's for scrolling reasons.
why not use a margin left on the relative div?
http://jsfiddle.net/q3nQr/1/
html
<div id="fixed"></div>
<div id="relative"></div>
css
#fixed { position: fixed; width: 60px; height:100px; background: red; }
#relative { position: relative; width: 300px;height:1000px; background: green; margin-left:65px; }
UPDATE
Take a look at the w3 spec for static positioning (just read the first two paragraphs).
http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning
Absolutely positioned elements are removed entirely from the document
flow. That means they have no effect at all on their parent element or
on the elements that occur after them in the source code. An
absolutely positioned element will therefore overlap other content
unless you take action to prevent it. Sometimes, of course, this
overlap is exactly what you desire, but you should be aware of it, to
make sure you are getting the layout you want!
Fixed positioning is really just a specialized form of absolute
positioning; elements with fixed positioning are fixed relative to the
viewport/browser window rather than the containing element; even if
the page is scrolled, they stay in exactly the same position inside
the browser window.
This means that elements with fixed or absolute positions do not associate with any other elements in the document, this means they cannot effect the width of another element. If the width of the static element is not known, I think you will need manipulate the DOM with javascript; something as simple as (jquery, not tested):
var staticwidth = $("#static").width();
$("#relative").css('margin-left', staticwidth + 'px');
I want to absolute position an iframe and define it's left, top, right, bottom offset:
#x {
position: fixed;
left: 10px;
top: 10px;
right: 10px;
bottom: 10px;
width: auto;
height: auto;
border: 2px solid #aaa;
z-index: 100002;
background: #abc;
display:none
}
I found the left and top value is respected while right and bottom value is ignored. When I don't have a left and top value set, then the right and bottom value is treated correctly. Check this fiddle: http://jsfiddle.net/7fTEF/
Any idea?
Note I don't want to set width and height of the element because I want it be relative to the viewport, neither do I want to set the width and height to a percentage, I just want to keep the border offset a fixed value, say "10px" here.
Not sure why, but, after a little playing around, it seems like IFrames don't like that style of positioning for some reason.
One solution I could make was to container it in a div, and get the div to the size/position you want.
http://jsfiddle.net/7fTEF/1/
Also, despite being 500x500px, the body background color will keep going to fill up all the space in a page, but the sizing of the div is still correct. (resize the body to check it out... )
You can not set both left and right or both top and bottom property. edit: Turns out you can actually provided you are positioning absolute, as i just learned from this article: http://www.alistapart.com/articles/conflictingabsolutepositions (all credits to #thirdender for the tip!). Iframes seem to behave differently though.
You could achieve what you are after like this: http://jsfiddle.net/7fTEF/2/
Note that there is no absolute postioning required. Also i used the css3 property box-sizing. You will have to add browser specific prefixes as explained here http://www.w3schools.com/cssref/css3_pr_box-sizing.asp
Note that this solution will not work in old browser, you will end up with scrollbars. If you want to make it fully browser compatible i think yoy will have to resort to some js, but then you have problems with people who have this disabled. You could also try a combination of both. It all depends on your audience and how import you find it...
You can find the container size via javascript and after set the iframe size.
I found this page here http://www.alistapart.com/articles/conflictingabsolutepositions/ that explains a couple of solutions that are also compatible with older IE browsers using just CSS. Otherwise some JavaScript calculations would probably be required.
I have a site with absolute positioned elements on it, for example the top Navigation of the site:
#topNav
{
position: absolute;
top: 100px;
left: 50%;
height: 40px;
width: 1000px;
margin-left: -500px;
}
Now I created a sticky footer like on the following site:
http://ryanfait.com/resources/footer-stick-to-bottom-of-page/
Now, the problem is that the footer will "overlap" the topNav,
because the topNav is positioned absolute, which means it's "outside of the normal float of elements". The relative position will not "notice" that there is the topNav before.
Before I start creating additional "pusher divs" for each absolute positioned element I would better ask if there are better practices than "pusher divs" or should I even not use position absolute on my elements?
EDIT:
JsFiddle here: http://jsfiddle.net/dkxUX/15/
When you scale down your browserwindow you'll find #footer overlapping all elements before it.
You could just apply a 140px top margin/padding to the body or other container element which would make the topNav's height and offset accounted for.
Better yet, don't set position to absolute in this case - it appears to me that all you're doing is horizontally centering a 1000px wide div.
/*top-margin of 100px + center the element*/
#topNav {width:1000px; height:40px; margin:100px auto 0;}
Update: I see your jsfiddle now. You could account for all absolutely positioned elements when setting the margin/padding as suggested in the first paragraph You are using absolutely positioned elements when normal document flow could be relied on.
a little bit too late to give an answer but it may help someone in the future, I came up with that problem not too long ago so here was my shot at it, using jquery since I couldn't came up with a CSS solution that wasn't removing the DOCTYPE tag (which isn't something you should do, anyways).
So here it is.
$("#CONTAINERDIV").prepend("<div id='relativefix' style='position:relative;margin-top:"+($("#YOUR_ABSOLUTE_DIV").offset().top+$("#YOUR_ABSOLUTE_DIV").outerHeight()+30)+"px'></div>");
$(window).resize(function(){
$("#relativefix").css("margin-top",($("#YOUR_ABSOLUTE_DIV").offset().top+$("#YOUR_ABSOLUTE_DIV").outerHeight()+30)+"px");
});
So yeah, that's all there is to it, you just dynamically add another div at the start of the container hard-placed under the absolute div, that will force all subsequent relative divs to me placed after it, it is like a clear fix for someone who ran out of ideas.
Just a quick question regarding CSS positioning. I have several "segments" on my site which are 100% wide (fills the screen), and I want them floated next to each other. So only the first one will be visible, the other ones will be off-screen. I've tried playing around with positions and the overflow property without luck. Right now they just pop down below each other instead of floating.
This would work perfectly if the elements did not exceed the screen width, but as they do, they just pop down as I said earlier. I've tried setting a huge width to the "wrapper", something like 99999px. And then setting the segments to 100%, but that will just fill the whole 99999px width instead of the screen.
Any ideas?
JSFiddle example: http://jsfiddle.net/9xGPb/
Do you mean like this?
Example Fiddle: here
I used my favourite alternative to floats, inline-blocks
if you actually take it out of the fiddle it has some pretty (gaudy?) colours which show that it allows for the min-width: 900px; on the centered_content div to work too, and I removed the absolute positioning for the menu so the content would go below it, for demo only but you may find it useful..
let me know if any good or if you have any questions
Updated with some jQuery and to make corrections for default word-spacing
New Example: here
re: the IE6/7 hack rightly mentioned in the comments;
.segment {
display: inline-block;
overflow: hidden;
width: 0;
}
.segment {display: inline !ie7;}
needn't be a "parse hack" if that's your preference as long as that second rule is given to [lte IE 7] somehow, and separately at that it cannot be combined into the original rule with the * hack or anything, it won't work.. has to be in a separate ruleset.
I discovered word-spacing might be a problem if relying on width to hide, the natural behaviour of inline blocks is to put 3-4px between the elements like the space in between words, the workaround to this is to correct the word-spacing on the wrapper
.segment-wrapper {
white-space: nowrap;
word-spacing: -4px;
}
then restore it normal for the actual content divs, same place as you would restore the normal wrapping behaviour
.centered_content {
width: 900px;
margin: 0px auto;
background: #fcf;
white-space: normal;
word-spacing: 0;
}
and last, apart from this was fun.. there's 2 effects in that new fiddle - uncomment and comment the other.. forgive me I was playing! :)
The meaning of float is to try to float to the right or left unless there is not room for it.
This means that you cannot ever float an element off the page.
If you need to keep the element off the page, you will need to use a different positioning mechanism like position: absolute.
It sounds like you're creating a horizontal one-page portfolio. I've recently been working on something similar.
Using your fiddle I've set the .segment class to
.segment {width:90%;height:90%;position:absolute;}
and then offset each left positioning further off the screen
#home {background-color:red;left:5%;}
#work {background-color:yellow;left:105%;}
#portfolio {background-color:green;left:205%;}
#contact {background-color:blue;left:305%;}
http://jsfiddle.net/9xGPb/2/
I also added some jQuery logic to switch views for the divs.
I'm still not entirely sure which segments you want to start off the page but this jsfiddle uses positioning to shove the #two div off to the right: http://jsfiddle.net/EdAZP/1/
Which part of your example did you want to start off the page?
Did you try to just hide the other elements and toggle them with some javascript (jQuery is much easier)?
http://api.jquery.com/toggle/
This question already has an answer here:
What are the CSS properties that get elements out of the normal flow?
(1 answer)
Closed last year.
I know position: absolute will pop an element from the flow and it stops interacting with its neighbors.
What other ways are there to achieve this?
One trick that makes position:absolute more palatable to me is to make its parent position:relative. Then the child will be 'absolute' relative to the position of the parent.
jsFiddle
None?
I mean, other than removing it from the layout entirely with display: none, I'm pretty sure that's it.
Are you facing a particular situation in which position: absolute is not a viable solution?
Another option is to set height: 0; overflow: visible; to an element, though it won't be really outside the flow and therefore may break margin collapsing.
There's display: none, but I think that might be a bit more than what you're looking for.
position: fixed; will also "pop" an element out of the flow, as you say. :)
position: absolute must be accompanied by a position. e.g. top: 1rem; left: 1rem
position: fixed however, will place the element where it would normally appear according to the document flow, but prevent it from moving after that. It also effectively set's the height to 0px (with regards to the dom) so that the next element shifts up over it.
This can be pretty cool, because you can set position: fixed; z-index: 1 (or whatever z-index you need) so that it "pops" over the next element.
This is especially useful for fixed position headers that stay at the top when you scroll, for example.
For the sake of completeness:
The float property removes a element from the flow of the HTML too, e.g.
float: right
Floating it will reorganise the flow but position: absolute is the only way to completely remove it from the flow of the document.
I know this question is several years old, but what I think you're trying to do is get it so where a large element, like an image doesn't interfere with the height of a div?
I just ran into something similar, where I wanted an image to overflow a div, but I wanted it to be at the end of a string of text, so I didn't know where it would end up being.
A solution I figured out was to put the margin-bottom: -element's height, so if the image is 20px hight,
margin-bottom: -20px;
vertical-align: top;
for example.
That way it floated over the outside of the div, and stayed next to the last word in the string.
Try to use this:
position: relative;
clear: both;
I use it when I can't use absolute position, for example in printing when you use page-break-after: always; works fine only with position:relative.