简体   繁体   中英

Vertically centering a popover div

I'm trying to make an iPad-like popover div as an exercise, but I can't find out how to vertically center the popover div, having an unspecified content width/height.

http://jsfiddle.net/mbYyR/5/

I want the triangle to point to the position defined by #popover-wrapper's top/bottom right/left values, but top: -50% does not work.

Thanks for your help :)

你可以使用jquery解决这个问题,请检查小提琴链接

If you do not want to use javascript, then centering it vertically is not possible (as previously stated by others). However, if your goal is to simply have a nice pop-up that allows some flexible width/height, I recommend the following pure CSS solution. Some explanation follows each section for what I did and why I did it.

OPTION #1 HTML (my preferred)

<div id="popover-wrapper">
    <div id="popover-direction-setter">
        <div id="actual-popover-div">
            <div id="content-with-unknown-height">
                Content Content with unknown dimensions. Tip should point to the blue dot
                Content with unknown dimensions. Tip should point to the blue dot
                Content with unknown dimensions. Tip should point to the blue dot
            </div>   
        </div> 
    </div>
</div>
<div id="target-blue-dot"></div>

The triangle div is gone, because I am going to use an :after pseudo class to apply it since it is purely presentational.

OPTION #1 CSS (note the #triangle-tip code was replaced with #popover-direction-setter:after )

#popover-direction-setter {
    position: absolute;
    right: 20px; /* grow left */
    top:   0px;
    background: #EEE; /* for debugging */
    width: 160px; /*left position of wrapper - 40px for right position of this and triangle tip border size */
}

#actual-popover-div {
    position: absolute;
    right: 0px;
    top: -.5em;
    margin-top: -25px; /* border-radius + half the height of the triangle */
    padding: 0.5em;
    background: black;
    color: white;
    border-radius: 15px;
    min-height: 50px; /* 2 * border radius + half the height of the triangle */
}

#popover-direction-setter:after {
    content: '';
    position: absolute;
    width:  0;
    height: 0;
    top:           50%;
    margin-top:   -20px;
    border-top:    20px solid transparent;
    border-bottom: 20px solid transparent;
    border-left:   20px solid black;
    right:        -20px;
}

Do not be alarmed by the #popover-direction-setter having width set. I presume you know the left position (since you use it), so this width can be pre-calculated and makes a width that the pop up will be so that it does not end up flowing off the left side of the browser window. 宽度,这样它就不会从浏览器窗口的左侧流出。 I would think that would be a good thing.

The min-height is set on #actual-popover-div so that if content is minimal, it looks good with the triangle.

The top position of #actual-popover-div is offsetting your em sizing on the padding . The margin-top on that element is just bumping up enough to make the arrow sit nicely in the upper corner, and be centered when the min-height takes effect.

OPTION #2 HTML (keeps triangle div but repositions it)

<div id="popover-wrapper">
    <div id="popover-direction-setter">
        <div id="actual-popover-div">
            <div id="content-with-unknown-height">
                Content Content with unknown dimensions. Tip should point to the blue dot
                Content with unknown dimensions. Tip should point to the blue dot
                Content with unknown dimensions. Tip should point to the blue dot
            </div>   
        </div> 
        <div id="triangle-tip"></div>
    </div>
</div>
<div id="target-blue-dot"></div>

OPTION #2 CSS remains as you originally had the triangle div and eliminates my :after pseudoclass code.

I know this does not meet your challenge requirements fully. Again, I agree with others that there is no way currently to position an element centered vertically with an undetermined height. However, if nothing else, others may find my solution good for them.

I'm pretty sure #actual-popover-div isn't moving because it's set at position: relative . Setting it to postion:absolute and altering some values seems to get the effect you're looking for.

Example: http://jsfiddle.net/mbYyR/8/

One thing to play with is setting the top position, as you are, and also setting a negative margin-top value. You MAY be able to achieve the effect through this method without using jQuery.

My pure HTML + CSS solution (needs some cleanup though):

http://tinkerbin.com/f2LIo7RM

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM