Hacker News new | past | comments | ask | show | jobs | submit login
The complete guide to centering a div (tipue.com)
390 points by SteveP1961 on Feb 2, 2014 | hide | past | favorite | 165 comments

Whenever anybody says that CSS is easy, or "of course you can do that with CSS", or even hints that CSS is somehow well-designed...

...the only thing I really need to say, is that every couple months, on Hacker News, where a lot of really smart people hang out, a new top-voted story comes up about how to center a div. With tons of comments and discussion too. And it's not even a joke.

What more is there to say?

CSS has two faces, the awesome "You can make amazing things with ease" face and the "It won't do what I want unless I create some cludgy arrangement of elements in order to attach a combination of weird properties"

Those two faces are because of two simple facts.

1. CSS is a really good way to set properties.

2. The properties are shit.

The part of the properties that is most gloriously broken for layout is that the X and Y dimension behave differently. That's _really_ not what a lot of websites want.

I experimented a while back and came up with a model for placement like this


If you had properties like these you could center, proportionally center, left/right/top/bottom align and handle growing in the direction the user wants.

What CSS needs is a new generation with all new properties, a full modal change so that it doesn't have to be backwards compatible and interact with archaic properties.

With the GSS constraint solver stuff like this becomes very easy...

  #div[center-x] == #container[center-x];
