1

I have an outer "container" div in which I want to position inner divs which, in turn, will contain text (in the form of a "p" element) that is vertically and horizontally centered. It looks like this: relative

Blue part: section of outer container

Green: The "inner divs," whose black text is, as you can see, indeed vertically and horizontally centered.

I accomplished this with relative positioning:

<div class="container" id="c">
        <div id="node1" class="node" style="position: relative; top: 50px; left: 50px;"><p class="numtext" id="node1text">1</p></div>
        <div id="node2" class="node" style="position: relative; top: 100px; left: 100px;"><p class="numtext" id="node2text">2</p></div>
        <div id="node3" class="node" style="position: relative; top: 150px; left: 150px;"><p class="numtext" id="node3text">3</p></div>
</div>

The relevant sections of the CSS I used follow:

div.container {
    margin-left: auto;
    margin-right: auto;
    position:relative;
    overflow-y: auto;
}

div.node {
    border-radius: 50%;
    text-align: center;
}

p.numtext {
    position: relative;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
    line-height:100%; /* This vertically centers the text in the parent div, found on stackoverflow */
}

So far, so good. However, the problem is that if I remove the middle "2" node, the position of the "3" node also changes! (Likewise, if I remove the "1" node, the positions of the other 2 change.) It moves up and to the left slightly, but not all the way to where 2 was before. See picture:

relative2

Yet, everything else in the code is the EXACT SAME! So I assumed relative positioning had something to do with it, and I was right; if I changed that (for instance, the div lines would now read like:)

<div id="node1" class="node" style="position: absolute; top: 50px; left: 50px;"><p class="numtext" id="node1text">1</p></div>

I get something very different looking:

absolute

This, actually, looks closer to what the code "should" output, because the nodes are only separated by a small distance that looks more like 50 pixels (for reference, the size of each node is 75.6px). But, obviously, the vertical alignment of the text is WAY out of whack, and for good reason - the nodes [green] are now positioned absolutely, so the text, which is positioned "relatively," is now positioned relative to the container [light blue], not the node (I don't think I explained that properly, but what I'm referring to is similar to this case, I think: Absolute positioning inside absolute position).

So, I think I need to keep all three elements (outer div, inner div, and inner text) relatively positioned, but I don't know how to make the inner divs' positions independent of each other. Any thoughts?

I am also amenable to solutions that ditch the idea of relative positioning, and absolutely position both the inner div and the text, but I still need the text to be centered within the green circle (however note that the circles also can change size [and the text along with them], and the text may have multiple digits, and maybe I might even want to switch to a different font later on, so it seems like a difficult problem to ensure vertical alignment).

Community
  • 1
  • 1
user2258552
  • 824
  • 1
  • 11
  • 25
  • 4
    This code is such a mess. Why are you positioning the text?? It's a child of the circle... It doesn't need to be positioned. All you need to do is set the line-height of the p to the height of the circle and text-align center. That'll solve the numbers issue. – Sean Stopnik May 30 '15 at 07:37
  • @SeanStopnik do you mean "line-height="100%" text-align="center"? I just tried that (removing all other CSS in the

    ), it did not work - the numbers are still not vertically aligned within the circles at all. I also tried just setting line-height to 75.6px (since that is the height of the circle). It did not work.

    – user2258552 May 30 '15 at 07:40
  • Can't edit my previous comment, but actually those give the exact same results as in my scenarios above - if the circle is relatively positioned, the text looks fine but upon deleting a circle the lower circles move. If the circle is absolutely positioned, the text is horizontally centered but the top of the text is at the bottom of the circle. – user2258552 May 30 '15 at 07:47
  • Can't reproduce your first result: `.node` by default will occupy the whole width of parent (they are divs) and that's not the case. Please provide a fiddle – FelipeAls May 30 '15 at 11:10
  • *It moves up and to the left slightly, but not all the way to where 2 was before* => probably due to *whitespace* if your `.node` elements are `inline-block`. See my codepen http://codepen.io/anon/pen/xGgPMm that should show you the problem (4px of whitespace between each pair of `.node`) – FelipeAls May 30 '15 at 11:12
  • 3/3 It's unclear what you're trying to achieve: I understand '2' may or may not be there but then what should happen to '3': should it stay where it is or should it move exactly where '2' was? – FelipeAls May 30 '15 at 11:15
  • @FelipeAls I want it to stay where it is. My node elements are not inline-block, at least unless they are by default (I didn't explicitly make them so). Here is a JSfiddle (change "relative" to "absolute" to get the second result): http://jsfiddle.net/98ngp6pd/ – user2258552 May 30 '15 at 16:09

1 Answers1

1

Correct me if I am wrong, but isn't this what you are trying to do?

http://jsfiddle.net/h2h6qro4/

.container {
    position: relative;
    width: 300px; /* for demo only */
    margin: 0 auto;
}

.circle {
    position: absolute;
    width: 60px; /* whatever your circle size */
    line-height: 60px; /* whatever your circle size */
    text-align: center;
    border-radius: 50%;
    background: #a0f4b6;
}

.circle-1 {
    top: 50px;
    left: 50px;
}

.circle-2 {
    top: 100px;
    left: 100px;
}

.circle-3 {
    top: 150px;
    left: 150px;
}
Sean Stopnik
  • 1,868
  • 11
  • 9
  • Yes! I understand now - this didn't work when I set the

    line height, so I just removed the

    and set the line-height of the div instead of the height of the div.

    – user2258552 May 30 '15 at 19:33