Search code examples
androidhtmlcssgoogle-chromecenter

Centering block on android chrome


I'm having weird issue with displaying of my web page on mobile Chrome. I have a block centered horizontally and it is displayed just fine on desktop Chrome, but on mobile Chrome it sticks to the left border of the page.

After some research I realized that there is mobile "viewport" which is different from the screen size. Thus, it is not a simple task to have something centered.

The simplified markup I'm using:

<body>
    <div class="block">
    </div>
</body>

And the CSS:

body {
    width: 100%;
    margin: 0;
}
.block {
    position: relative;
    width: 1024px;
    height: 768px;
    background-color: red;
    top: 44px;
    margin: auto;
}

I've tried also centering the block using:

left: 50%;
margin-left: -512px;
position: absolute;

But that has the same effect. Also I've tried adding viewport metatag:

<meta name="viewport" content="width=device-width, initial-scale=1">

And it does not help either. My device has 1920x1080 hardware resolution and it does display the page with real width ~1200px or so, but the "device-width" is 640px by default and if I scale the page using multitouch, it still keeps left border at the initial position.

The best possible goal for me would be having the page fixed at some resolution (1200px is just fine and no scale required for my task) and the block to be centered. But I don't see the way to set the "device-width" to the real hardware pixel size and lock the scaling... (I know how to lock the scaling, but it does not help with the resolution and centering).

An example of the page where it can be easily reproduced: http://37.48.93.204/androidtest.htm

It works just fine at desktop Chrome, but has described issue on Android Chrome.


Solution

  • Assuming you're talking about horizontal centering:

    The easiest way of centering something within it's container, would be to give it a fixed width, and then use margin-left: auto; and margin-right: auto;. This will center the element within it's container.

    The best approach would be to set a max-width and play with margins as soon as the screen size is large enough.

    Create a wide wrapper with the background image (horizontally centered) and limit the content inside that wrapper to a maximum of 1024px. Then let it resize when the screen is narrower then 1024px.

    DEMO

    HTML code example

    <html>
      <head>
        <meta name="viewport" content="width=1224">
      </head>
      <body>
        <div class="mainblock">
          <div class="topside">
            Top
          </div>
          <div class="content-wrapper">
            <div class="content">
              Content
            </div>
          </div>
          <div class="bottomside">
            Bottom
          </div>
        </div>
      </body>
    </html>
    

    CSS code example

    body {
      width: 100%;
      margin: 0;
    }
    
    .mainblock {
      max-width: 1024px;
      width: 100%;
      height: 768px;
      margin: 0 auto;
    }
    
    .content-wrapper {
      background: url('http://lorempixel.com/1224/768/') no-repeat 50% 0;
      display: block;
      position: relative;
      max-width: 1024px;
      padding: 0;
    }
    
    .content {
      background: salmon;
      box-sizing: border-box;
      min-height: 768px;
      padding: 0;
      max-width: 1024px;
      width: 100%;
    }
    
    .topside,
    .bottomside {
      max-width: 1024px;
      height: 50px;
      background-color: blue;
      margin: 0 auto;
    }
    
    @media only screen and (min-width: 1024px) {
      .mainblock, .content-wrapper {
        max-width: 1224px;
      }
    
      .content {
        margin: 0 auto;
        width: 1024px;
        position: relative;
        z-index: 2;
      }
    
    }
    

    Edit:

    Also add the viewport resetting meta tag to the head-section of your HTML code:

    <meta name="viewport" content="width=1224">
    

    Edit 2:

    Created a new demo (http://codepen.io/anon/pen/dPzJPX) and updated the initial answer.