Search code examples
htmlcssalignmentvertical-alignment

How to center child divs along each side of a parent div


I want to center 4 small, square child divs along each edge of a square parent div. My current solution depends on hacked-together absolute positioning. http://jsfiddle.net/Lrc4h/

Current div layout

HTML:

<div class="tile"> 
    <div class="tile_inner"></div>
    <div class="exit_left"></div>
    <div class="exit_right"></div>
    <div class="exit_up"></div>
    <div class="exit_down"></div>
</div>

CSS:

.tile {
    float: left;
    width: 180px;
    height: 180px;
    background-color: gray;
    border: 2px solid black;
}

.tile_inner {
    width: 120px;
    height: 120px;
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border: 1px solid white;
}

.exit_left {
    position: absolute;
    top: 90px;
    width: 20px;
    height: 20px;
    border: 3px solid pink;
}

.exit_right {
    position: absolute;
    left: 165px;
    top: 90px;
    width: 20px;
    height: 20px;
    border: 3px solid red;
}

.exit_up {
    position: absolute;
    left:90px;
    top:10px;
    width: 20px;
    height: 20px;
    border: 3px solid blue;
}

.exit_down {
    position: absolute;
    left:90px;
    top:165px;
    width: 20px;
    height: 20px;
    border: 3px solid green;
}

How can I get each of the exit directions centred along the edge of each axis?


Solution

  • Here is an updated snippet: http://jsfiddle.net/Lrc4h/3/

    First of all you need to know that when you're using position: absolute the element will position with absolute coordinates based on the first parent that is position: absolute or position: relative falling back to the document if there is none.

    Secondly it's important, when dealing with borders like in your example, to understand the box model and how nasty things get when borders cross the borders ;-). It's a common practice to use box-sizing: border-box to make things a bit easier and to mix relative and absolute units nicely. I've included a box model initialization how I prefer it on the top of the example I've posted.

    Combining all this together you can start use relative units (percentage) in your absolute positioning. The example I've posted is still using absolute positions but relative to the .tile element. You should always make your absolute positions relative to a parent. Using left: 50% centers the start of your element to the center of your parents width. However, as your exit element also has a width this needs to be compensated by half of it's width. That's why there is a margin-left: -15px. You could also use the calc function if browser support is IE9+. This would look like this: left: calc(50% - 15px).

    As you can see the example still has absolute positions and this problem is easy to solve with absolute positioning. You still have to "hard code" a few values, but they are all relative to the parent and you can easily change your .tile dimensions without changing the child elements.

    Cheers Gion