This forum is now read-only. Please use our new forums! Go to forums
Please read this instead of following Eric Weinstein's instructions.
Eric Weinstein’s instructions for this section are completely wrong and seem to be confusing a lot of people. So here is my attempt to correct that…
Setup
First, in order to understand positioning for this exercise, you need three divs in your HTML. Delete the code between the body tags in your html. Replace it with the following:
<div id="parent">
<div id="child">
</div>
<div id="sibling">
</div>
</div>
Replace your CSS with the following code:
div {
border: 2px solid black;
}
#parent {
height: 500px;
width: 150px;
background-color: #45ADA8;
}
#child {
height: 75px;
width: 75px;
background-color: #547980;
}
#sibling {
height: 75px;
width: 75px;
background-color: #807954;
}
Position: Static
Note that in the CSS, we have not specified any positioning yet. Since we did not specify a position, these divs will have the default position value of static. Now look at the Result tab. You will see the three divs: the #child and #sibling divs are stacked on top of each other inside the #parent div. This demonstrates the normal flow of the document. The normal flow is how the browser will render elements without any change to their position properties. In other words… the normal flow determines how elements with a static position will be displayed.
Since a div is a block level element, the #sibling div appears below the #child div. (This is explained in an earlier lesson: HTML Basics III, Div and Span). The #child and #sibling divs are nested inside the #parent div at the top left.
Margins have nothing to do with the position property
Here is where Eric Weinstein’s directions go horribly wrong. He tells you to use the position property in combination with the margin-left property. They have nothing to do with each other!! To demonstrate this, add a margin-left of 40px to your #parent div like so:
#parent {
height: 500px;
width: 150px;
background-color: #45ADA8;
margin-left: 40px;
}
Notice we did not specify a position property yet. The div is still static. Look at your page in the Result tab. The #parent div has moved 40px to the right because we increased the left margin by 40px. (If you need to understand more about margins, do a search for “css box model”). The #child and #sibling divs went along for the ride, because they are nested inside the #parent div. All the divs are still in the normal flow of the document! This is an important distinction! Just remember: changing the margin does not affect an element’s position property.
Position: relative
Add two lines to your CSS for the #child div… position: relative; right: 30px.
#child{
height: 75px;
width: 75px;
background-color: #547980;
position: relative;
right: 30px;
}
These two properties work together to tell the browser where to put this div. Now look at the Results tab… TA-DA! The #child div has moved. But where exactly? Well, it moved 30px from the right of where it would have been if it were in the normal flow! Also, the other elements on the page stay in the same place they would be if #child was in the normal flow. So if you use relative to position an element, it’s as if the browser pretends everything is static, positions everything accordingly, and then tweaks the relative positioned elements according to their top, left, bottom, and right properties. Experiment with the CSS by adding left, right, top, or bottom properties to your #child div.
Position: absolute
Here’s where things get a little trickier. First, let’s go back to our CSS and change position: relative to position: absolute for our #child div:
#child{
height: 75px;
width: 75px;
background-color: #547980;
position: absolute;
right: 30px;
}
You should notice two things in the results tab.
1. The #sibling div has moved up to the top of the #parent div! Why? Because unlike a relative-positioned element, the absolute-positioned element is taken out of the flow completely. With absolute positioning, the browser does not figure out where everything else would go as if the absolute-positioned element were still static. The #sibling div is at the top of the #parent div because it’s as if the #child div wasn’t there at all.
2.The #child div is all the way over toward the right side of the window.
This is because when you give an element an absolute position, it is positioned relative to the browser window. (exception to this rule to follow). So right: 30px puts the div 30px from the right side of the browser window, no matter what. If there was something else there already, the #child div would just plop right on top of it. Again, you can experiment with your CSS, combining top, right, bottom, and left properties to plop your div in different places. Something interesting to keep in mind is that the top and left sides of a browser window stay the same, but the right and bottom sides of the browser move when the window is resized. (Unfortunately, you can’t really test this with the Codeacademy console).
THE EXCEPTION (as promised)
Now go back to your CSS and give the parent div a position: relative.
#parent {
height: 500px;
width: 150px;
background-color: #45ADA8;
margin-left: 40px;
position: relative;
}
In the Results tab, you will see that the #child div now has an absolute position relative to the #parent div, instead of relative to the browser window. This is because the #parent div now has a non-static position (non-static = relative, absolute, or fixed). Notice that we did not even have to specify a top, left, bottom or right property. The general rule is: An absolutely positioned element will be positioned relative to its closest parent with a non-static position. If there are no non-static parents, the element will be positioned relative to the browser window.
This may sound very confusing right now, but after some practice and experimentation with positioning, you will pick it up quickly enough.
Position: fixed
Position: fixed works exactly the same as absolute, with two differences:
- When you scroll the browser window, the fixed element will appear to stay in place.
- When you specify a top, right, bottom, or left property, the fixed element will always be positioned relative to the browser window, regardless of its parents’ positioning.
EDIT: If a top, right, bottom, or left property is not specified, the fixed element will appear where it normally would if it were static, but it will still be outside of the normal flow and will still appear fixed when you scroll. Thanks to Louie Solomon for helping clarify this. (An absolute-positioned element displays this same behavior–without the scrolling, of course.)
I’ll leave you to experiment with fixed positioning on your own. UPDATE: bbd has posted a nifty example below
Once you’ve mastered all this, you’ll be ready to tackle floats! Good luck :)
Thanks to Russel Bowen for correcting a typo with the code in the absolute section.
Answer 50f6460ac22b7b977d0005c8
Thank you for this excellent post. It clears positioning up perfectly!
Answer 510715d1c28d52493800082b
By the way, below is a quick “fixed” example. The child and sibling elements are fixed to the left and the right of the screen, and stay visible even when scrolling up and down the page.
div {
border: 2px solid black;
}
#parent {
height: 800px;
width: 150px;
background-color: #45ADA8;
position:absolute;
left:0px;
}
#child{
height: 75px;
width: 75px;
background-color: #547980;
position: fixed;
right: 0px;
}
#sibling {
height: 75px;
width: 75px;
background-color: #807954;
position: fixed;
left: 0px;
}
3 comments
Excellent, thanks! I updated my post to mention your example.
Hmm, I’ve copied this into the page builder on this site, and for some reason it works in the result page, but when I click ‘View Project’ and get the page as a regular webpage, the boxes aren’t fixed.
I thought it might have been because of my browser, but I’ve now tried Chrome, FF and IE to no avail.
Do you know what could be the problem?
And just to clearify, I’m using dwesley’s html bit and bbd’s css page. And thanks for making the positioning clear, contrary to mr. Weinstein’s guide.
Krazh try it in dabblet.com worked for me.
Answer 5104fa31776ae63d3d00334b
why Codecademy has still not replace Eric’s exercise with this one?
Answer 510ecf1363c1970e4f00a2ad
Answer 5100505011a2a1bcfa001b83
Answer 5106f29bc304809669000026
Answer 5108ab390d7d08a8bb00128b
thank you dwesley! that’s an awesome explanation. it shoul be incorporated in the couse.
Answer 5125853be7339927a300483c
@dwesley Thanks for taking the time to make this informative post.
Answer 515f22a7eecb74332f001a64
Basically, a static positioning puts the element where it belongs according to the normal flow.
The relative positioning creates a hidden “copy” of the element such that the other elements can use that ghost as part of the general flow. However, the relative element can be moved relatively to this ghost, without interacting with the other elements. Instead, the ghost (as the static foot print of the relative element) interacts with them.
An absolutely positioned element can be positioned with respect to the closest parent that has a non-static positioning. It is absolutely taken out of the flow. (“Absolute” literally means “detached.”) It overrides other elements (though one may change that, if desired), meaning it is rendered on top of the ordinary flow. If the closest parent with a non-static position is the window itself, the origin of the coordinate system in which one moves the absolute element lies at the top left corner of the window. (See bottom of this comment for a side note.) In cases where the closest parent with a non-static position is not the windows itself, one can think of the origin of the absolute element’s coordinate system as the top left corner of that very closest parent.
This leads to an important difference: Relative positioning directly cares for the content of its parent with regard to its ghost’s position within the parent, i.e. the origin of the coordinate system for a relative element is part of the flow due to its “siblings.” For absolute positioning, the “siblings” do not directly influence the origin of the coordinate system. It is still the top left corner of the closest non-static parent, no matter what else that parent may or may not contain.
To clear this up, do the following: in #parent:
- position:relative;
in #sibling:
- position:relative;
- left:50px;
- top:10px;
First, take note that sibling is 10px below child and not parent, due to the flow. Now, change sibling’s position to absolute and the top value to 0. Observe the following: sibling changes position with respect to parent and not the window because parent’s positioning is relative (non-static). Furthermore, absolutely positioned elements, when created, take the position values that put them where they would statically belong, if they were part of the flow, (and not, as one might expect, a bunch of 0s!), unless these values are changed manually afterward. That is why the top value needs to be set to 0 explicitly. Now, remove the top assignment, and see what happens. Do not put the top assignment back.
To show that the sibling is indeed not part of the flow, though it is, by default, positioned as if it were, make child a class (in both the HTML file and the CSS file) and add a second <div class=”child”> to your HTML file, below sibling. You now have a child, a sibling, and a child again. See how the second child ignores sibling because the sibling’s positioning is absolute?
Test your understanding, by answering the following question without looking it up:
<div id=”parent”> <div class=”child”> <div class=”child”> <div id=”sibling”> </div>
parent and child have relative positioning. child and sibling are the 75px boxes we are used to by now. child is green, sibling is red. sibling has relative positioning and a top value of 75px. What will the result look like? Now, set sibling to absolute positioning. What changes?
Side note: There are pretty much four coordinate systems, one in each corner. If one only changes the top and the left values, one may view the top left corner as the origin of the movement. If one, however, only uses, say, bottom and right values, the origin is the bottom right corner. It’ll probably get confusing, once one starts to use more.
tl;dr: Static positioning is the default behavior and puts elements where they fit. Relative positioning creates a static foot print where the element would be, if it were static. Only this foot print interacts with other elements, since it is part of the flow. One may change the position of the element relatively to this foot print. The actual element will, however, not interact with the others, since it is removed from the flow. Absolute positioning takes the closest non-static parent as a reference frame. That may be the window itself, in which case top and left values are distances to the top and left borders of the window, respectively. It is, however, also possible that the closest non-static parent is another element. That parent then becomes the reference frame, meaning the content of the parent is not relevant to the absolutely positioned element. The element does not interact with other elements, since it is not part of the flow. It is also, usually, on top of all other elements. An absolutely positioned element does not have a static foot print; it is entirely ignored by the other elements.
I hope that helps to pin down the exact behaviors of the different options one can choose of. If anything is wrong, since I, for myself, am just in the process of learning this, please leave a comment.
1 comments
Very good explanation. Your explanation (and dwesey’s too) cleared up a lot of questions I had. Thanks!
Answer 50fb867fa376e6890b0047f9
but under the subtitle “Positioning:Absolute” you have a screenshot of your code that still says position:relative;
1 comments
Thanks! I updated the code to say absolute.
Answer 50fb880935ac5eb9cc00483f
still better than Eric’s instructions.
Answer 510709ab2ddb2ed9a6000170
Answer 5107f35c93e3caad5b0001ed
Your last statement about Fixed positioning is incorrect. A fixed position div CAN be relative to the parent div.
Using Eric Weinstein’s example, if you set the outer div to “relative” positioning and the inner div to “fixed”, you will notice that the fixed div will go to the top-left corner of the outer div, not the corner of the page.
This is a really nice feature for creating websites with fixed navigation headers that are the same width as the content of the site.
5 comments
Ah… true, the fixed div does stay inside the parent div in that case. But that is because you haven’t specified any top, right, bottom, or left properties. What I should have said is: a fixed position element will always ignore its parent and be positioned relative to the window when you specify one of these properties. If you don’t specify a direction, it will be where it would normally appear, but outside of the normal flow. Thanks for bringing up this example. I’ll clarify that in my post :)
Also, you don’t need to set the outer div to relative. It could just be static.
Just to clarify, you cannot use top, right, bottom, or left to position a fixed element relative to its parent, regardless of the parent’s positioning. Top, right, bottom, and left will always position a fixed element relative to the window.
dwesley, that’s correct, both static and relative positioning work with an inner fixed div.
Also, this is where Eric Weinstein’s use of positioning the div with margins would be useful!
Yes, you could change the fixed div’s margins to adjust where it appears on the page. I wouldn’t call that “Eric Weinstein’s use” of margins, though. The way that he was saying to use margins has nothing to do with your example. In my opinion, Mr. Weinsten’s course is incorrect, misleading, and completely indefensible. Just look at the other posts in the forum to see how many people he has confused and misled.
Answer 5124cd7c064cdf3b55002fd7
Just to reiterate this point changing the margins has nothing to with position : absolute, however you can do something like - left : 20px; which won’t work when static.
Answer 512f3286382757587c00ac7b
Wow, thanks so much! I’ve been trying to make a web page by doing all the positioning based on margins of all the divs on the page.. i knew it couldn’t be the right way lol dammit.
Answer 512ffe71d4ca2bb496000f1b
Answer 513045643d5d35b3ee005af0
Answer 513115d0cdf1c5be9d00097b
Thanks a lot, at first, I thought I had memorized bad informations on some others tutorials about positioning in CSS. But since I ‘ve read your explainations, all is clear again !
Thanks for these exemples, and the help, I hope they’ll quickly replace the bad information by good ones, because It won’t be good for people to learn mistakes.
Answer 5133b629fcc38ccae000c2e0
Why the heck has this been flagged? people are so dumb -_-
2 comments
In a desperate attempt to get it Eric’s info replaced by dweasly’s post, I suspect.
So the mods will look at it and hopefully replace Eric Weinstein’s one with this one
Answer 513743a99f6047eae7004ccc
Answer 5137f64f17d450bf20005c2a
Answer 5138184ccc4b4dc68a0004f3
Answer 513ae29e618bab38b50001dd
Thank you so much, dwesley! Great job!
Answer 513bb738e411886647002d25
Also you can check this site -> 10 steps to learn CSS Positioning:
http://www.barelyfitz.com/screencast/html-training/css/positioning/
Answer 515c6d41a4145761b2000612
Answer 523df7dcf10c60308f001f2c
1 comments
thank you.. buddy!
Answer 513b01a5f3a2a55ace000803
Answer 515e285ba94e5952960003fc
Answer 51d9f29b282ae3148c00efc3
wish I could upvote OPs or threads themselves, this should be a sticky or the top thread of the Positioning section
Answer 53bf20797c82cae158000203
Popular free courses
- Free Course
Learn SQL
In this SQL course, you'll learn how to manage large datasets and analyze real data using the standard data management language.Beginner friendly,4 LessonsLanguage Fluency - Free Course
Learn JavaScript
Learn how to use JavaScript — a powerful and flexible programming language for adding website interactivity.Beginner friendly,11 LessonsLanguage Fluency - Free Course
Learn HTML
Start at the beginning by learning HTML basics — an important foundation for building and editing web pages.Beginner friendly,6 LessonsLanguage Fluency
2 comments
Glad I could help!
thank you, mr., but how do i open new tab for stylesheet.css