CSS Gotchas
January 10, 2013
I'm still learning html and css. As I debug simple websites I write, (including this one), I've encountered a lot of behavior that seemed very counterintuitive to me. I thought I'd share some of this so that future people (especially myself) can avoid the same mistakes I've made.
Splitting a Webpage in Half
As a simple exercise in css positioning, I tried to split a webpage into two side-by-side parts, like the two adjacent pages of an open book. Here's the simple code I used, and this is what it looks like.
<!DOCTYPE html> <html> <head> <style> body { position: absolute; width: 100%; height: 100%; } #left { float: left; width: 50%; height: 100%; border: 1px solid black; } #right { float: right; width: 50%; height: 100%; border: 1px solid black; } </style> </head> <body> <div id="left">This should be the left half of the page.</div> <div id="right">This should be the right half of the page.</div> </body> </html>
Instead of two divs, side by side, I had two divs diagonally across from each other! Debugging this took far longer than it should have. Maybe there's roundoff error in the width: 50%
, I wondered, causing it to add up to more than 100%? Setting width: 49%
kind of solves the problem, looking like this, but is unsatisfying because of the 2% wasted space in the center. Maybe there's some browser-default margin or padding that I don't know about? But setting these to zero explicitly, as I found, does nothing to fix the problem, and it looks the same in Firefox and Chrome.
Finally, I figured it out: The border: 1px solid black
that I had added in order to be able to see my divs are not governed by the width property, so that the total width taken up by the divs, together with their borders on each side, is (1px + 50% + 1px) + (1px + 50% + 1px) = 100% + 4px. This causes the second div to spill over. To fix this I just replaced the borders with outlines, which are almost the same thing but don't contribute to width. This fix looks like this. Another possibility would be to keep the borders, but set margin: -1px
, which undoes the space taken up by the border, and looks like this.
Positioning a Link
As I was designing the main blog page of this site I came across this problem: I had a paragraph with text, and then a link after it, but the link was too far away from the paragraph for my liking. No problem, I thought, I'll just give the link a margin-top: -5px
, moving the link up. Here's the code, and here's what it looks like.
<!DOCTYPE html> <html> <head> <style> a { margin-top: -5px; } </style> </head> <body> <p>This is a paragraph.</p> <a href="#">This link is too far from the above paragraph</a> </body> </html>
The problem is, though, that the link doesn't budge. Maybe it's just because the -5px is too small to be seen? But changing it to -100px or even -100000px doesn't change anything at all. Maybe you can't have negative margin-top's some bizarre reason? But if you make it positive, even to 10000px, it doesn't change anything. Ahh, I though, there's probably some problem in how I'm selecting the link in the css! (The selector in the real example was more complicated). But using the same selector I can give the link a color: #ff00ff
, so that can't be it. I also tried playing with the padding-top attribute, which also had no effect.
Finally, some Google-searching yielded the answer. Anchors are inline elements, and so margin-top and padding-top don't apply to them. You have to turn the anchor into a block element with display: block
to make the margin-top have any effect. That fix looks like this. Another possible fix would be simply wrap the anchor in a div tag, (which is a block element), and apply the margin-top to the div, like this. Finally, you could include the anchor in the preceding paragraph, and add a <br>
before it, though this does not have the same flexibility to move the anchor around arbitrarily.