Vertical centering isn't that useful when you already have to know the height of things... I mean, if you already know the heights, you can just put the numbers in straight.
The best way to do real vertical-centering that works with variable heights, and doesn't use JavaScript, is to take advantage of the fact that table cells do this with "vertical-align: middle". Inexplicably, only table cells allow true vertical centering with variable heights.
So you can either convert the surrounding element to a big ole <table><tr><td></td></tr></table>, or you can use CSS to give it a property of display: table-cell. And in both cases, give it a "vertical-align: middle". Then you're good to go!
And of course, horizontal positioning in the table cell is easy.
But I can't figure out, for the life of me, why the bizarre ".container:before" declaration is needed -- it would seem to be entirely superfluous, but if you remove it, the whole thing breaks. Can you explain what's going on?
That's not true necessarily: what if you're trying to vertically align something of a known height on something WITHOUT a known height. The thing with the unknown height is responsive, while the overlay is not. That's what I was just doing, found this, fixed my problem!
That kinda ruined all the excitement for me :(
Good of the OP to include all of the alternative techniques that might be better for cross-browser or other specific situations.
Seems like transforms are better than the original main suggestion though... why not stick with those?
The fact that this is an interesting article is a huge indictment of CSS. It was developed for a different, simpler use case, and it's obviously the wrong abstraction at this point. Too bad it's entrenched.
What do you suppose we do about it? Like it or not, people use web browsers to access the Internet, and as long as web browsers render HTML and CSS, we have to use the tools we have.
My complaint is that a lot of people like CSS/HTML/JS. Because they have learned it and gotten comfortable with it. They don't know/understand anything else and their identity and sense of self-worth is challenged if you speak ill of these technologies. That's a big problem.
Pragmatically: I suppose that we embrace CSS/HTML/JS as object code. And I mean this in a much more dramatic way than CoffeeScript or SASS. This is finally starting to happen, thanks to browser support for things like source-maps. This is one reason I contribute to ClojureScript!
Idealistically: We should be pushing for lower level platforms for code distribution and execution, as well as host platform integration. Portable Native Client and similar efforts shouldn't be so controversial.
There have been attempts to fix this by creating languages which compile to each of those: HAML for HTML, CoffeeScript/Dart for JS, SASS/LESS for CSS. The language benefits tend to be fairly obvious, but there hasn't been much of anything in the way of native browser adoption that I've seen yet, apart from Google's plans for Chrome & Dart.
Now, I haven't used SASS/LESS that much, so feel free to correct me, but it seems like they're solving a different problem. They keep your code DRYer, add nice things like mixins, etc.
However, they don't abstract over tasks like layout--you're still stuck with hacky CSS tricks and semantics.
yet, despite this the web seems to be doing just fine, apps are powerful, often better than native and nobody (else) seems to be complaining that much. Sure, some things take actual skill to implement. We live in an imperfect world, and while it's always easy to blame the tools, it's far better to just get on with improving things and making the best of what we have. It's a far better world today that the setup.exe days.
The entire combined might of the 21st century computing industry has managed to make the dominant application platform provide a tolerably good application experience on a dual-core multi-gigahertz machine.
CSS was originally designed only for inline and block layout in a traditional single column of text with left or right floated figures. It has never had any features specifically designed for full page layout, but people have done lots of hacks to use inline, block, margins, padding, and floats to achieve full-page layouts they were never designed for.
There have been improvements in CSS2 and CSS3, like adding table layout so people could at least use the table layout features on div elements rather than abusing tables for layout, and CSS flexbox that work well for standard UI widget layouts.
But the big fixes to layout have been harder to specify and agree upon. They've been in the works for many years, but it's taken a while to figure out how they really should work, and which parts should be fundamental. It looks like it's getting a lot closer; the CSS Grid Module http://dev.w3.org/csswg/css-grid/ is being treated as the fundamental part of the stack on which others will build, it is being worked on by several browser vendors and is in highly active development, and several browsers have implementations in development. It seems to draw elements from IE's experimental CSS grid, as well as the templates of the earlier template layout proposal.
> But the big fixes to layout have been harder to specify and agree upon. They've been in the works for many years, but it's taken a while to figure out how they really should work, and which parts should be fundamental. It looks like it's getting a lot closer; the CSS Grid Module
Although lower-level and not as modular, flexbox can already be used with great success for a number of layout sections (media objects, vertical centering, input inserts) or full layouts ("holy grail", sticky footers and grids): http://philipwalton.github.io/solved-by-flexbox/
Name another software runtime that even partially works as well cross-platform. Or another runtime that has the notion of multiple competing implementors.
I agree with your frustration about this article being newsworthy (it's 2013! How are we still figuring out vertical centering?!), though I would argue that CSS is great for its original use case and certainly has its place today. Why is it bad that CSS is entrenched in the Web?
Like any development technology, CSS has a learning curve and has several shortcomings (like vertical positioning), but I think it's a fine tool for the job and struggle to come up with something better.
CSS is not great for its original use case. It was poorly designed by a group of people who chose to ignore existing understanding of layout models. The TeX boxes+glue model, had it been adapted for CSS, would have made all the absurdities and nasty layout workarounds of the last 20 years unnecessary.
I like to point to the failure of keeping table headers visible at the top of a page as you scroll down a table. If I had a book where a table spanned multiple pages and the header row wasn't included at the top of the page, I would throw the book out.
A scrollable table with fixed headers is something that Visual Basic supported in 1997.
Of course it wasn't a use case of interest to the mighty browser vendor cabal so it has never been considered a priority. It does seem like it will be possible soon though with position:sticky https://air.mozilla.org/intern-presentation-ford/
We should probably prepare some sacrifice to the browser vendor gods to thank them for this small morsel they have thrown us.
> It was poorly designed by a group of people who chose to ignore existing understanding of layout models.
Can you please elaborate how tables were the understanding of layout models 15 years ago?
The web was not thought to be interactive at that era, but to be printed, it's not the fault of the old specs that the web progressed significantly fast.
I said the web was tought to be printed, all the effort of CSS (circa 98) was about styling the web in a way that made sense for print, not for interaction.
I said nothing about tables. I specifically referred to the TeX boxes+glue model.
In addition, if the web was truly meant to be printed — an assertion I have never heard before; it sounds blatantly false — then not adopting the massively successful TeX system sounds even more insane.
Please read Håkon Wium Lie's PhD thesis http://people.opera.com/howcome/2006/phd/ to understand the reasoning behind the development of CSS. I think it was going in the right direction, although the ride got bumpy when committees and commercial interests started getting involved. Its major objective was to achieve separation of content from presentation which it achieved and I think you being unfair in your statement about CSS not being great for its original use case.
CSS did borrow concepts from TeX at the time. I agree with you that if it had borrowed more from TeX maybe we would have avoided Javascript and also we would have benefited from an updated model for TeX and I said so at http://tex.stackexchange.com/a/6463/963.
> Its major objective was to achieve separation of content from presentation which it achieved and I think you being unfair in your statement about CSS not being great for its original use case.
I have never seen this fully implemented except in the simplest of blog-engine layouts and toy examples. There is always some pollution of the markup, at the very least in the form of the ordering of elements.
A template-based approach would've provided the same semantics a lot sooner than a decade of half-baked CSS hacks.
There's nothing wrong with CSS the language. There are missing properties that could be better implemented, and hopefully future browsers will do so. But CSS is still a fine base to work from.
That said, I use LESS. But while everything compiles down to CSS, it doesn't impact me much.
Fixes are (finally) coming in for layout in CSS in the form of flexbox (http://philipwalton.github.io/solved-by-flexbox/) (and mayhaps grid layout, we'll see. You can create most layouts with flexbox but it's pretty low-level, grid works at a higher level and looks more modular but has seen less implementation so far)
I used to think that as well, until I tried to implement the equivalent of
<div style="padding:5px;margin:5px;">variable text</div>
in an iOS TableView.
It's so frustrating that it still requires all sorts of gymnastics to do something so conceptually simple in CSS, and yet many people seem to see CSS as a self-evident imperative to be used in all cases.
This is the first time in my life going to HN while I'm futzing with a problem has actually helped. Thought I was going to take my mind off - instead I found the answer immediately!
Before the inevitable complaints about CSS start flying in, you really actually hate the Box Model and should direct your anger towards it. To wit, the article itself says:
"Other Techniques
Absolute Centering is a great solution for centering, but there are other methods that may fit more specific needs. The most commonly used or recommended methods are Negative Margins, Transforms, Table-Cell, Inline-Block, and now Flexbox. They are covered more in depth in other articles, so I’ll only cover the basics here."
Pray your support matrix allows you to just stick to Flexbox soon and all of this will start to feel like a bad dream from the bygone past.
First we abused tables, then we abused divs, now there are actual sane hooks for this, it just took 20 years is all.
Next time when I want to explain why HTML/CSS can be a pain, I'll take this example.
"Imagine it's 2013 and there is a website that has been online for years, where the greatest hackers and entrepreneurs exchange exciting ideas. When somebody posted an easy solution how to center something in HTML horizontal AND verical it was the favored post on that site for a day" ... ;)
I personally think it's just incredible that vertical centering in CSS has been so woefully neglected over the 16 years we've had CSS. Every time I read another article about how somebody just maybe has figured out a kludgy way to vertically center things with CSS, I just shake my head. Aren't there any graphic designers on any of the W3C working groups surrounding CSS? Back in the old days when everything was a table-based layout, there was a clean, one-to-one mapping between the grid framework that your graphic designer created and the code underlying the page.
Then the semantic web pedants came along and decreed that tables shall never be used for layout. Fine -- but nobody ever bothered to come up with a DIVs+CSS replacement for the grid-based layout that any serious graphic designer uses to build a page.
And do you know what happened to the web? Debate cause and effect all you want, but webpage designs are far more boring now than they were 10 years ago. Now it's all just blocks of large-print scrollable text, some images here and there (or maybe a wall of them), and a cute logo. It's like everything is a Geocities page with better fonts and color choices, minus the gifs. I feel like I never see anything really cutting edge or creative in the design space on the web.
The internet is a really young medium of course, and it will naturally go through phases, where certain types of design come into fashion while others go out. And I would love it if somebody would prove me wrong by posting some links to some really kick-ass-looking sites. But from where I'm sitting these days, from a design perspective the web is a big yawnfest. Maybe today's websites are more usable and easier to index and work well on a screen reader, but from a graphic design perspective... zzzzz....
I can't wait until the new version of flex box has widespread support and we can stop relying on these dumb hacks to do the most basic layout operations in CSS.
I'm wondering, why does even CSS3 not have a simple way to vertically center text (or even vertically center anything)? It's a pretty basic and wanted thing afaik... Seems like a higher priority than shadows and 3D effects to me.
The history of CSS is one where Microsoft earned an awful lot of bad will and what an epic fail the W3C has been in this regard.
Microsoft of course deviated from the nascent "standard" such that we've been burdened for years with "if IE ..." blocks to the point that the latest version of IE pretends not to be IE.
You reap what you sow.
But every time I come across the issue of "how to vertically center in CSS", an issue that has existed for years, I get angry. I get angry because the old way (vertical alignment on table cells) just works. As much as the CSS purists (some might call them "anti-table zealots"), it's hard to argue with something that works all the way back to IE4 and probably beyond (well valign="middle" probably does, CSS vertical-align: middle is probably IE5/6).
But beyond this there are so many things in HTML/CSS that should be simple but are hard. This is just one of them.
Consider spacing between table cells. There's (still) actually no way to do this... if you want no spacing between the leftmost and rightmost cells and the edge of the table, which I find is a pretty good use case. People end up doing things like:
Any such solutions had varying backwards compatibility issues, a problem we're now largely getting behind us, but still...
Why can't I specify (separately if need be) the vertical and horizontal spacing between cells separately to the edge of the table (which should really be a property of the table rather than the cells IMHO).
The problem here is that the CSS WG seems to have started with a model and then just run with it without running it through very common use cases.
Looking at the article, it looks fine. One thing I'll say is it starts off with the "margin: 0 auto" trick, which everyone who does anything with CSS needs to know. Why is centering that hard? Why can't I just say "put this in the center"? Why can't I then use margins to offset from center or something?
Also FWIW, the margin: 0 auto thing didn't work in older versions of IE if you didn't specify a DOCTYPE and force "standards compatibility mode" (rather than the euphemistic "backwards compatibility mode".
Good grief, if the element to be centered has a fixed height and width, then there's nothing to this. I've been using the negative margin method for years:
Front-end stuff always seems to make the front page of Hacker News. I think it's because front-end is easier, and possibly more "hip" right now (as far as jobs go), so there's more interest in it.
I'm a full-stack engineer that started out on the front end. I don't think frontend is easier - in terms of the amount of background you need to know to produce something useful, being a frontend engineer is significantly harder than being a backend one. However, frontend stuff demoes better. If you do a fancy machine-learning analysis of some public data set but present it as a command-line app or a table on some bare-bones website, people will be like "Uh, what's the deal?" If you make things fly around the screen in cool patterns, they'll be like "Woah! I didn't know you could do that!"
A lot of this is also because a frontend engineer's job is to lower the cognitive processing a user has to do, while a backend engineer's job is to come up with useful things to cognitively process. In other words, when a backend engineer comes up with a demo, they make the viewer work to understand it, while when a frontend engineer does the same they make the viewer go "Ooh! Aah!"
Fair enough. This seems like CSS Positioning 201 to me, but I've been dealing with this stuff for a long time now, so my perspective is probably pretty skewed.
I completely agree with your point re: cognitive processing: good CSS communicates intent to the reader, so if this kind of stuff is unclear to people and the Smashing Mag post helps the concept click in readers' minds, then it's a win :)
There are, in-fact, and have been for a while several known ways do do this in CSS 2.1 this just being another with a similar long list of restrictions and context requirements.
I'm curious why there isn't something like TypeScript or Coffeescript for CSS? I'm aware of LESS and SASS but to my knowledge they don't go as far as their JavaScript complements in adding future-looking functionality. Is it simply not possible to add CSS grid or flexbox (or both!) support to LESS and have it compile down to plain ol' CSS?
Not sure what you mean by "future-looking functionality". I don't know anything about TypeScript but CoffeeScript is just an opinionated way to generate JavaScript. Isn't that what both LESS and SASS do for CSS? Regarding grid or flexbox, that is ultimately a design decision/preference of the architect.
So using your example, if SASS inherently used grid that would be like CoffeeScript introducing MVC into your project.
TypeScript adds some features planned for Javascript such as classes with inheritance and modules. The thinking is that when these features become standardized your TypeScript code will be valid Javascript. (Or at least as far as those features are concerned.) So in the same vein, why doesn't SASS provide the next generation of CSS functionality? That is, you use the proposed syntax for CSS grids and it transforms that into whatever mess is necessary to emulate it in today's CSS. Later when CSS grid support is available no translation is necessary.
I suppose the answer is because it can't do so in CSS alone and that emulating CSS Grid would require CSS, DOM, and Javascript to be emitted from the compiled SASS script. It would be neat if someone who knew more could confirm my suspicion.
I'm not sure I follow your example regarding CoffeeScript and MVC.
61 comments
[ 2.0 ms ] story [ 116 ms ] threadThe best way to do real vertical-centering that works with variable heights, and doesn't use JavaScript, is to take advantage of the fact that table cells do this with "vertical-align: middle". Inexplicably, only table cells allow true vertical centering with variable heights.
So you can either convert the surrounding element to a big ole <table><tr><td></td></tr></table>, or you can use CSS to give it a property of display: table-cell. And in both cases, give it a "vertical-align: middle". Then you're good to go!
And of course, horizontal positioning in the table cell is easy.
See https://twitter.com/giuseppegurgone/status/38820349236545126...
But I can't figure out, for the life of me, why the bizarre ".container:before" declaration is needed -- it would seem to be entirely superfluous, but if you remove it, the whole thing breaks. Can you explain what's going on?
The pseudo-element (in red) is 100% tall and both .container:before and content are inline-block with vertical-align: middle;
That kinda ruined all the excitement for me :( Good of the OP to include all of the alternative techniques that might be better for cross-browser or other specific situations.
Seems like transforms are better than the original main suggestion though... why not stick with those?
Pragmatically: I suppose that we embrace CSS/HTML/JS as object code. And I mean this in a much more dramatic way than CoffeeScript or SASS. This is finally starting to happen, thanks to browser support for things like source-maps. This is one reason I contribute to ClojureScript!
Idealistically: We should be pushing for lower level platforms for code distribution and execution, as well as host platform integration. Portable Native Client and similar efforts shouldn't be so controversial.
However, they don't abstract over tasks like layout--you're still stuck with hacky CSS tricks and semantics.
You're correct, but that hasn't stopped people from trying.
Whoopee.
There have been improvements in CSS2 and CSS3, like adding table layout so people could at least use the table layout features on div elements rather than abusing tables for layout, and CSS flexbox that work well for standard UI widget layouts.
But the big fixes to layout have been harder to specify and agree upon. They've been in the works for many years, but it's taken a while to figure out how they really should work, and which parts should be fundamental. It looks like it's getting a lot closer; the CSS Grid Module http://dev.w3.org/csswg/css-grid/ is being treated as the fundamental part of the stack on which others will build, it is being worked on by several browser vendors and is in highly active development, and several browsers have implementations in development. It seems to draw elements from IE's experimental CSS grid, as well as the templates of the earlier template layout proposal.
So, yeah, for many years CSS has had a big deficiency in specifying page layout. It's going to get better very soon, however, once the CSS Grid Module is finished and implemented. I'd imagine we'll start seeing implementations within a year; here's Webkit's tracking bug for it: https://bugs.webkit.org/showdependencytree.cgi?id=60731&hide... here's Chromium's: https://code.google.com/p/chromium/issues/detail?id=79180 . Mozilla doesn't seem to be working on it yet, though they have had some preliminary discussion: https://bugzilla.mozilla.org/show_bug.cgi?id=616605 . IE had implemented an experimental Grid Layout proposal that the current work is based on, so while the syntax won't be exactly the same, they have most of the underlying functionality working: http://msdn.microsoft.com/en-us/library/ie/hh673533(v=vs.85)...
Although lower-level and not as modular, flexbox can already be used with great success for a number of layout sections (media objects, vertical centering, input inserts) or full layouts ("holy grail", sticky footers and grids): http://philipwalton.github.io/solved-by-flexbox/
Flexbox is a CR, and it's starting to get pretty well supported: http://caniuse.com/#feat=flexbox
I agree with your frustration about this article being newsworthy (it's 2013! How are we still figuring out vertical centering?!), though I would argue that CSS is great for its original use case and certainly has its place today. Why is it bad that CSS is entrenched in the Web?
Like any development technology, CSS has a learning curve and has several shortcomings (like vertical positioning), but I think it's a fine tool for the job and struggle to come up with something better.
A scrollable table with fixed headers is something that Visual Basic supported in 1997.
Of course it wasn't a use case of interest to the mighty browser vendor cabal so it has never been considered a priority. It does seem like it will be possible soon though with position:sticky https://air.mozilla.org/intern-presentation-ford/
We should probably prepare some sacrifice to the browser vendor gods to thank them for this small morsel they have thrown us.
Can you please elaborate how tables were the understanding of layout models 15 years ago?
The web was not thought to be interactive at that era, but to be printed, it's not the fault of the old specs that the web progressed significantly fast.
(1) The "H" in HTML stands for hypertext. (2) When has a web page ever printed well?
I said the web was tought to be printed, all the effort of CSS (circa 98) was about styling the web in a way that made sense for print, not for interaction.
In addition, if the web was truly meant to be printed — an assertion I have never heard before; it sounds blatantly false — then not adopting the massively successful TeX system sounds even more insane.
CSS did borrow concepts from TeX at the time. I agree with you that if it had borrowed more from TeX maybe we would have avoided Javascript and also we would have benefited from an updated model for TeX and I said so at http://tex.stackexchange.com/a/6463/963.
Maybe is time to revisit and revamp both.
I have never seen this fully implemented except in the simplest of blog-engine layouts and toy examples. There is always some pollution of the markup, at the very least in the form of the ordering of elements.
A template-based approach would've provided the same semantics a lot sooner than a decade of half-baked CSS hacks.
That said, I use LESS. But while everything compiles down to CSS, it doesn't impact me much.
CSS makes life much, much easier.
http://codepen.io/shshaw/full/gEiDt
"Other Techniques
Absolute Centering is a great solution for centering, but there are other methods that may fit more specific needs. The most commonly used or recommended methods are Negative Margins, Transforms, Table-Cell, Inline-Block, and now Flexbox. They are covered more in depth in other articles, so I’ll only cover the basics here."
Pray your support matrix allows you to just stick to Flexbox soon and all of this will start to feel like a bad dream from the bygone past.
First we abused tables, then we abused divs, now there are actual sane hooks for this, it just took 20 years is all.
http://philipwalton.github.io/solved-by-flexbox/demos/vertic...
"Imagine it's 2013 and there is a website that has been online for years, where the greatest hackers and entrepreneurs exchange exciting ideas. When somebody posted an easy solution how to center something in HTML horizontal AND verical it was the favored post on that site for a day" ... ;)
Then the semantic web pedants came along and decreed that tables shall never be used for layout. Fine -- but nobody ever bothered to come up with a DIVs+CSS replacement for the grid-based layout that any serious graphic designer uses to build a page.
And do you know what happened to the web? Debate cause and effect all you want, but webpage designs are far more boring now than they were 10 years ago. Now it's all just blocks of large-print scrollable text, some images here and there (or maybe a wall of them), and a cute logo. It's like everything is a Geocities page with better fonts and color choices, minus the gifs. I feel like I never see anything really cutting edge or creative in the design space on the web.
The internet is a really young medium of course, and it will naturally go through phases, where certain types of design come into fashion while others go out. And I would love it if somebody would prove me wrong by posting some links to some really kick-ass-looking sites. But from where I'm sitting these days, from a design perspective the web is a big yawnfest. Maybe today's websites are more usable and easier to index and work well on a screen reader, but from a graphic design perspective... zzzzz....
Microsoft of course deviated from the nascent "standard" such that we've been burdened for years with "if IE ..." blocks to the point that the latest version of IE pretends not to be IE.
You reap what you sow.
But every time I come across the issue of "how to vertically center in CSS", an issue that has existed for years, I get angry. I get angry because the old way (vertical alignment on table cells) just works. As much as the CSS purists (some might call them "anti-table zealots"), it's hard to argue with something that works all the way back to IE4 and probably beyond (well valign="middle" probably does, CSS vertical-align: middle is probably IE5/6).
But beyond this there are so many things in HTML/CSS that should be simple but are hard. This is just one of them.
Consider spacing between table cells. There's (still) actually no way to do this... if you want no spacing between the leftmost and rightmost cells and the edge of the table, which I find is a pretty good use case. People end up doing things like:
Any such solutions had varying backwards compatibility issues, a problem we're now largely getting behind us, but still...Why can't I specify (separately if need be) the vertical and horizontal spacing between cells separately to the edge of the table (which should really be a property of the table rather than the cells IMHO).
The problem here is that the CSS WG seems to have started with a model and then just run with it without running it through very common use cases.
Looking at the article, it looks fine. One thing I'll say is it starts off with the "margin: 0 auto" trick, which everyone who does anything with CSS needs to know. Why is centering that hard? Why can't I just say "put this in the center"? Why can't I then use margins to offset from center or something?
Also FWIW, the margin: 0 auto thing didn't work in older versions of IE if you didn't specify a DOCTYPE and force "standards compatibility mode" (rather than the euphemistic "backwards compatibility mode".
http://jsfiddle.net/mBBJM/2155/
Not that it's any less Stockholm-Syndrome-y than the linked article's solution, but still, I have no clue why this is on the front page of HN.
A lot of this is also because a frontend engineer's job is to lower the cognitive processing a user has to do, while a backend engineer's job is to come up with useful things to cognitively process. In other words, when a backend engineer comes up with a demo, they make the viewer work to understand it, while when a frontend engineer does the same they make the viewer go "Ooh! Aah!"
I completely agree with your point re: cognitive processing: good CSS communicates intent to the reader, so if this kind of stuff is unclear to people and the Smashing Mag post helps the concept click in readers' minds, then it's a win :)
http://css-tricks.com/centering-in-the-unknown/
They're all much of a muchness, at least we'll be able to just use flexbox soon enough.
So using your example, if SASS inherently used grid that would be like CoffeeScript introducing MVC into your project.
I suppose the answer is because it can't do so in CSS alone and that emulating CSS Grid would require CSS, DOM, and Javascript to be emitted from the compiled SASS script. It would be neat if someone who knew more could confirm my suspicion.
I'm not sure I follow your example regarding CoffeeScript and MVC.