Aligning elements with different horizontal positi

2019-09-06 10:30发布

问题:

I have a container with two elements, like so:

<div id="container">
    <div id="button-container">
        <!-- sometimes other buttons as well in this part -->
        <input type="button" value="EXIT">
    </div>
    <h1 id="title-h1">Page Title</h1>
</div>

I want to align the #button-container vertically with the #title-h1 - that is, I want them both to be in the vertical center of the #container div.

In contrast, I want the #button-container to be pushed to the left edge, while the #title-h1 should be in the center of the #container horizontally.

And finally, I want to do this without hardcoding in any values.

The following is not valid CSS (maybe it should be) but it's pseudo code for what I'm trying to accomplish:

#button-container {
    position: align-to-parent(left, middle);
}
#title-h1 {
    position: align-to-parent(middle, middle);
}

The best I could come up with was hardcoding the position of the button container like this:

#container {
    padding: 5px;
    vertical-align: middle;
    text-align: center;
    position: relative;
}

#button-container {
    position: absolute;
    left: 5px; /* since the padding has no effect on it */
    top: 33%; /* not very resilient */
    display: inline-block;
}

#title-h1 { 
    display: inline-block;
}

JSFiddle

How can I do this so that it's more resilient with respect to the sizes of the various containers and fonts?

回答1:

For completely dynamic vertical centering, you can use CSS to set the top of the element to 50%, then use the CSS3 transform-translate properties to offset the element by half of it's height. For example:

#button-container {
    position: absolute;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    transform: translateY(-50%);
}

And here's a jsFiddle demo: http://jsfiddle.net/6hku6gdo/

If you don't want to use translates, providing you know the height of the element, you can set a negative margin instead. I would tend to use this method, unless the height of the element is likely to change.

#button-container {
    position: absolute;
    top: 50%;
    margin-top: -20px; /* assuming the height is 40px */
}

For centering horizontally, you could use display: inline-block and text-align: center, or use a similar method as above by using left: 50% and setting a negative margin, or using the vendor-prefixed translateX(-50%) properties.



回答2:

The easiest way to align both elements vertically with their middles in line with each other is to make them both inline blocks, and give them the vertical-align atrribute:

#button-container, h1 {
    display : inline-block;
    vertical-align : middle;
}
#container { border: 1px solid red; }

(I've also added a border to the container to show more clearly what's happening.)

In this scenario, centering the h1 horizontally now becomes tricky, because the one line now holds both headfing and button, but you can work out how wide the heading is, then choose a percentage offset (experiment to get best value) from the right container side:

h1 { 
    position : relative;
    right : -30%;
}

It will wander off-centre depending on screen width as the screen narrows (but you could add a media query or two to compensate for that).