(note that this is fully source order independent. It doesn't matter where in DOM the elements #div and #container are)

Have you tried flexbox?


I have had a look at it. It doesn't fill me with confidence. It looks like it will make some things possible that previously required wrapper elements, but it doesn't seem to be very easy to imagine scenarios.

It feels like it is a solution directed at specific problems, whereas I always felt that was much of the problem with CSS properties. They solved their target problem and if your problem was different to their one you might be out of luck. If the properties were defined to be more general I think a lot of those problems would never have appeared.

CSS was created for styling. Bold, colors, borders, that stuff. It was not meant as a layout engine. Hence the name, of course.

Floats were meant for other stuff (placing pictures in the flow of text and such). They are just as much as an abuse as using tables was for layout.

But tables, at least, had one thing going for them: they are an almost feature full layout system for most needs, with sane defaults, and familiar (from all grid layout systems) behavior. So both CSS and tables were abused for layout, but at least with tables they picked something appropriate to abuse.

Now, finally, CSS has some extra functionality (flexbox, multi-column etc) that was added later as specifically intended for layout. Which, of course, is not fully supported and implemented yet.

Btw, the whole idea of "semantic html" is another cargo-cult -- people conflating the webpage (a presentational output) with some intermediate format, forgetting that REST, JSON, DBs et all are far more appropriate for that repurposing of content.

Basically a bunch of designers who knew nothing about computer science, taxonomies, RDF, etc, thought it would be very sophisticated to adopt this "semantic" word. So, they started building pages caring about the naming of elements and such, as if webpages are meant for screen-scrapping (some hand waving always included support of "reading devices", who nobody of course ever tried to actually test with his pages -- they'd found out they're specially adapted to work with regular noise webpages).

> the whole idea of "semantic html" is another cargo-cult -- people conflating the webpage (a presentational output) with some intermediate format, forgetting that REST, JSON, DBs et all are far more appropriate for that repurposing of content.

Exactly right. The semantic content is structured data, not HTML. If you want to decouple semantic content from presentation, that's what your API is for. HTML is a presentation format.

You seem to be very upset about all of this...

The nice thing about semantic HTML is that any metadata and structured data is a part of the document itself instead of hidden away somewhere else through an API. This has its disadvantages (I'd rather interact with an API than scrape a website, even if it's all tidy and semantic) but it absolutely also has advantages. The usual alternative to semantic HTML is not a well-designed API, the alternative tends to be nothing.

>You seem to be very upset about all of this...

Which is neither here nor there regarding the validity or not of what I say, and a little rude to boot.

>The nice thing about semantic HTML is that any metadata and structured data is a part of the document itself instead of hidden away somewhere else through an API. This has its disadvantages (I'd rather interact with an API than scrape a website, even if it's all tidy and semantic) but it absolutely also has advantages. The usual alternative to semantic HTML is not a well-designed API, the alternative tends to be nothing

Which is fine too, since the usual case also is that nobody is consuming the raw html anyway except the browser.

I write my HTML semantically primarily for myself. It's far easier to read, debug, and develop when the structure makes sense and isn't littered with a dozen nested divs with incredibly complicated class names.

>I write my HTML semantically primarily for myself. It's far easier to read, debug, and develop when the structure makes sense and isn't littered with a dozen nested divs with incredibly complicated class names.

Sure, but nobody called for "a dozen nested divs". You can ease the same number of divs, semantically or not. Just make the styling targets are encompassing as they can be.

Semantic HTML isn't about formatting HTML as a data format. That's not what HTML is. It's about formatting HTML as a sane to read document. It makes it more accessible, more understandable, and easier to develop when the structure makes sense and isn't full of hacks.

That's also wrong. HTML is not the document to read.

HTML is a MARKUP format. The document you're meant to read is it's rendered output in the browswer.

In fact the original TBL's HTML vision included tools to work on the HTML, not manually editing/reading the code.

Haha... hadn't seen that one before.

> With tons of comments and discussion too

To be fair, the majority of comments tend to either be ones like yours, or ones elaborating on the "CSS is somehow well-designed" front.

As others have noted, tools like flexbox make what the article is trying to accomplish easy. The issue is that lots of users run really old browsers, so if you want a single solution across your user population, you're going to have to resort to the same really old hacks.

It's silly to say that "nothing has changed", when what you're really saying is "nothing has changed in the browsers that haven't changed". I'm not sure that should be surprising.

Well no, the issue is that we're getting close to 20 years since CSS was introduced and they only got around to introducing something that makes this basic simple task 'easy'[1] relatively recently. It's not even like this was some basic part of CSS2 that got ignored by vendors, it became a candidate recommendation for CSS3 in 2012.

[1] It makes it 'easy' by introducing yet another weird box modelism that doesn't really fit anything else that's already there. It's really as much a symptom of these problems as a solution, imo.

I'm not sure what your point is. Web standards have had a turbulent history? Of course that's true.

- CSS 2 was originally published as a recommendation in 1998. CSS 2.1 was pushed as a recommendation in 2011. Maybe something was wrong?

- "Ignored by vendors" is a bit of an understatement, because your "close to 20 years" includes 5 years of the vendor with 90% marketshare not releasing anything at all.

- FWIW, what became flexbox was useable (assuming polyfills aplenty) in Firefox and Webkit browsers 5 years ago[1]. It took some time to standardize, but while frustrating in the present, it's ok to take time to make sure the spec works, because it will be (in theory) around for quite a while.

> It makes it 'easy' by introducing yet another weird box modelism that doesn't really fit anything else that's already there

What many people don't appreciate about layout in general (and WRT to the web, dynamic layout in particular), is that it turns out to be difficult (and sometimes extremely computationally expensive) to implement an expressive layout system that does what we intuitively think it should. A good example is word wrapping, which is easy to tell when it "looks right" (at least to a trained eye), was done by hand by many when printing was done more manually, but turns out to be difficult to assign a metric that handles all use cases, especially when you're trying to be computationally efficient.

Web layout is like a whole set of word wrapping requirements, expected to get along and paint a page in real time. The process that birthed CSS is nowhere near what you'd turn to if you wanted to develop a cohesive styling whole, but it's how history usually plays out. If it's any consolation, I personally don't think there's a comprehensive theory of everything for styling anyways, so there are always going to be aspects that need to be learned, not inferred.

In any case, flexbox is pretty straightforward if you spend an afternoon with it, just a constraint-based layout system that maps pretty well to how you would describe a layout like that.

[1] http://infrequently.org/2009/08/css-3-progress/

> Maybe something was wrong?

Well yes, that is exactly my point. It's not like the desire to center things vertically came about a mere 5 years ago, it was a thing that people were doing in 1996 when CSS was first propagated.

I don't really get your point. You seem to be arguing that people shouldn't have been frustrated for the last 17 years by CSS' inability to do basic and non-novel tasks simply because it's starting to become possible now.

My post may have been confusing because I was addressing two different things, the standards process and the merits of flexbox's design.

> You seem to be arguing that people shouldn't have been frustrated for the last 17 years by CSS' inability to do basic and non-novel tasks simply because it's starting to become possible now.

The standards process is frustrating. For the CSS working group in particular, there was until relatively recently a stubborn clinging to monolithic CSS standards even with nearly a decade of evidence that holding up everything people agree on until people agree on everything is not a winning strategy. That's how you end up with being unable to center a div for so long.

Flexbox's particulars aside, however, my point is that there is a difference in kind, not degree, between "trying to express this in CSS makes me want to murder the universe" (the case in 2008) and "this thing does not work in a browser from 2008" (the case today). If your point is that it's taken a ludicrously long time to get there, I don't think you'll find anyone to disagree with you.

>It's silly to say that "nothing has changed", when what you're really saying is...

I don't see the GP comment saying that, what are you respondng to?

Next week: The complete guide to sticky footers!

It's unbelievable just how annoying CSS can be for seemingly simple things.

I may be using words incorrectly, and I'm not positive you can even make the distinction, and I am happy to stand corrected, but it always seemed to me that CSS was fine for style, but terrible for layout.

So I think I'm agreeing with you.

I think the issue, in terms of CSS being bad for layout, is that it tries to treat the logical structure of the document as the layout structure. If there were a way to restructure the document and then apply CSS to it a lot of things would get a lot easier and separation of content and presentation could be more realistic.

XSLT was interesting in providing some of this kind of restructuring power, but was far too heavyweight for pure layout manipulation.

Of course, this is also what flexbox tries to do and I think we'll be groaning about its lack of relative power in this area in the future when it's more established. It feels like a bandaid to me.

Right, to me plain HTML tables are great for overall master page layout yet it seems everything I've read and the few web geniuses I've met will deride using them over CSS.

Same here. It's amazing how convoluted "modern" CSS can be compared to simple, reliable tables.

Layout with CSS is really much simpler than doing that with tables.

Exactly. I mean, I get the part where people are against layout with tables in principle.

I just hate the part where they act like CSS is a good alternative in practice.

Even better is to draw everything in a canvas!

To that point, no human should have to work directly with CSS for layout!

Generally I agree that too many people have a fetish about avoiding tables when it's clearly the right tool for the job. But I've definitely been bitten by using them. Table layouts don't play well with other CSS properties.

If you are using HTML tables for layout then you definitely aren't using the right tool for the job. If it isn't tabular information then it doesn't belong in a table.

You can easily get around that by using `display: table` and `display: table-cell` So you have your semantic HTML elements, if you're into that sort of thing, and flexible layout options, like `vertical-align: middle`.

Depending on how you do the layout it also may not play well with screenreaders.

Why do people care about screen readers? Is it because they are good people and want to make sure sight-impaired visitors are able to access their content? Or is it because they have contracts that require 508 compliance?

Why does it matter why they care? Does doing it for 508 compliance somehow make it less important? It's simply the right thing to do.

I ask purely out of curiosity, not because I think the answer should affect my, or anyone else's, actions.

I guess it's a good question. At a recent conference it [website accessibility] was described as the digital equivalent to putting a ramp in at your door.

Where I work at the moment I'm required to comply with WCAG2 AA at a minimum.

> but it always seemed to me that CSS was fine for style, but terrible for layout.

I think you're right there. When I've set colours, fonts, etc in CSS it's always worked first time, but getting layout right it feels like I'm fighting against the system all the time.

I wonder if it wouldn't make sense to build a tool that abstracts out the layout part of CSS? I once built a tool in python that lays out Tk/Tkinter GUIs[1] which I may have a go at adapting to produce CSS/HTML output.

1: https://github.com/cabalamat/parrot

This is as close as I can get without HTML tables:

  <title>Testing making a footer with CSS</title>
  <div id="divpage">
  <div id="divcontent" style="overflow: auto; height: 60%;">
  This is the content area.
  <div id="divfooter" style="overflow: auto; height: 30%;">
  This is the footer.

I usually go with the footer height 50px, content min-height 100%, bottom-margin -50px. Generally works, but still has some edge cases that can throw it for a loop.

Whereas what I instinctively want to do is something more like a conditional absolute positioning. If the content fits above the fold, then have the footer absolute at bottom:0. Else, have it relative to the content div. It can be done in JS of course, but I feel it should be a lot easier to do in CSS.

Honestly, please don't use sticky footers. I curse CSS not because that's difficult, but because it's possible. :/

In the case of sticky footers I'm all for the adage "if it's annoying to use, it should be annoying to style".

I recently went back to a project to convert the CSS to SASS, and shit was over 1,200 LOC. I think I managed to trim something like 200 LOC, but it turns out that there were a truckload of hotfixing for all the evil quirks CSS throws at you at every given opportunity.

The LOC just grows exponentially, when you approach 100% non-quirky cross-browser uniformity.

I will say this; CSS is a great lesson in humility for every hacker and programmer who try their hand at it. And you can learn a lot about someone by how they describe CSS and the front-end developers who make a living working with it.

This is why, even though I have been doing on and off web development since 2000, I jump of joy when allowed to do native UI coding instead.

Most native frameworks provide tools to position elements, although at the end of the day they are just positioning things on an x,y,z axis.

Using CSS and JS you can do the same thing, respond to events and re-position your elements.

The problem is, people get preachy about how you shouldn't use JS for this, because websites should be progressive and degrade gracefully. Native code doesn't have this problem as much as it's not only accepted, but viewed as cool when you only support the latest OS version (iOS7).

My main problem is not only layout, but the whole design stack.

I do like UI programming, but like many of us I am a bit lacking in the design area.

Native toolkits allow me to ramp up pretty quickly UI thanks to components and layout managers. When something is missing I can drop down to pure graphics programming.

With web designs, it doesn't matter how much I try, without the help of a designer guy on the team, I always end up hacking around until something kind of works, repeating it ad nauseum for all required platforms.

Surely we can agree: designing text and images in a fixed frame without alternatives for accessibility is a completely different ball game then designing for screens of immensely variable dimensions with audiences as diverse as completely blind users and search engine bots.

Does anyone have an alternative to CSS that tries to take on a problem this big?

To be fair, CSS is hard even if you're only designing for one screen/device.

Many tools that handle diverse problems are worse in specific problems: jack of all trades, master of none

(not trying to make the case for CSS being good)

Anytime someone says CSS is well designed, ask them how to vertically center something and look at their face as they go through the five stages of grief.

I'm pretty good at CSS I suppose, and it's not something you can learn logically and progressively. You have to learn all the weird nuances and quirks of it as well as the syntax.

EDIT: speaking of CSS, if you want to know true pain and nothingness, try making responsive emails that look good at three sizes on several clients in CSS.

Not too long ago I saw the best simple solution to vertical centering. It was so obvious:

position: absolute;

top: 50%;

transform: translateY(-50%);

Translate is processed at the end, meaning it is based on the final element height. This means it works with any element, even dynamic heights. Of course it only works on relatively new browsers, but translate is well accepted and on the path to being ubiquitous. The style is also easy to understand and isn't hacky.

I think the parts of CSS that are designed are well designed (considering how hard the problem space is). However, lots of CSS just wasn't designed at all. It was just everyone throwing in their conflicting specs and implementation without any coordinating. But that was pretty much all of the web. All things considered, I think we're not too bad off considering how crazy things were in the early days.

Also, any time anyone complains about CSS, I just show them some pre-css code with `<font>` tags and `bg-color` properties and insane tables. That gets them to shut up pretty quickly. :)

>Also, any time anyone complains about CSS, I just show them some pre-css code with `<font>` tags and `bg-color` properties and insane tables. That gets them to shut up pretty quickly. :)

Nothing is insane about "tables". It behaves as a classical grid based layout system, even though it was not intended as such. That's why it was such a good fit.

As for the "font" tags and bg-color properties, nothing strange about them either -- at least nothing worse than a style="" tag. Besides, that's the formatting part, which CSS is quite good add, we're talking layout here.

It's not that bad when combined with other methods of positioning, but remember, back then there was nothing else available, meaning you had to use tables for everything. Of course, the biggest problem was the lack of classes, meaning you had to redefine every style on every element.

Agreed. I think everyone will move to canvas eventually (for the whole site), and get over it.

Of course, CSS was a compromise between old guard semantic "purists" (who envisioned an HTML document as being pure text with structural meaning semantically applied to the content via tags, with the browser in full control of presentation) and designers, who wanted control over look and layout (the fools!). And so, CSS was created, and designers could have their silly colours and fonts. Any layout or typographic abilities were added as a neglected and poorly considered afterthought.

Designers being what they are, worked out systems like tables, and the hacks in the link to get what they want out of CSS anyway. (but why would you want to centre anything? that's stupid! the original designers of CSS grumble)

meanwhile, far superior systems, such as "Constraints Based CSS" were proposed, and ultimately rejected because it's stupid and irresponsible to want to control the layout of a webpage!

Now it's 2014 and we have flex box as a patch over. Constraints based css would have been much better, and that's what you get in Cocoa Auto-layout now,

but oh well. let's copy java and flash. what difference does it make?


I don't know anything about the history of CSS's design, but I'm perpetually amazed that positioning (and specifically centering) requires so much CSS magic. I would think CSS positioning would be a one-liner, but instead it's a collection of context-dependent, browser-dependent recipes. I wonder if there's a good reason for the madness, or if it's just poor design. (FWIW, I'm a backend engineer and have only dabbled with front-end code.)

The thing that boggles my mind is that we're over ten years and three major versions in and we can't center stuff reliably or conveniently, images won't scale up to fit (only down...), multi-column text is barely implemented and Google is ripping it out, the box model is borked by default, it's non-trivial to determine the layering of UI elements, and so on.

It's amazing that we get solutions for things that no-one really needs (animated 3d transitions...) while bread and butter stuff still requires rocket science. Back in 2005 I used to joke that 90% of the world's Javascript was just doing button rollovers (probably a conservative estimate) — well, CSS eventually fixed that, kind of — now Javascript is mostly doing similarly idiotic stuff like handling resizing, making things that aren't lists impersonate lists because multi-selects are borked, centering stuff, and trying to reliably hook up event handlers.

All of which were solved problems before the web was born.

Good thing we are practically putting all our eggs in this basket.

HTML and CSS will be our document structure, and javascript will describe how the document behaves. Truly a universal standard for the ages.

Humans are dumb.

Javascript gets a lot of shit, but really the biggest WTFs are HTML and especially CSS. Javascript at least has Crockford. No-one really has a handle on how to deal with CSS -- it's a wall-to-wall disaster.

Preprocessing languages like SASS help a little. They don't really fix the ugly parts, but do help shove them under the bed a little more

images won't scale up to fit

img { width: 100%; }

multi-column text is barely implemented

columns: 3 [1]

Google is ripping it out

No, they’re not. You’re thinking of CSS Regions?

the box model is borked by default

It’s different to what you’re expecting by default, and you can flip it to your required behaviour with a single switch.

it's non-trivial to determine the layering of UI elements

Fixed z-index? And if you’re concerned about different stacking contexts, they solve a problem in themselves.

[1] If you don’t care about IE8+9 http://caniuse.com/#feat=multicolumn

> we can't center stuff reliably or conveniently

Flex box fixes this. The only reason not to use it is old browsers.

The browser your employer ships only currently has partial support for flex box. Why do Mozilla employees insist on being misleading about Firefox's standards support? Flex box is not ready for mainstream use. Not just because of 'old browsers', because of your current browser.

https://bugzilla.mozilla.org/show_bug.cgi?id=702508 this won't be in the stable release for a couple of months.

See http://caniuse.com/#search=flexbox for other issues

You have been able to center stuff using flex box for years in Firefox.

Yes, in a way that was incompatible with other browser i.e. useless.

"It's amazing that we get solutions for things that no-one really needs (animated 3d transitions...)"

I believe you will see some really amazing animated 3d ransitions used in production very soon, and they happen to be necessarily for the user experience, reducing needed document space for larger amounts of visual blocks.. at least in the projects I know they are being developed on.

CSS 3D is lovely, but it would be nice if they -- Apple, Microsoft, Firefox, and (especially) Google -- took care of freaking business.

The latest Chrome on Windows has completely screwed up select controls for no apparent reason -- they do things like fade and zoom in, but don't actually work properly (I'm a Mac guy, but our Windows guy has been cursing Chrome for days).

> we can't center stuff reliably or conveniently

Yes we can. The problem is not the lack of ability, it's that no one is backporting to IE8 or IE9 but lots of people still run them.

> images won't scale up to fit (only down...)

I don't understand what you mean here

> multi-column text is barely implemented and Google is ripping it out

No, the currently shipping implementation of multicol will be staying. I think you're confused about the rewrite tied to CSS Regions, which has never been turned on in Chrome.

> the box model is borked by default


> it's non-trivial to determine the layering of UI elements

I don't know what this means either. You do have to know what a stacking context is, true, but a quick trip to MDN and browser developer tools will help you out if you're confused.

You're completely missing the point. Having elaborate workarounds for utterly common problems that have all kinds of edge cases is exactly where we were with button rollovers in 2005.

All the W3C had to do for CSS2 was look at Mac App or Cocoa or any other decent GUI framework and figure out what needed to be added to make all that stuff work simply. Instead we get ridiculous crap that sort of half solves the problem if you do it in just the right way and apply a couple of rolls of duct tape to it. We're at CSS3 (?) partially implemented with stuff being proposed for CSS4, and none of these common problems have been solved.

No, you missed what I wrote (for instance, nothing of what I wrote would qualify as "elaborate"). If you're referring to centering a div, the issue is not workarounds because the specs are half-assing it, the issue is workarounds because people are still running IE8. All current browsers ship flexbox. You can stop catering to those older browsers, but that's a business decision, not a web standard one.

Best time to plant a tree is 20 years ago and all that. CSS 2 came out in 1998. At some point, you have to let it go. Current state is very far from perfect, but the common problems you listed have been solved.

The article's example for "vertical" centering is both elaborate and doesn't actually work unless you dedicate the outer div entirely to centering and you do it by fixed dimension. Every "solution" I've seen or tried to this problem is actually a workaround that only covers a subset of possible (common) cases.

And requiring the middle div to be fixed dimension for centering to work is dire.

By contrast, imagine if something like position: absolute, align: center center; just worked! Or imagine if the elaborate CSS syntax for positioning background images were available for positioning any element within its offset parent. Imagine if offset parents worked sanely.

Again, centering a control within a rectangular context was a (i) known, (ii) common, and (iii) solved problem outside the web browser in 1990. Go see how resizing is handled in Interface Builder -- same as it was in 1989.

If there's a solution to cleanly upscaling images to fit, I'd like to know what it is. Downscaling relies of max-width|height which itself is more of a lucky side-effect (like most of the "solutions" CSS provides).

And the problems I point out in the second paragraph, such as having to write all kinds of code to handle resizing, are totally intractable with CSS right now.

> I wonder if there's a good reason for the madness

Well the reason is that CSS originally wasn't intended for layout….

But since there was no other tool for layout, once the web design community decided to remove tables from layout it got drafted despite being severely insufficient. Layout modules have just started being developed, fought upon and implemented in the last few years. Here's how vertical centering looks like when using flexbox (http://philipwalton.github.io/solved-by-flexbox/demos/vertic...):

    .parent {
        display: flex;
        align-items: center;
        justify-content: center;

    .centered {
        max-width: 50%;
(note: this ignores prefixing, specs differences and browser-specific issues, here's the component https://github.com/philipwalton/solved-by-flexbox/blob/maste... which is itself expanded to suit browsers)

The sad thing is that I'm going to bookmark this.

Well, I have bookmarked it both for the article contents and for the discussion. As is often the case.

The Web Styling Challenge: you and another person are going to make a web site. You are doing the HTML, while the other person does the CSS (you can discuss it and swap jobs if you want). You can talk as much as you want ahead of time, but the only record you can keep is a table that maps CSS selectors to a description of what you'll be using them for. You are then split up and do your individual tasks. When you're finished, you will be judged on how broken the results of combining your pages with the other person's stylesheets are. I think just imagining how this game would go makes it pretty clear that CSS is lousy at separating the concerns of style and layout.

> Centering a div Within a div, Horizontally and Vertically

The code in this section is incorrect. "margin: auto" does nothing in the vertical direction. If you set the height of the outer div to something more than 160 px, you will see that the inner div is not centered.

Came here to say the same thing. Not sure the rest of the article is worth reading if the author doesn't know CSS well enough that a) they don't know a priori that this is wrong, and b) manages to convince themselves it's true using Codepen

Here's the Codepen that shows it with a larger outer div,


No, it doesn't work with a fixed height. I didn't claim it did, of course. In a responsive world fixed heights in a container are somewhat irrelevant, but I'll amend the article.

It sounds like you are trying to say that the equal top and bottom padding is what is giving you the centering, simply by way of the fact that there is no empty space remaining to fill. Fair enough.

Regardless, the fact that you used "margin: auto" as opposed to "margin: 0 auto" in this particular example is somewhat misleading, as well as the fact that in the description you refer to this as the "margin auto trick". As noted previously, "margin: auto" does nothing in the vertical direction, and the sample would behave identically in every browser, past and present, even if you had used the more well-defined "margin: 0 auto" like in the other examples.

What? It doesn't work at all -- without a fixed height, the height of #outer would be determined by summing the heights of its statically/relatively positioned children.

If there were multiple children of #outer, #inner would still not be centered vertically. This only works for some trivial definition of vertical centering, when what you really mean is that a single block child will occupy the vertical center position of its block parent, provided the parent's height is not specified. Which is the most obvious of statements in CSS.

It works in a container with no fixed height. Perhaps it doesn't work for your particular requirements, but it does work.

The the element is merely sitting on the line-height and not being positioned. So no, I think you are incorrect on that one. It is a nice bit of work otherwise.

Thanks, but isn't that semantics? :-)

The height of the outer element is determined by the height of the children, plus padding. Since you have only one child, then the outer element is as tall as that one child, plus padding. Ergo, assuming symmetrical vertical padding, the inner element will by definition be centered.

It would be as if I wrote a tutorial on how to make one element fill the entire viewport, and one of my methods was "put all your content in the <body> tag" and I said that was a way to fill the viewport. That is the trivial case, it's a degenerate solution!

> it's a degenerate solution!

Well, there you go. :-)

I don't think it is semantics, setting vertical margin: auto here has just no effect.

It's worth noting that the last example with margin:auto can be used for centering within any div that has position: relative (there's nothing special about the whole page). It also works for intrinsic dimensions, so you can center an image without knowing its size, see http://jsfiddle.net/jdudek/hfbnS/1/.

There are a few more useful techniques not covered by this article, for example:

* line-height + vertical-align: middle + display: inline-block (which allows you to center vertically an element with dynamic height)

* display: table-cell (mentioned by others in this thread, although without stating its disadvantages).

While I appreciate the effort, calling the article "complete guide to centering a div" is an overstatement.

Margin auto does work, and it'll work for most people when they need it to work.

What they're getting at is that the vertical aspect of margin:auto (that is, margin: 0 auto vs margin: auto) has absolutely no effect in your example. For your own credibility (since this purports to be a "complete" guide), this needs to be fixed and you need to add the table/table-cell method.

I think it would be best to simply replace that example with what is essentially the last example, which is much more useful. This codepen[1] shows the markup within another div. This is by far my favorite centering method, although it requires a fixed or percentage height while table/table-cell does not. It also avoids some of the bizarre quirks of table/table-cell, so there are times when one or the other is the best method.

[1] http://codepen.io/anon/pen/whHIL

I wrote this five years ago. I'm somewhat dismayed at how relevant it still is today:


That article, and especially the second followup, are brilliant. Well argued, sharply written.

Thank you!

My utmost favourite technique for centering unknown width and height DIV's/elements perfectly center in the page is using 2dtransforms. I've created a Codepen here that shows off the technique, it's simple and well supported IE9+: http://codepen.io/Figurated/pen/zcypx — if you don't need to support IE8 any more, it's a perfect solution.

My favourite technique: position absolute and top: 0 bottom: 0 left: 0 right: 0

also doesn't require a fixed width http://codepen.io/anon/pen/vsliJ

Your technique is less good (on IE11) when you resize the width of the browser. The text finish outside the div, while DigitalSea's solution works well.

That's great! And it seems to have pretty good browser support.

This is a pointless post. Use the TABLE tag. Yes, it will violate the purity of CSS, but you can trust it, and it will make your day better because it will free you angst and from extensive cross-browser testing. Simple is better than complex. Straightforward is better than arcane.

As igvadaimon wrote below, there's no need for a <table> tag. Instead of:

        <td> my div </td>
you can do

    <div style="display: table;">
      <div style="display: table-cell;
                  vertical-align: middle;"> my div </div>
The inline styling is just for illustrative purposes, of course.

I'll admit that the table-cell approach is nice -- thank you. But how curious that the article, which purports to be an in-depth examination, doesn't mention it. And how curious that the table-cell approach has not turned up in the numerous times I've gone looking on-line for a robust, pure CSS solution. I've long harbored suspicions that many CSS gurus are too quick to adopt complex solutions.

It doesn't mention flexbox[0] either. It's not an in-depth examination, it's blogspam. There are better[1] years-old[2] resources which are no more incomplete.

[0] http://philipwalton.github.io/solved-by-flexbox/demos/vertic...

[1] http://css-tricks.com/centering-in-the-unknown/

[2] http://gtwebdev.com/workshop/vcenter/vcenter-inline-css.php

It feels like they're doing "something right" by avoiding <table> at all costs, even if it means emulating the same behaviour that's already built into the browser with a set of CSS rules. This is blind faith, not reason... and oddly enough I've noticed this type of dogmatic thought far more in the web development community than in that of any other programming language. My own philosophy on writing webpages is to do the simplest thing that works and don't obsess over layout; the content is more important. I'll use tables when they make things easier, CSS when it makes things easier. But never do I give any consideration to "X is bad", "always use Y" etc. After all, your visitors probably couldn't care less whether you used tables or CSS.

I think, at least in some small part, the people who went over-the-top anti-table in favor of CSS don't advocate table-cell usage for that reason.

That is, it could be read as kind of an admission of CSS's shortcomings for layout, and HTML table's relative ease for same.

Kind of like saying, "Don't use HTML tables. They are evil and you are an amateur. Use CSS instead. It is amazing and absolutely rocks. Er, BTW, if you actually want it to work, use table/table-cell properties, etc".

I don't know the current state of browser's but the is likely because, at least at one time, the display type of table wasn't widely supported.

On the other hand support for centering vertically with auto isn't/wasn't widely supported either.

Using display: table-cell on a div is a more semantic approach than using <table>.

God no, I just threw up in my mouth.

Once your website is sufficiently complex, having to trail and which td belongs to what tr in which td is a NIGHTMARE.

Don't do it people - coming from a front end developer. A backend developer has no business commenting on front end issues, just a javascript developer shouldn't really dive out advice on proper DBA procedure.

Using some discipline with indentation easily solves the issue of nesting table-related tags.

Also, I would gently recommend that asserting one's status is a poor substitute for discussion of an idea's merits. Dogmatism is always injurious.

If you don't have the experience why would your novice opinion be valued?

What about cases in which developer wants to vertically center a div, but he or she doesn't want to specify a height property?

"display: table-cell" with "vertical-align: middle" works.

That this is missing is surprising. This method is the most compatible across browsers and only real drawback is the additional markup.

Well, of course it comes with gotchas:

- if that item is "display: table-cell", it must be within a larger element that's "display: table" or "display: table-row"

- "vertical-align: middle" works also for inline-block elements, but that means it's subject to all the other gotchas present in the article about explicit sizing

It eventually makes a kind of sense, but these rules are passed down in folklore and trial-and-error.

Your first point isn’t correct: if you have a solitary element with display:table-cell it’ll generate the appropriate anonymous elements needed for display.


This article nicely shows all the alternatives with a list of caveats for each: http://coding.smashingmagazine.com/2013/08/09/absolute-horiz...

Then unfortunately you have to calculate it with JS if it varies. Vertically centering divs has always been a gigantic pain-in-the-ass. If anyone has a better idea for doing this without JS, please let me know. Once CSS implements variable-based elements (ie #div.height) then we'll have a lot more control.

> If anyone has a better idea for doing this without JS, please let me know.

Flexbox, with optional fallback to JS for IE 8 and 9. That said, vertical centering is almost always a nice-to-have rather than a must-have so personally I wouldn't even use a fallback.



As mentioned elsewhere: "display: table-cell" with "vertical-align: middle".

This is my favorite vertical centering method [1] and combined with the table/table-cell method, it allows me to avoid using JS for layout about 95% of the time. It's not very well-known and even though I've used CSS for well over a decade, I have no idea why it works.

The real trick is realizing that `margin:auto` actually does do something, so long as you set a fixed width/height and position: absolute with dimensions set to 0. But for the life of me, I don't understand why that happens to trick the box model into working properly. But this technique is fantastic and really helps out when table/table-cell interacts badly with your styles, or you need to support older browsers.

I would be very happy if someone in the know could explain why this technique works.

[1] http://codepen.io/anon/pen/whHIL

I was wondering why the demo is not working for me. it really took me a while to realize that it is actually a button.

Obviously you can't show off css in the same browser window as your text, that would be insane. No, you have to load up a completely different website, that makes much more sense.

CodePen shows live code that can be edited and played around with. It does make sense.

No, it does not. It is good to be able to play around with the code, but to require someone to see the code working it is overkill.

Okay, good point. :-) I've changed it and hopefully it's more obvious.

damn, I thought that box was supposed to show the alignment of the div itself too, and I couldn't figure out why it looked always the same

<center><div>I'm centered!</div></center>

DRY, though, right? Changing one set of CSS rules is better than hunting down 20 <center> elements when requirements change. Not to mention <center> is deprecated.

When requirements change —

    center { text-align: left }

A simple search-and-replace is enough to get all the <center> elements... and chances are when the requirements change, that's the least of the structural changes you'll have to make. IMHO all the CSS purists do is overcomplicate things.

That works great vertically! </sarcasm> Did you even read the article?

Time to introduce a new tag into the standard!


Relax, I'm not recommending anyone actually do it that way. I'm just old and found it humorous that something as simple as centering a div requires an entire article.

A few additions. If you know the width and height of the element, centering horizontally & vertically can be achieved with one <div> like so:

.center-div { height:100px; width: 100px; position:absolute; top:50%; left:50%; margin: -50px 0 0 -50px; }

This can be modified for the 'centering at the bottom of the page' example, but with more efficient code.

More challenging is centering the unknown: http://css-tricks.com/centering-in-the-unknown/

Is it me or is the content of this page annoyingly off-centered?

For an in-depth look at all the different options for centering an element, have a look at Stephen Shaw's research on Codepen: http://codepen.io/shshaw/full/gEiDt

This article is not actually correct. There are really 2 or three techniques for centering a block level element. The post repeats these techniques for multiple scenarios, and is wrong about the first vertical centering technique.

Maybe I'm thick. The article is dated February 2014, it says flexbox "currently lacks browser support, mainly in IE (version 10 has partial support and full support won't arrive until version 11). Chrome, Safari and Firefox have support but with browser vendor prefixes."

IE11 came out in preview in June 2013, released officially in November 2013, and at least IE and Mozilla are currently supporting it unprefixed (though Mozilla's multi-line flexbox fails last time I checked). This article is over 3 months out of date, if not more, but being presented as new and current.

I've been using Flexbox for a while now. Unless you need to support older IE than it is quite usable. The one problem is the older syntax for IE10 but it is fixed in IE11 and going forward.

I've been working on this form with php [1]. Only positioning I've tried so far is using tables. Focusing on functionality for now, figure I can just wait til it works to make it look pretty. Haven't really worked to understand CSS since I was in middle school in the late 90s.

[1] http://i.imgur.com/eRbSdbT.png

Shame that demo's take you out of the site.

Despite a wonderful article, I cannot help but notice that it is 2014 and we still need multiple ways of centering a div. :(

...and the one that really works (variable height and width) uses `display: table` :(

Best centering (vert. and hor.) solution ever: .outer { position: relative; } .inner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }

<div class="outer"> <div class="inner"></div> </div>

This way you don't need to know the width or height of inner element...

The critical piece I'm always missing is how to center a div vertically if you don't know its height?

Well, I'd use display:table-cell with vertical-align:middle.

Doesn't work without the parent having a defined height.

I found this a few days ago, I haven't tried it yet but it looks promising. http://snippetrepo.com/snippets/vertical-align-anything-with...

Did he make a typo?


Doesn't work, unless you change `position: relative` to `position: absolute`

Heres's a trick using pseudo elements : http://codepen.io/anon/pen/pIFna

All the problems with HTML and CSS in one title. All hail the "modern GUI development"!

From six years ago, during which it would seem CSS has gotten no better: http://beradrian.files.wordpress.com/2008/01/breakdown.png

There is really not much more to say...

...maybe that the reason for all of this is that the CSS API (box model ..., box properties ...) is too complex and as a result browser implementations tend to f* it up easily.

Is there a framework that allows one to avoid most of CSS and just use js?

Even if there was, if something went wrong you'd just have more shit to sift through.

After IE6, we can just center a div using inline-block, can't we?

The outer element can have display: table-cell and the inner element would have vertical-align: middle and display: inline-block.

One day someone will have to come up with a convincing explanation on why the hell is margin: auto; unable to vertically center an element if the outer element has a defined height.

anyone miss <center> tag? :)

I'm curious, why did they remove the <center> tag? What was wrong with it?

Is this article intentionally ironic with a column of text that isn't centered as the header is?

The irony here is that the content of this post is not centered.

nice list, would be nicer to have a more detailed definition of "modern browsers" , like browser types/versions that support each method.

Noted. Thanks.


will not work?

> This feature has been removed from the Web. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.


It also won't work because <center> controls text alignment and will have no effect on the alignment of a div (it will center its contents, though) (also this isn't entirely true, centering text will also center divs in IE6 and earlier).

The fact that centering a div requires a complete guide is tragicomically sad and a condemnation of our industry.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact