
CSS Absolute Centering - nvk
http://codepen.io/shshaw/full/gEiDt
======
gamegoblin
I have just started doing web programming in the last month after several
years of applications programming.

It feels like to me, and someone please tell me why I'm wrong, that the amount
of hackery that goes into making webpages look the way web designers want them
to is astounding. I google for solutions to various problems and the top rated
comment on StackOverflow says "...there isn't a good way to do this in CSS,
but here is this hack...".

I feel like somewhere in the universal programming ether there exists a
beautiful unification of HTML, CSS, and JS that doesn't rely on any ugly
hackery, and it's just waiting to be found and start a brave new world of web
programming...

~~~
blhack
I'd love to know why just using tables is wrong.

The user gets what they want, the designer gets what they want, and the only
people unhappy are some purists.

why? what about this is wrong?

~~~
ahallock
I would have agreed with you maybe 2-3 years ago from a pragmatic standpoint,
but the most compelling reason now for not using tables for layout is that
they're not compatible with responsive web design. Table cells don't stack and
can't be reconfigured like block-level elements.

You can get away with using "display: table-cell;" and the like inside
components that are independent of responsive requirements, though.

------
crazygringo
Just in case anyone's unaware... it's entirely possible to vertically center
elements of _variable_ height too in pure CSS... it's just "unsemantic",
because it relies on the fact that only table cells have "vertical-
align:middle".

But that's how I center every one of my "modal dialogs" on a site -- the whole
modal dialog is inside a <table> with position:fixed and
top/bottom/left/right:0. Then, just give the <td> a "vertical-align:middle",
and then put your desired visible dialog <div> inside it.

It's annoying to have to wrap something inside of a <table><tr><td> just to
vertically center something, but it sure beats using JavaScript to do it. (You
might be able to do it just with the display:table-cell property too, but it's
been a long time since I checked browser compatibility.)

~~~
rimantas

      > It's annoying to have to wrap something inside of a
      > <table><tr><td> just to vertically center something
    

And you dont have to. Because your container does not have to be a table, and
you don't need cells and rows. Just use display: (table|table-cell). See for
an example: [http://css-tricks.com/centering-in-the-unknown/](http://css-
tricks.com/centering-in-the-unknown/)

It is not OK to use table and friends in you HTML just for styling purposes.
It's totally OK to use display: table* in your CSS, because CSS has no
semantics, its purpose is styling.

~~~
jakobe
Why is it not okay to use tables for styling purposes? Why is it okay to use
multiple nested divs, but not the table/tr/td tags? Are there any practical
reasons, besides the goal of making the markup more 'semantic'? Are there any
screen readers that can't handle table tags? Or do some crawlers choke on
tables?

I keep hearing this dogma, don't use tables for layout, but nobody has ever
explained to me why it is a problem in practice.

~~~
ricardobeat
Being "semantic" (your quotes) is not an abstract concept or dogma. This
discussion has been exhausted as far back as 2005. A more practical
explanation:

HTML is meant to be parsed and interpreted by machines too, with no visual
representation. Tags are meta-data about their content. A 'table' element says
"I contain tabular data", and user agents will make lots of assumptions based
on that. One of the consequences of this is you'll be giving bad data to
search engine bots, that's why it's bad for SEO.

HTML is also meant to be used by non-visual interpreters, like screen readers.
Assistive technology is not only for the legally blind; visual impairment
affects 20-30% of the world's population. We don't see high user %s because
they just most won't bother, it's too hard, sites' HTML is broken, it is
easier to have somebody look it up for you.

Going on a little more over semantics, there are rules for what elements can
contain each other, so that a structure can be inferred based on headings and
hierarchy. By not following the rules you are wreaking havoc on this, and
preventing aforementioned bots and screen readers from providing meaningful
navigation and context for your page.

We were supposed to have a _semantic web_ by now, where every piece of
information was annotated with meaningful meta-data, allowing for context-
aware applications (add this commenter on facebook; where can I buy this
product?; add this event to my calendar). Turns out it's damn hard to get
everyone to use markup correctly, or even agree to common formats.

~~~
andybak
> Being "semantic" (your quotes) is not an abstract concept or dogma. This
> discussion has been exhausted as far back as 2005

No it really wasn't. A small group of people managed to make it orthodoxy and
in the intervening years very few of the supposed benefits have materialised.

In the meantime the same arguments that it is pie-in-the-sky have persisted
and events have supported them.

The argument isn't even internally consistent as in the real world people are
debating one kind of tag soup vs another. If the only way to create a
particular appearance is either using several wrapper divs or a table then
you're splitting hairs.

<div><div><div></div></div></div> vs <table><tr><td></td></tr></table>

Is that a semantic difference worth fighting for?

The real gains in the semantic web have come from small targeted blocks of
metadata and natural language processing. Not waiting around for everyone to
figure out <section> vs <article> correctly.

<clarification> I'm not arguing against the benefits of semantic markup - just
that a lot of the hand-wavey "this is semantic and this isn't" advice that
gets thrown around is either nonsense or adds such a microscopic amount of
semantic information that it's not actually providing any benefit to anyone.
The real test is to list actual benefits for actual user
agents.</clarification>

~~~
ajanuary
Tables have a well(ish) defined semantics that you're breaking. Those
semantics give rise to real practice benefits like navigating via column and
row with screen readers or hinting how best to split a table up into multiple
pages when printing.

Practically, the way it's ended up, the semantics of a div is "some stuff".
It's evolved into the go-to method to hide a multitude of styling sins. I
don't think there's anything hugely hypocritical in limiting any ugly
semanticless hacks to a single generic container like divs.

Put as much as you can into semantic markup, and then anything else you really
can't fit into that, favour using div soup over breaking the semantics of
another tag.

~~~
Daniel_Newby
What about inline elements inside divs? Even the semantic correctness
crusaders freely resort to abuse of <b> and <i>.

HTML lacks extensibility. If you want to move beyond classical typography you
have to make heinous compromises, and there is no reason <table> should be
specially exempt.

~~~
ajanuary
I agree we have to make compromises because HTML has huge shortcomings. My
point, and the point of a lot of people advocating semantic markup, is that if
you have to resort to hacks, prefer lots of uly generic containers like divs
and spans to misusing things that have better defined semantics that are
actually of use to people, like tables. I can't think of anything you can do
with tables that you can't do with an ugly mess of divs and a little
compromise in cross-browser consistency.

------
jiggy2011
It confuses me that you have to specify things in terms of margins, I
understand how that is technically correct but surely something like
alignment: center should just align to the center of the parent element?

I've spent hours in the past the past getting correct centring behaviour in
CSS, then tried by just putting the whole thing inside <center></center> and
had it work immediately in all browsers. But apparently that's "cheating".

~~~
null_ptr
Cheating according to who? Surely not your website's users?

It's the standards makers' fault. Needing to center something on either the x
or y axis relative to the parent is as common a scenario as you can get.

~~~
jiggy2011
Well technically the center tag is deprecated so any browser could simply drop
support for it (as they did with <blink> in a future version and break the
site.

------
eagsalazar2
OMG, just use a table! It's not semantic but no one will die and your mom will
still love you, I promise! And if you are using haml/jade/handlebars whatever
it is so insanely easy to create a little mixin or whatever to keep your code
clean.

Articles about how to do this should be summarized like this: "Vertical
centering hard/hacky/messy unless you just put it in a table. So put it in a
table".

(I do realize the article says this).

BTW, regarding the argument about the damage of using tables wrt screen
readers, google themselves used tables to layout very basic buttons on their
landing page until very recently. If you use it sparingly and just for this
purpose, screen readers will do just fine. Now, using tables for other types
of layout can and will break screen readers but a full old-school table-based
layout is a long way from having a single TD to center stuff.

------
mkl
I haven't done any front end web work so I'm confused by this. Can someone
please explain why it is noteworthy? It seems strange to me that something as
simple as centring a box should require special attention. Why aren't such
tasks trivial beginner stuff?

~~~
steveax
Centering content of unknown dimensions (and since the user is ultimately in
control of font size this happens often) vertically is surpringly difficult to
do if you want to support legacy browsers. It's a common pain point. There are
others, but this one is particularly vexing (esp. to newcomers to CSS) because
it seems, at first glance, like it should be easy.

------
jafaku
Can someone paste the code somewhere else please? The linked website is
broken. And yes, I have Javascript enabled. But it's probably using
localStorage (with no graceful degradation), which I won't allow. Is this
becoming a thing? Either you give up your privacy, or you can't surf the web
anymore?

~~~
systemtrigger

      margin: auto;
      position: absolute;
      top: 0; left: 0; bottom: 0; right: 0;
    

The JavaScript console error I see is:

    
    
      Blocked a frame with origin "http://s.codepen.io"
      from accessing a frame with origin "http://codepen.io".
      Protocols, domains, and ports must match.
    

localStorage.keys is null, thus the page does not appear to be using
localStorage.

How is localStorage a significant privacy concern? My understanding is that
websites only have access to the keys stored by that particular domain.

------
unclebucknasty
When CSS reached a certain point, using tables for layout suddenly became
evil. CSS was like some strange measure of your salt as a frontend dev. Very
Emperor's New Clothes type stuff.

But, I can remember trying projects with tableless design at that point, and
absolutely beating my head against a brick wall attempting things in CSS that
required almost zero thought with tables. Then, I'd finally get it right in
one browser only to find that it looked like garbage in another.

It was like having a toolbox with a hammer that I couldn't use, instead being
forced to nail everything with a screwdriver. And it wasn't just that I was
accustomed to tables. They were easier and more natural. When you think about
it, layout is nearly always grid-like.

So, I confess that there were times when I said screw it and reverted to
tables. I'd solve problems that weren't working after hours of trying with CSS
in literally minutes.

And the challenge with CSS is still apparent. Here we are all of these years
later, still trying to do something as simple and frequently necessary as
center things vertically which, BTW, doesn't work in my stock Android browser.

CSS is a bloated, convoluted mess and just too much work for simple things.
That's why I have always found it somewhat draconian that people insisted on
CSS as if it didn't have its own significant issues. If there were a tag that
operated just like tables, but indicated layout or, as I think someone else
suggested, a simple attribute to mark a table as layout vs row/column data,
most of the semantic/SEO problems could be solved.

For that matter, I am not convinced that we should be so bent on having html
pull double duty as the source for semantic data _and_ the source for a
presentation engine's rendering. Maybe a different approach altogether could
be more liberating and efficient on both fronts.

~~~
pedalpete
Though I agree in some respects, I've been a convert of CSS since the
beginning. My reason, floats for wrapping elements depending on screen size.
You can't do that with a table.

~~~
unclebucknasty
> _floats for wrapping elements depending on screen size_

Not sure exactly what you mean here. Are you talking about floating divs to
wrap elements to the next visual "row" for smaller screen sizes, as in
responsive design?

Because I don't find this necessary very often in practice, and certainly not
nearly as often as the tons of other general layout that's required. Not to
mention, of course, that you can still use divs where "needed".

BTW, on a side note, the jury is still out on responsive design for me. Or, at
least as I have frequently seen it practiced today. For instance, many times a
site with sidebars (including nav) will wrap the sidebars on smaller displays
such that content, nav, etc. are all lined up in one vertical column. Not very
appealing or usable IMO.

I really believe that how we treat designing to different formats will change
and this responsive wave will pass. And, while I know there are other reasons
to wrap elements, I do think responsive design is responsible for a good bit
of it.

~~~
Daniel_Newby
People still use floats to make the sidebars stack up on narrow browsers? I
thought they mostly went back to tables years ago.

~~~
unclebucknasty
I think it's still very common. In fact, tableless design is still very much
the mantra from what I see.

But, you're right: tables can be used for the same.

Not something I've done much either way. I just don't think its a nice effect.
Guess it's just a style preference.

------
hayksaakian
Does it seem a bit off to anyone else in chrome?

[http://www.imgur.com/7JA69Ty.png](http://www.imgur.com/7JA69Ty.png)

Or is the browser chrome considered usable real estate.

~~~
systemtrigger
You are correct, it is off by the height of the bar at the bottom of the
window. It uses fixed positioning -- not absolute positioning as was
prescribed in the hack. Also he sets the modal height to 50%. The CSS of the
demo is not the CSS of the write-up.

~~~
enyaboi
This !!!!

You can also do this

position: relative; margin-top: 50%; transform: translateY(-50%);

~~~
systemtrigger
You can, if you don't mind it breaking in IE < 9.

------
X4
Why is such basic css hyped so much? Can someone technically explain it? Is
the ratio of HN folks that need Web 101 greater than the ratio of people who
need Startup advice, including technical and architecture solutions? (Been
doing dev+webdev for >13y)

~~~
cbr
This article isn't basic css, it's a discovery of a simpler way to do a
somewhat common layout task.

But overall your point is fair: HN has a lot of people (including me) with
weak front-end skills.

~~~
Rumudiez
It's not a new discovery. I've been using this for over a year...

------
lectrick
The fact that something so simple needs to be explained as "a thing" or "a
trick", many years after HTML5 even came out, feels like a disgusting frontend
failure.

------
DigitalSea
Pretty nifty trick, but I think undoubtedly the best is the transform 2D
method detailed in this CSS-Tricks article: [http://css-tricks.com/centering-
percentage-widthheight-eleme...](http://css-tricks.com/centering-percentage-
widthheight-elements/) — You don't need to know the height or the width, and
the great thing is transform2d's are supported in most browsers that matter.
If you're smart and have dropped IE8 support, then all browsers are mostly
covered and is definitely a lot nicer/neater than needing a height/width or
using display:table and display:table-cell hacks.

If IE8 and down matters, then there are polyfills available for this
functionality.

------
spleeder
I have written about a much better (IMHO) solution that does not need the
height be declared and does not use tables.

[https://news.ycombinator.com/item?id=6193203](https://news.ycombinator.com/item?id=6193203)

------
the_cat_kittles
Very nice. When I actually stop to think about it, it's amazing to me that
this is not immediately easy to do. Things like this give credence to Bret
Victor's most recent talk.

------
candl
HTML/CSS is generally quite flexible when it comes to operations on text. No
surprise since it was its intended purpose to be a format for documents.

Making any layouts and god forbid centering elements has always been a
headache for me. Even by looking at the CSS examples provided by the link my
first thought is how random they all seem and how ugly they are not to mention
difficult to remember and use. There should be a single way to center an
element. It should be an obvious operation given how important and common it
is.

Some very useful CSS properties might take a lot of code and be hard to
implement in native GUI toolkits like floats, overflow, height/width with
percents, text wrapping etc. This is a sweet spot where HTML/CSS shines.

I have been playing with QML lately and decided to implement the Dialog
(Absolute center within viewport) that pops after visiting the linked page
just for comparison:

Here's the dialog equivalent that just fills the entire screen of an
application done with QtQuick 2.0 for Desktop.

[http://pastebin.com/mnN3Zr6N](http://pastebin.com/mnN3Zr6N)

Layouting is easily done by anchors. Filling a rectangle to match a parent's
container, centering an element inside a parent, etc. Other containers such as
Rows, Columns or Grids are also provided. Property bindings are used for
centering the dialog even if the viewport changes. Text wrapping is also done
explicitly and binding was necessary to limit text width to the ScrollView for
it to work.

One big difference compared to CSS is that by looking at the source I can see
at glance what the layout structure is and what might be happening with the
element.

Another cool thing about QML is that it's as simple as taking the code,
creating a new file 'Dialog.qml', adding a few properties, a signal and some
functions and we get a reusable standalone component:

[http://pastebin.com/CSbxrnK3](http://pastebin.com/CSbxrnK3)

that is very convinient to use:

[http://pastebin.com/XKnhW4wN](http://pastebin.com/XKnhW4wN)

result:
[http://i.minus.com/iGTQhAxP55bBP.gif](http://i.minus.com/iGTQhAxP55bBP.gif)
(3MB gif)

~~~
ricardobeat
How is that better than CSS?

[http://jsbin.com/ezocec/1/edit](http://jsbin.com/ezocec/1/edit) (25 lines
counting the HTML)

CSS has columns and grids, custom text wrapping. These features are available
now in >90% of browsers. The `.dialog` class can be used as component without
any changes, and we have things like component.io and browserify to package
them up with behaviour.

result: [http://cl.ly/2w1o3h0i1t0r](http://cl.ly/2w1o3h0i1t0r)

~~~
candl
Sure, at this point HTML/CSS has grown to accomodate many features. But
there's a lot of ugly and non-obvious cruft that has been inherited over the
ages and it won't change soon.

Perhaps a tool can bundle resources, but in the end it's still going to be
inserted into the DOM and can potentially clash with other code since
everything lives in a global namespace. There's also the problem of competing
tools and the dilemma of which one to choose. Any other additional library
that is meant to augment/fix HTML/CSS is another dependency that can cause
problems and needs to be maintained.

QML is meant to be extensive. Not happy with how the drop shadow works? Write
your own shader that does it the way you want it. Feeling that there's some
primitive like an Ellipse missing? You can write your own in C++ and expose it
to QML easily. In fact you can expose any native code to QML.

With HTML/CSS you are constrained to the environment it works in.

QML supports components, animations, transitions, particles, states, bindings,
i18n and much more. It's also very smooth, qml is hardware accelerated. In the
case of CSS so you get some hardware acceleration only for animating
properties like translation, etc.

Here's the dialog I posted before which I changed to support states and
transitions and also added an inline shader and particle emitter:

[http://pastebin.com/hh7xARTS](http://pastebin.com/hh7xARTS)

[http://i.minus.com/iATg82IRCaMa9.gif](http://i.minus.com/iATg82IRCaMa9.gif)
(result 4MB gif)

As it can be seen it's highly declarative and it basically contains no
javascript logic at all besides setting the states.

Of course a lot of such features are available indirectly in HTML/CSS by
piggybacking on third party libraries/frameworks, but wouldn't HTML be so much
nicer if it were designed with those things in mind from the very beginning?

~~~
ricardobeat
Now you're pushing it, but it's getting there :)

Shadow DOM is the specification that will fix the collision/cascading issue,
making it possible to isolate components. You can now write your own shaders,
use custom masks/clipping etc, and of course, SVG for unlimited vector shapes.
If that's not enough, write your own graphics layer with WebGL or Canvas.

[http://jsbin.com/ezocec/3/edit](http://jsbin.com/ezocec/3/edit)

[http://cl.ly/1q1b0T0n0l0u](http://cl.ly/1q1b0T0n0l0u)

Now around ~80% less code.

This is a fun but pointless showdown of course, these are technologies born
worlds apart, with different audiences, purposes and constraints. HTML
appeared in 1990, with the sole purpose of marking up hypertext, grew
organically and has a hundred other interoperability concerns; QML showed up
in 2009 (?), twenty years later, and was designed to solve specific problems.
I'm certain the web wouldn't have grown as fast if it didn't have a stack as
accessible as html/css.

------
mcgwiz
This is interesting but I don't like it. It's a quirky non-idiomatic hack.
Using vertical-align/line-height/inline-block is equally-effective and IMHO
conceptual and readable/self-documenting.

Details: [http://jsfiddle.net/uy64k/6/](http://jsfiddle.net/uy64k/6/)

This requires no extra markup, but it does require the font-size and line-
height to be reset.

------
msujaws
We use this same technique in Firefox to center images when viewing them
standalone, inspect [http://www.elizabethtownfamily.com/wp-
content/uploads/2012/0...](http://www.elizabethtownfamily.com/wp-
content/uploads/2012/09/African_Elephant_Transparent.png) to see for yourself
:)

------
namuol
Don't forget to sacrifice at least one goat, if you want cross-platform,
standards-compliant code.

------
lwhi
I came up with a similar solution a while back [1]

[1] [http://stackoverflow.com/questions/5009864/using-all-four-
po...](http://stackoverflow.com/questions/5009864/using-all-four-positioning-
parameters-with-positionabsolute-is-this-acceptabl)

------
pbreit
Vertically centering dialog boxes in a window is a minor pet peeve of mine.
Boxes should be slightly above center.

If I recall correctly, the original Mac UI guidelines specified that the
midpoint of the box should be 1/3 the distance from the top.

------
ghostdiver
What is performance loss/gain compared to Javascript solution of this problem?

~~~
ashray
There's an infinite performance gain for browsers that have javascript turned
off or use noscript.

Other than that, I'd say that doing this kind of stuff in CSS would by default
be much faster in a web page context.

~~~
ghostdiver
What if I don't want fixed dimensions? Maybe media queries could help a bit,
but Javascript usage seems to be inevitable.

ps. I didn't mean pure javascript solution anyway:)

~~~
erichurkman
If you don't care about older browsers [1], you can use Flexbox to do all
sorts of dynamic, fluid positioning.

[1] [http://caniuse.com/flexbox](http://caniuse.com/flexbox) \- it's in the
current version of all browsers (some still prefixed).

------
marcolz
Those CSS class names are unacceptable. (:grin:)

------
stesch
Doesn't work with NoScript. Bad example.

~~~
cbr
Huh? This solution doesn't use any javascript.

~~~
dredmorbius
Regardless, with ScriptSafe (Chrome) enabled, all I see is a blank page.

I've got to enable assets. and s.codepen.io to see the page rendered.

That appears to be due to the use of an iframe from s.codepen.io for the
content.

------
hpaavola
It's a shame that we need to hack layouts to work with language designed for
changing fonts and colors.

------
oakaz
It's still impossible if you'd like to center a div that resizes itself
depending on the content.

~~~
emn13
nope, consider:
[http://codepen.io/KatieK2/pen/ucwgi](http://codepen.io/KatieK2/pen/ucwgi) or
[http://jsbin.com/uqutol/3/edit](http://jsbin.com/uqutol/3/edit)

These have intrinsically sized (autosized) boxes that vertically and
horizontally center in some container.

------
BigBalli
not sure how people who "know CSS" can work without knowing this...

~~~
izolate
There are other ways to center elems, and once you learn another such way (and
it consistently works for you), is there any point in researching
alternatives?

------
marizmelo
There is anything new here ?

------
ForFreedom
Why do you need this to center a box in css? It can be done without this too.

------
ilovecookies
How is this related to hacking now again?

------
blogtechjav
this is good

