1

I'm trying to create a popup in my application and I need to center it vertically. I do NOT know the height of the popup, so I can't hard-code any values.

I'm experimenting with the following code: Centering in the Unknown

So far the centering works fine, but there is a problem. My popups have a fixed width(and they are not responsive), so my goal is when the width of window is lower than popup's width, a horizontal scroolbar should appear.

On higher resolution the centering works fine:

enter image description here

But when window resolution is lower than popup resolution, this happens: (The actual popup is moved under viewport)

enter image description here

.block {
  text-align: center;
  background: #c0c0c0;
  border: #a0a0a0 solid 1px;
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
}
.block:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}
.centered {
  display: inline-block;
  vertical-align: middle;
  width: 500px;
  padding: 10px 15px;
  border: #a0a0a0 solid 1px;
  background: #f5f5f5;
}
<div class="block">
  <div class="centered">
    <h1>Some text</h1>
    <p>But he stole up to us again, and suddenly clapping his hand on my shoulder, said&mdash;"Did ye see anything looking like men going towards that ship a while ago?"</p>
  </div>
</div>
Community
  • 1
  • 1
Deepsy
  • 3,769
  • 7
  • 39
  • 71

1 Answers1

1

As far as I know it's not possible to trigger the scroll bar with position fixed element, But there is a way to prevent the popup moving under the viewport, we can use the font size tricks, set font-size:0; on the container and font-size:16px; or so on the inner box, read this for more - https://stackoverflow.com/a/5078297/483779 Then change fixed width to max-width to make it responsive, again no scrollbar.

Updated Demo

I also added a couple of other approaches. The 1st one will keep the content box always stay in the middle. The 2nd one behaves similarly your current demo. And the 3rd will be able to trigger scroll bar but it's using absolute position.

Approach 1: using CSS3 transform, browser support IE9+.

JsFidde Demo

.wrapper {
    text-align: center;
    background: #c0c0c0;
    border: #a0a0a0 solid 1px;
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
}
.centered {
    width: 500px;
    padding: 10px 15px;
    border: #a0a0a0 solid 1px;
    background: #f5f5f5;
    
    position: absolute;
    left: 50%;
    top: 50%;
    -ms-transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
}
<div class="wrapper">
    <div class="centered">
        <h1>Some text</h1>
        <p>But he stole up to us again, and suddenly clapping his hand on my shoulder, said&mdash;"Did ye see anything looking like men going towards that ship a while ago?"</p>
    </div>
</div>

Approach 2: using CSS table layout, it should work on IE8+. Note, added an additional <div> into the markup.

JsFiddle Demo

.wrapper {
    text-align: center;
    background: #c0c0c0;
    border: #a0a0a0 solid 1px;
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    display: table;
    width: 100%;
    height: 100%;
}
.centered {
    display: table-cell;
    vertical-align: middle;
}
.content {
    max-width: 500px;
    padding: 10px 15px;
    border: #a0a0a0 solid 1px;
    background: #f5f5f5;
    margin: auto;
}
<div class="wrapper">
    <div class="centered">
        <div class="content">
            <h1>Some text</h1>
            <p>But he stole up to us again, and suddenly clapping his hand on my shoulder, said&mdash;"Did ye see anything looking like men going towards that ship a while ago?"</p>
        </div>
    </div>
</div>

Approach 3: Using absolute position, for triggering the scrollbar when the viewport is smaller than the content box, change position:relative to absolute

JsFiddle Demo

.wrapper {
    text-align: center;
    background: #c0c0c0;
    border: #a0a0a0 solid 1px;
    box-sizing: border-box;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    display: table;
    border-collapse: collapse;
    width: 100%;
    height: 100%;
}
.centered {
    display: table-cell;
    vertical-align: middle;
}
.content {
    width: 500px;
    padding: 10px 15px;
    border: #a0a0a0 solid 1px;
    background: #f5f5f5;
    margin: auto;
}
<div class="wrapper">
    <div class="centered">
        <div class="content">
            <h1>Some text</h1>
            <p>But he stole up to us again, and suddenly clapping his hand on my shoulder, said&mdash;"Did ye see anything looking like men going towards that ship a while ago?"</p>
        </div>
    </div>
</div>
Community
  • 1
  • 1
Stickers
  • 75,527
  • 23
  • 147
  • 186
  • Hi. Thanks for the good answer, but there are some issues. With the first one, I would like on low height resolution to have a scroolbar, but due to the negative transform half of the content is hidden under the top of the page. With the second approach, due to height: 100%, if the popup have 500px height and the window is 300px height, the wrapper will be 500px, so a scrollbar could not appear :( – Deepsy Jun 30 '15 at 15:40
  • thanks for the answer. Unfortunately http://puu.sh/iIp5M/bd2210565e.png this happens(not whole area is visible). – Deepsy Jun 30 '15 at 17:02
  • This bug exists on the fiddle you provided. Take a look at the scroll bars, the vertical scroll bar is on the highest possible position (scrollTop: 0) and the header text is cut by half, same happens with horizontal scroll: The horizontal scroll bar is on maximum left position and the paragraph is still cut. Thanks :) – Deepsy Jun 30 '15 at 17:57
  • @Deepsy one way I can think of is change position:fixed to absolute, see the [update demo](http://jsfiddle.net/gr35e0cg/1/), also updated above into the answer. – Stickers Jun 30 '15 at 18:25
  • Thanks, that works pretty good. But there is just one exception, what if the page is scrolled down? Due to position absolute it will appear in the begining of the page. – Deepsy Jun 30 '15 at 19:24
  • @Deepsy two options, **1)** set a percentage size for the content box like how it work on [fancybox](http://fancyapps.com/fancybox/) **2)** set up media queries or JS to detect the page/viewport size and choose either to use absolute or fixed position. That's all I could do, no further comments, thanks. – Stickers Jun 30 '15 at 19:29
  • I added more info into the updated answer, suggested some workarounds to make it responsive rather than scroll. Wish it helps. @Deepsy That's all I can do I believe, good luck. – Stickers Jul 16 '15 at 14:44