quutdq
Last Updated: November 10, 2016
·
74.56K
· elad2412
Elad1

How to REALLY center an HTML element (via CSS position absolute/fixed)

A lot of people try to center element like modal box in absolute/fixed position in the center of the page via only CSS and fail, then they try to do it with JS(second mistake).

In this tip, I will show you how to center modal box without using JavaScript.

The trick is quite simple, instead of using only one wrapper element, use two elements.

HTML

<div class="popup">
  <div class="wrapper">
       some content
    </div>
</div>

CSS

.popup{
   position:fixed;
 left:50%;  
}

This CSS will center the element left side to the center of the window.
But we want the modal box to centered window according to the middle of the element.

Picture

And now comes the trick, because we have two wrapper to the popup, we can manipulate the inside div and will tell him to go left -50% relative, and because it is in a container he will move only half of is size to the left. And that how we center the modal box.

Add CSS

.popup .wrapper{
  position:relative; 
  left:-50%;
}  

Picture

That's it we center the element horizontal!

LIVE EXAMPLE:
Link

Enjoy!

If you like this tip, I will be happy to get your LIKE. You can follow me and endorse my skills.

28 Responses
Add your response

6655
2f18a281f9f8a30e4c491037d938be5c

Nice. What about vertical alignment? Adding simliar top properties doesn't seem to work.

over 1 year ago ·
6665

Yep, it doesn't work on vertical alignments since the percentages (both left:-50%; top:-50%) are relative to the width of the container. That's why god created flex-box (but there's also table-cell and js for the weak of heart)

over 1 year ago ·
6674

@Elad : thanks, that was very useful.

@RonnyO, @shex : well, it does work for block content: http://jsfiddle.net/ut3NR/ (removing width and height for outer and inner boxes work too).

It just won't solve inline elements vertical positioning (which can be achieved to some extend with vertical-align and line-height).

EDIT : it appears it seems to work on my example only because text has a very small height. For vertical positioning to work, we have to explicitly give the box height for both outer and inner boxes.

over 1 year ago ·
6692
0baabb7dbcb726a289966c88a1eab549

Please don't make a wrapper where you don't need to. Use display: block and margin: 0 auto, or a negative margin of half the element width, or if you can use calc() use left: calc(50% - <your element width>/2), or if you can use flexbox use that, or display: table-cell...

over 1 year ago ·
6693
Elad1

@tome , its good for supporting all browsers. It's better to use Only one wrapper. But if you need to support IE old versions?
We still use extra elements, sometimes for design. I remember the days that we made 9 elements for rounded corners. We need to prefer the minimum elements we add to the page, but sometimes is the less worse option.....

over 1 year ago ·
6694
0baabb7dbcb726a289966c88a1eab549

display: block and margin: 0 auto works in old IE, and doesn't need an HTML wrapper

over 1 year ago ·
6695
Elad1

@tome . you can't use margin 0 auto with position fixed.....

over 1 year ago ·
6696
0baabb7dbcb726a289966c88a1eab549

If you're using absolute/fixed, then use negative margins:
For a 400px-wide element:

left: 50%;
margin-left: -200px;
over 1 year ago ·
6697
Elad1

@tome you need to know exactly width...., in my solution it's dynamic

over 1 year ago ·
6698
0baabb7dbcb726a289966c88a1eab549

That's preferable to unnecessary wrappers (most of the time)

over 1 year ago ·
6699
Elad1

@tome I will agree to disagree. I show example with images. One time the image 200px width and in the second time it will be 400px, what then?

over 1 year ago ·
6700
0baabb7dbcb726a289966c88a1eab549

Then use a modern solution like table-cell, flexbox, or calc(), and let IE7 and below use overflow: auto, or lock the container width and have its contents percentage-sized. http://caniuse.com/css-table

over 1 year ago ·
6701
0baabb7dbcb726a289966c88a1eab549

IE7 is six years old. We shouldn't be filling our modern markup with stuff to support it; it's holding the Web back.

over 1 year ago ·
6702
Elad1

@tome And what with IE8?
sometimes the decision aren't always of us.

My solution benefits<br>
1. My solution it's better then to calculate with JS the exactly position(for IE7 and IE8).<br>
2. It's dynamic for for unknown width size.<br>
3. Supports IE7 & IE8. (sometimes you mast support them).

And until you bring solution that resolve all this issues, this is still necessary solution.

And if you find something that does that, I would love to know It.

over 1 year ago ·
6703
A34a9ac7c21984c5f6076620a1ee1931

Thank you for sharing this ;) it was really useful for me :).

