Position an element relative to its container

Viewed 246220

I'm trying to create a horizontal 100% stacked bar graph using HTML and CSS. I'd like to create the bars using DIVs with background colors and percentage widths depending on the values I want to graph. I also want to have a grid lines to mark an arbitrary position along the graph.

In my experimentation, I've already gotten the bars to stack horizontally by assigning the CSS property float: left. However, I'd like to avoid that, as it really seems to mess with the layout in confusing ways. Also, the grid lines don't seem to work very well when the bars are floated.

I think that CSS positioning should be able to handle this, but I don't yet know how to do it. I want to be able to specify the position of several elements relative to the top-left corner of their container. I run into this sort of issue regularly (even outside of this particular graph project), so I'd like a method that's:

  1. Cross-browser (ideally without too many browser hacks)
  2. Runs in Quirks mode
  3. As clear/clean as possible, to facilitate customizations
  4. Done without JavaScript if possible.
5 Answers

You are right that CSS positioning is the way to go. Here's a quick run down:

position: relative will layout an element relative to itself. In other words, the elements is laid out in normal flow, then it is removed from normal flow and offset by whatever values you have specified (top, right, bottom, left). It's important to note that because it's removed from flow, other elements around it will not shift with it (use negative margins instead if you want this behaviour).

However, you're most likely interested in position: absolute which will position an element relative to a container. By default, the container is the browser window, but if a parent element either has position: relative or position: absolute set on it, then it will act as the parent for positioning coordinates for its children.

To demonstrate:

#container {
  position: relative;
  border: 1px solid red;
  height: 100px;
}

#box {
  position: absolute;
  top: 50px;
  left: 20px;
}
<div id="container">
  <div id="box">absolute</div>
</div>

In that example, the top left corner of #box would be 100px down and 50px left of the top left corner of #container. If #container did not have position: relative set, the coordinates of #box would be relative to the top left corner of the browser view port.

You have to explicitly set the position of the parent container along with the position of the child container. The typical way to do that is something like this:

div.parent{
    position: relative;
    left: 0px;  /* stick it wherever it was positioned by default */
    top: 0px;
}

div.child{
    position: absolute;
    left: 10px;
    top: 10px;
}

Absolute positioning positions an element relative to its nearest positioned ancestor. So put position: relative on the container, then for child elements, top and left will be relative to the top-left of the container so long as the child elements have position: absolute. More information is available in the CSS 2.1 specification.

If you need to position an element relative to its containing element first you need to add position: relative to the container element. The child element you want to position relatively to the parent has to have position: absolute. The way that absolute positioning works is that it is done relative to the first relatively (or absolutely) positioned parent element. In case there is no relatively positioned parent, the element will be positioned relative to the root element (directly to the HTML element).

So if you want to position your child element to the top left of the parent container, you should do this:

.parent {
  position: relative;
} 

.child {
  position: absolute;
  top: 0;
  left: 0;  
}

You will benefit greatly from reading this article. Hope this helps!

Related