The complete guide to centering a div
tipue.com
tipue.com
...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?
It's unbelievable just how annoying CSS can be for seemingly simple things.
So I think I'm agreeing with you.
Where I work at the moment I'm required to comply with WCAG2 AA at a minimum.
I just hate the part where they act like CSS is a good alternative in practice.
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.
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.
<html>
<head>
<title>Testing making a footer with CSS</title>
</head>
<body>
<div id="divpage">
<div id="divcontent" style="overflow: auto; height: 60%;">
This is the content area.
</div>
<div id="divfooter" style="overflow: auto; height: 30%;">
This is the footer.
</div>
</div>
</body>
</html>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.
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.
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.
[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.
- 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.
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.
> 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.
I don't see the GP comment saying that, what are you respondng to?
Does anyone have an alternative to CSS that tries to take on a problem this big?
(not trying to make the case for CSS being good)
http://inspectelement.com/wp-content/uploads/2013/03/Q3cUg29...
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
http://www.fingswotidun.com/gunk/boxtest.swf
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.
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.
#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)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.
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. :)
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.
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 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.
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.
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.
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.
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.
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).
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.
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?
http://www.cs.washington.edu/research/constraints/web/ccss-u...
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)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.
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.
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
box-sizing
> 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.
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.
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.
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.
Flex box fixes this. The only reason not to use it is old browsers.
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
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.
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).
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
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.
Here's the Codepen that shows it with a larger outer div,
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 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!
Well, there you go. :-)
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.
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.
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.
also doesn't require a fixed width http://codepen.io/anon/pen/vsliJ
<table>
<tr>
<td> my div </td>
</tr>
</table>
you can do <div style="display: table;">
<div style="display: table-cell;
vertical-align: middle;"> my div </div>
</div>
The inline styling is just for illustrative purposes, of course.On the other hand support for centering vertically with auto isn't/wasn't widely supported either.
[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
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".
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.
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.
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.
http://philipwalton.github.io/solved-by-flexbox/demos/vertic...
- 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.
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.
center { text-align: left }<vertical-center>Hello!</vertical-center>
.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/
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.
<div class="outer"> <div class="inner"></div> </div>
This way you don't need to know the width or height of inner element...
http://codepen.io/cheapsteak/pen/axJit
Doesn't work, unless you change `position: relative` to `position: absolute`
...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.
The outer element can have display: table-cell and the inner element would have vertical-align: middle and display: inline-block.
<center>
will not work?https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ce...