over 1 year ago ·
6704
0baabb7dbcb726a289966c88a1eab549

IE8 supports table-cell.

If you absolutely have to support IE7 - I mean have to - looking exactly the same as modern browsers, then at least use text-align: center in the parent. At least that way, if you want to add more elements side-by-side, you can: http://jsfiddle.net/7Esg9/1/

Edit: Updated the fiddle to demonsrate the modularity of it.

over 1 year ago ·
6751
User

@tome
OP just posted a cross-browser solution that works,
What's the point of removing the extra wrapper? Making the markup cleaner and better looking, right? Your workarounds IMO make it look worse.
Anyways, I would agree with the concept of dropping the old browsers support at some point, but that's not always an option.

over 1 year ago ·
6752
0baabb7dbcb726a289966c88a1eab549

@fardjad ?comment=@fardjad (Sorry, Coderwall has a bug that replaces my "Edit/Delete" with your "Reply")

The point of removing the wrapper is less to do with cleanliness than the modularity and re-useability of the relevant CSS. The 'ugly' (and I agree it is uglier) CSS should be handled by a preprocessor anyway - centering an element horizontally in fixed/absolute positioning is something you'll need to do all the time, and that means editing the CSS will require a lot of comparatively awkward HTML editing, and quite of lot of HTML 'divitis'/bloat.

To be clear, <div> and <span> are intended to be unsemantic tags, so the semantic value of the markup isn't one of my concerns here.

It's also worth noting that the modern solutions I emphasised in my first comment as being strongly preferable to an IE7 workaround can look much nicer than the workaround, particularly in the case of calc.

over 1 year ago ·
6805
Regent twitter

This is a clever technique.

Yes, there are places where margin 0 auto; is the best choice, and there are places where negative margins are the best choice. But this is the best solution, or at least a very reasonable solution, for a specific class of problems where you have a fixed positioned element with a highly dynamic width which needs centered, and supported across all browsers.

Not using a wrapper when you don't need to is certainly a good principle to work by. But another good principle is: don't sacrifice cross-browser support to avoid using a wrapper.

It's simply not the case that everyone can develop using only the most modern browser techniques, and I don't think a healthy debate centers around the value of competing techniques which cannot be proven objectively better in all cases, nor do I think it's appropriate to look down your nose at people who disagree with those non-objectively provable claims.

I think this is a good technique, used in the right situation. So, thanks for the tip!

over 1 year ago ·
6822
Bbccad8b762ed44688e2f0090826baf9

That helps.

over 1 year ago ·
12380
Default profile 4 normal

A simple guide on CSS positioning

http://www.corelangs.com/css/box/positioning.html

CSS tutorial

over 1 year ago ·
12935
Default profile 6 normal

Hi All,
A best simple way to do this
There is no need of wrapper class
for horizontal u can use
.popup{
position:fixed;
width:200px;
height:300px;
left:0;
right:0;
margin:auto;
}
best way

for vertically u need two more css above this in first use display table, in child use display:table-cell; vertical-align:middle;
then use your design div

over 1 year ago ·
12936
Default profile 6 normal

use left:0; right:0; margin:auto;

over 1 year ago ·
13623
Profile square

Nice.

over 1 year ago ·
14264
Elad1

@georgemacin , the issue in this way, that you need to know the width to center, and it isn't always the case.

over 1 year ago ·
17919
Screen shot 2014 11 20 at 9.32.15 pm

nice trick. lemme try it

over 1 year ago ·
18255
538dd6d2b244c8c0dc8abf7f589fc75d

It is a magic! Thank you!

over 1 year ago ·
27628

OK, this it totally awesome - I've tried a whole bunch of stuff to center my fixed div and NOTHING else has worked across all browsers. Many thanks!

7 months ago ·