HTML/CSS Service

Margins and Absolute Positioning

Category: CSS, CSS3 Tutorial    |    565 views   |   

Getting a Handle on Absolute Elements

First recall how auto positioning is triggered, by letting the side-controlling properties of an absolutely positioned (AP) element be the default values of “auto” rather than some assigned length value. Those side properties are topleftright, and bottom. When those values are auto, the AP element does not consider any positioned ancestors but instead looks at the current “static position” where it would be placed if it were a normally flowed (static) element. The AP element then occupies that location, but is still placed on a separate layer and may overlap parts of the flow.

This generally works fine, but in doing so we give up the ability to use length values on those side properties, which is normally what we do when tweaking AP elements into desired locations. If the static position does not happen to be exactly where we want the AP element to be, there’s only one possible way to offset auto positioned elements, by using margins.

The specs say that margins work on all AP elements and never collapse with other margins, greatly simplifying the situation. However, there is one question that could cause confusion, having to do with AP elements that start out as inline elements, such as spans and links.

As mentioned in a previous article, inline elements normally ignore all top and bottom margins and padding, but AP elements usually obey all margins and paddings even when they are mere spans or links. This is because the act of becoming AP turns them intocontaining blocks, or to be more specific, into block elements.

This is fine for the purposes of moving the AP elements around via margins, but it’s a little strange when you consider the first auto positioning demo from the previous article. Here’s that live demo:

Vestibulum lacus tellus, adipiscing in, volutpat sit amet, dictum ac, mauris. Duis euismod sapien quis tellus. Vivamus aliquam, lorem a accumsan consequat, dolor est iaculis est, nec pulvinar magna ipsum at lacus. Duis aliquam. Sed mattis. Morbi ipsum ipsum, euismod ut, scelerisque quis, faucibus et, tortor. Sed aliquam erat vel justo. Etiam lacinia, massa a ultrices pellentesque, Link textTooltip text dolor ante sagittis nibh, eget interdum ante lectus nec est. Fusce rutrum faucibus mauris. Aliquam cursus nisl at diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Suspendisse leo mauris, dictum et, dignissim sed, eleifend et, dolor.

<p> Vestibulum lacus tellus, adipiscing in, volutpat sit amet, dictum ac. Duis euismod sapien quis tellus. Vivamus aliquam, lorem a accumsan consequat, dolor est iaculis est, nec pulvinar magna ipsum at lacus. Duis aliquam. Sed mattis. Morbi ipsum ipsum, euismod ut, scelerisque quis, faucibus et, tortor. Sed aliquam erat vel justo. Etiam lacinia, massa a ultrices pellentesque, <a href="#" class="linkparent1">Link text<span>Tooltip text</span></a> dolor ante sagittis nibh, eget interdum ante lectus nec est. Fusce rutrum faucibus mauris. Aliquam cursus nisl at diam. Lorem ipsum dolor sit amet. </p>   .linkparent1 { color: #a00; } .linkparent:hover span { left: auto; } /* this hover on the link changes the nested span's left value to auto */ .linkparent span { position: absolute; left: -999em; border: 1px solid white; background: #446; color: white; font-weight: bold; padding: 2px 4px; text-decoration: none; } /* tooltip may be custom styled as desired */ .linkparent:hover { background: url(bgfix.gif); } /* Applies 1x1 transparent bgfix.gif on hover - IE hover bug fix */

When the “Link text” link is hovered and the AP span popup appears in the window, auto positioning places that span in the spot where a simple inline span would go, even tho that span is AP and supposedly has become a block element. So as far as the browsers are concerned, the AP span is located like an inline element while at the same time it is treated as a block for all other styles such as margins, padding, and borders.

Also recall in the second demo that I specifically assigned a “display: block;” declaration to the span and then all non-IE browsers began placing the span on a new line and over against the left paragraph edge. Thus we see that specifically making the AP span a block doesn’t do anything new to the element, other than to change how it reacts to auto positioning (except in IE, sigh).

This is all very interesting but it won’t affect our margin experiments very much. I just want you to be aware of these points because occasionally they can cause trouble for the ill-informed.

Sneaking Around the Margins

Let’s say we want that AP popup span to appear a bit lower and a bit to the left so it partially covers the parent link. Not only will this look cool, but then they will overlap, insuring that the user can mouse from one to the other without any chance of “losing” the popup along the way.

Here’s the same demo but with a top margin to push it down and a right margin to push it toward the left, placing it in front of the parent link. First the new code additions:

.first-offset-test span { margin-top: .8em; margin-right: 50px; }

And the resulting demo:

Vestibulum lacus tellus, adipiscing in, volutpat sit amet, dictum ac, mauris. Duis euismod sapien quis tellus. Vivamus aliquam, lorem a accumsan consequat, dolor est iaculis est, nec pulvinar magna ipsum at lacus. Duis aliquam. Sed mattis. Morbi ipsum ipsum, euismod ut, scelerisque quis, faucibus et, tortor. Sed aliquam erat vel justo. Etiam lacinia, massa a ultrices pellentesque, Link textTooltip text dolor ante sagittis nibh, eget interdum ante lectus nec est. Fusce rutrum faucibus mauris. Aliquam cursus nisl at diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Suspendisse leo mauris, dictum et, dignissim sed, eleifend et, dolor.

Now hover the link text. Notice anything odd? The popup is lowered down a bit from before and that’s fine, but it is not moved over to the left! The right margin seems not to be working. Okay, let’s try it from a different direction, by using a negative left margin in place of a positive right margin:

.second-offset-test span { margin-top: .8em; margin-left: -50px; }

 

Analysis

Have you noticed the pattern yet? It’s simply that AP margins are only obeyed when they are applied to the same sides as the basic side positioning properties! In effect, after you apply a length to the left property you may then apply a length to theleft margin of the same AP element and it will be obeyed, and the same goes for all the other sides.

Why is this, you ask? Well, an AP element that has specified rigid dimensions can only be “tied” to some other element by two adjacent side-controlling properties (top and right, right and bottom, bottom and left, or left and top). The other two sides must be ignored or else the dimensions on the box could get altered from what you have specified, and that’s not something the specs allow to happen.

Since only two sides of the AP box are connected to anything else, only those sides are allowed to react when margins are placed on them. The other sides could be described as “loose ends” that don’t touch anything, and any margins on them can’t push or pull in any way without interfering with either the stated box dimensions or the two controlling side values. Such behavior would obviously be bad, so those unconnected margins are just ignored.

Auto positioned AP boxes act like they are being controlled on the left and top sides because that’s what matters when the static position is being calculated within a left-to-right flow situation. Thus the right side property doesn’t work for our demo and neither will the bottom property.

It’s no different when the AP box has no dimensions (with just two adjacent sides being controlled), because AP boxes in that case will “shrink-to-fit” around content both horizontally and vertically. This makes the AP box behave just as if it did have assigned dimensions that happen to match the size of the content. The only exception is when two opposing sides are controlled on an AP box that doesn’t have a stated dimension along that particular direction.

Tying the Loose Ends

Let’s say you assign the AP box left and right values of zero, but don’t give the box any width. This causes the box to stretch until it fills the horizontal area inside its closest positioned ancestor. Now both sides of the AP box are connected to another element, and thus both left and right margins will work on the AP box. This is true of positive and negative margins, as shown in the triple demo below.

The three contained AP boxes in the demo have left and right values of zero, but no width is applied. The first box has auto side margins (the default values), the second has positive length side margins, and the third has similar negative side margins.

Always keep in mind that IE6 does not allow AP boxes to be dimensionally controlled by two opposing side values, so side margin values don’t work correctly either, except in the cases of assigned dimensions.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • digg
  • del.icio.us
  • Stumble it
  • Furl
  • Reddit
  • BlinkList
  • Simpy
  • YahooMyWeb
  • Spurl

Share/Save/Bookmark

1 Star2 Stars

Tags: ,

0 responses so far!

Leave a Comment

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word