There are two in style approaches to positioning with CSS: float
and absolute positioning. Each approaches have their execs and cons. My teammates and I’ve developed a brand new positioning method that provides us the very best of each worlds. After fairly a little bit of experimenting and testing, it’s time to share the method with the remainder of the world and see how we are able to work collectively to enhance it. I’m calling it “fake absolute positioning” after the fake columns method that simulates the presence of a column.
Article Continues Under
Why do we want one other CSS format method?#section2
Many web site designs are primarily based on a columnar format with a header and footer. With completely positioned layouts, it’s nearly unimaginable to place the footer if the columns can develop vertically. With floated layouts, sudden content material modifications may cause whole columns to wrap (“float drop”), as described by Shaun Inman in Clearance. That is undesirable and laborious to manage in Web Explorer due to IE’s problematic remedy of width
.
Our use case was much more advanced: my group was creating a web-based WYSIWYG kind generator that permits the person to pull objects to arbitrary places on a canvas. We would have liked to let our customers create stunning varieties that didn’t use overly static layouts and to allow them to align columns as wanted.
For instance, let’s assume we would like a kind that places the postal code and metropolis fields on the identical line as a result of they’re semantically related. To perform this, we tried utilizing floated positioning impressed by the Holy Grail method. Utilizing this technique, we would have liked to regulate the width, borders, margins, and/or padding of the postal code subject to pin town subject to a hard and fast horizontal place. That was an issue as a result of if the width of the postal code subject wanted adjusting, or if we wished to regulate the quantity of whitespace between fields, town subject would wish to maneuver as properly. The extra components on a web page—the extra cells in your grid—the extra tedious this sort of adjustment turns into. Moreover, the positioning is delicate to the slightest change in quite a few parameters, which makes it nigh unimaginable to manage in case of dynamic kind objects.
Subsequent, we tried utilizing absolute positioning. This gave us way more management over the positioning of the objects and is powerful. However completely positioned components haven’t any top, and that brought about the containing component (the canvas) to break down. This made it laborious to place content material with out making every thing completely positioned—which is unimaginable to attain with dynamic content material.
A unique method#section3
Lastly, we tried an answer primarily based on discovering a approach to calculate the left offset from a hard and fast place, versus calculating it from the proper fringe of the previous component. We managed to do that utilizing a mix of place: relative
, left: 100%
and a damaging margin-left
.
Our technique begins by constructing a grid of strains and objects. We are able to place any variety of objects on a line and any variety of strains within the containing component:
<div id="canvas">
<div class="line">
<div class="merchandise" id="item1">
<div class="sap-content">content material right here</div>
</div>
</div>
</div>
…and so forth. Each merchandise has an additional sap-content
div
with a number of functions:
- it prevents the redraw bug in IE6,
- it offers us additional flexibility so as to add padding (instance beneath), and
- it lets us play with
place: overflow
(with out breaking the grid!).
The generic CSS utilized to those components is as follows:
.line {
float: left;
width: 100%;
show: block;
place: relative;
}.merchandise {
place: relative;
float: left;
left: 100%;
}
To place a specific merchandise, all we have to do is give it a damaging margin-left
and a width
. For instance:
#item1 {
margin-left: -100%;
width: 30%;
}
With some additional styling, for demonstration functions, it seems to be like this:
Instance of Fake Absolute Positioning in motion.
The generic CSS positions each merchandise on the proper aspect of the canvas, with every merchandise’s width
primarily based on its content material and all objects floated of their HTML supply order. The margin-left
is now offset from the proper aspect of the canvas as an alternative of from the component to its left.
With fake absolute positioning, we are able to align each merchandise to a predefined place on the grid (as with absolute positioning) however objects nonetheless have an effect on the traditional circulate and—due to clear
—have most of the similar benefits as normal-flow components. Each row within the grid will at all times have top
depending on the content material or as outlined in CSS, and can at all times take up 100% of the width, regardless of what number of columns are outlined within the row. Moreover, we are able to keep away from utilizing cumbersome margins or padding to regulate the quantity of whitespace between components—which is a plus, since these strategies nearly at all times require us to make use of IE6-specific hacks to compensate for the browser’s field mannequin.
One other benefit of the method is that it mitigates a lot of the fragility of floats. When the content material of a floated field is wider than the field itself, it pushes the subsequent field to the proper (and by consequence, the field typically drops down). With fake absolute positioning, the field to the proper stays in place, it doesn’t matter what. The content material of the packing containers might overlap (relying on different variables reminiscent of overflow: hidden
) however that’s all—and in our view, it’s higher to danger overlap than danger breaking the entire format.
Truthfully, I used to be a bit shocked that the method labored so properly. It makes use of legitimate HTML 4.01 and CSS 2.1, and damaging left margins are broadly applied in browsers. And there’s extra excellent news: it really works with fastened and liquid designs, it may be mixed with equal top columns (although the problems with this resolution stay), and there may be the potential for combining fixed-width and flexible-width columns (see the instance beneath). It’s even potential to make use of fake absolute positioning recursively, e.g., use a positioned merchandise because the container for brand spanking new strains and objects.
Fake absolute positioning could be very a lot impressed by and supposed for grid-based design and is extra rewarding with extra advanced layouts. When you’ve got a two-column fixed-width design, this will not be your strategy of alternative.
Moreover, fake absolute positioning is not going to work for each state of affairs. If you wish to align components on the left, you can’t use a unit that’s completely different from the unit by which the width of the canvas is outlined, since you can’t calculate the offset. For instance, if in case you have a canvas width: 800px
and desire a left offset of 2em to your merchandise you can’t calculate the margin-left
since you by no means know what number of ems slot in 800 pixels.
And since it’s a new method that hasn’t been examined by hundreds of customers, it ought to nonetheless be thought of experimental, as you might even see sudden ends in your precise mixture of markup, CSS, and browser.
One remaining difficulty: when a component bigger than the canvas precedes different components within the HTML supply, the trailing components on the identical line will probably be pushed to the proper by an quantity equal to the distinction in width between the the primary component and the canvas.
The primary instance is a three-column liquid format with fastened aspect columns, just like the Holy Grail. I’ve applied this format as a template for Drupal, a preferred open supply CMS. There are some things to notice:
- The left and proper columns have widths in pixels. Due to this fact, we can’t calculate
margin-left
for the principle content material, as a result of we don’t know the width of the canvas or the width of the left column as a proportion of the canvas. The answer is just like the Holy Grail: place the principle content material withmargin-left: -100%
andwidth: 100%
and add padding to offer the mandatory area for the columns. - Left, major, and proper columns are rendered on the similar hierarchical degree, so we might have one thing like
z-index: 100
on the columns. - Padding for the left and proper columns is added to the additional
div.sap-content
; this retains our math easy whereas affording us quite a lot of flexibility.
The second instance is a five-column liquid design by which canvas, strains, and objects are all sized in percentages. The addition of photographs, borders and paddings haven’t any impact on the general positioning, even for photographs which are bigger than the containing component, as is demonstrated with the outdated map of Maastricht within the instance.
Our method requires no hacks and it really works with all trendy browsers (Safari, Opera, Firefox, IE7) in addition to IE6 and even IE5.5/Win. It doesn’t work in IE5/Mac, however since this product has been discontinued, it isn’t on our precedence listing.
The method can be very secure, since components develop vertically if vital, and the format doesn’t break when a picture is wider than the component, for instance. The positioning of things is unbiased from the supply order in HTML.
I’m fairly obsessed with this method and see many alternatives for it. Be at liberty to strive, experiment and submit your feedback.