Hacker News new | past | comments | ask | show | jobs | submit login
How to Center in CSS (howtocenterincss.com)
1036 points by plurby on April 19, 2015 | hide | past | favorite | 289 comments

The mere fact that a site like this can exist and not be a joke is proof that CSS is still badly broken. I should be able to center things by writing:

    foo {
      align: center;
      valign: center;

You're in luck.

    foo {
        display: flex; /* opt into the new box model */ 
        justify-content: center; /* "align" */
        align-items: center; /* "valign" */
Vendor prefixes may or may not ruin your day (for now), but the spec is there and is exactly what you want. CSS is no longer "badly broken" if that's your metric.

Sweet. I figure only 15 more years until we get two column layouts working, and then we'll finally be able to publish like it's 1979.

CSS multicolumn layout is four years old. It's implemented in all the major browser engines, and many popular sites like Wikipedia use it. http://www.w3.org/TR/css3-multicol/

Only partially. You usually have to use browser prefixes to get it to function. http://caniuse.com/#feat=multicolumn

Add Autoprefoxer in your build process and never type them again.

That is not CSS anymore, it's "CSS + autoprefixer". Which, I agree, is great, but it's worth mentioning. Vanilla CSS requires the prefixes, "CSS + autoprefixer" doesn't, but it requires other things like an extra build step (and a build process, at all). Worse, it could be mutually exclusive with other tools.

When you advocate an add-on to an existing solution, you're changing the solution. It's like people who recommend typescript in reply to JS's lack of types, or Coffeescript to its ugly syntax: you can't have both, they change the original thing. Or vimperator with firefox, or vim-mode emacs, or... it's all not the same thing anymore. You push the carpet down in one place, it comes up in another.

CSS still requires the vendor prefixes. If autoprefixer is the perfect solution to that, let's stop people everywhere from using vanilla CSS and switch them over to "CSS + autoprefixer". Turns out it's not that easy, which gives the original "but it requires prefixes" argument more meat.

Or use Bourbon mixins (http://bourbon.io/docs/) if you use SASS.

SASS mixins are great, but Autoprefixer is better for prefixes: it looks the same as writing actual CSS (just with no prefixes) and has no cognitive overhead during editing. Compare the Bourbon mixin:

    @include background(linear-gradient(red, green) left repeat);
to autoprefixer:

    background: linear-gradient(red, green) left repeat;

AAAAaaand we're back to 7 solutions to a simple problem

How so? Autoprefixer allows you to just write spec CSS and let it worry about prefixes.

That's not a solution; that's a workaround.

Like I said, "working". I don't want two columns stretching ten feet long. I want two columns on this page, two on the next, two on the one after that...

That is indeed how multicol works when combined with pagination [1].

[1]: http://dev.w3.org/csswg/css-multicol-1/#pagination-and-overf...

I'm pretty sure flexbox can solve two column layouts very well, just not with one continuous piece of text.

It would seem there is less than 92% support for flexbox yet.

Better go back to print, then.

So fall back to display: table for the garbage browsers. This is not difficult stuff.

Hm, had you said 1978, I would have gotten the reference (Spoiler: TeX, though maybe not really 2-column at the time?). Did you have something specific in mind when writing 1979?

"Did you have something specific in mind when writing 1979?"

Probably the Prince song "1999" (party like it's 1999...) combined with the general era in which this stuff was figured out in non-web digital contexts.

1984 with the introduction of the Macintosh, would be a better year to have picked, as it could be considered the beginning of the desktop publishing revolution.

Unfortunately, though flexbox is nice and a welcome addition, it's not the panacea people make it out to be having used it a fair bit in the past - the details of how it plays with the rest of the layout and the various options are complicated (see http://www.w3.org/TR/css-flexbox-1/ if you don't believe me), and sometimes the interactions are confusing.

I still think there's scope for a language that compiles to CSS but allows totally intuitive positioning, provides error messages if you make a mistake and generally isn't as infuriating as CSS is. The amount of times I've done something which seemed like it really ought to do what I want and the layout doesn't change is unbelievable. Even assuming vertical alignment is totally solved by flexbox it's still an agonisingly painful thing to work with.

Maybe this can clear some things up: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

I've been doing flexbox heavily for nearly the past year, and that post is my go-to reference, because I still can't remember all the properties and values. Highly recommended.

It's legitimate for people to point out that these fixes are not universally available, because many people still need to support old versions of IE.

That said, I think it's important for people to understand that many of the problems that people have canonically associated with the web's incompetence have been "solved" in standards for a number of years. There's a real difference between problems that remain unsolved in all browsers and problems that do not remain in the current versions of all browsers.

That difference may seem moot until the features are universally rolled out, but understanding that a solution to centering content rolled out in all major browsers (including Internet Explorer) three years ago may help us get past a sense of learned helplessness about the web.

Yes, improving the platform takes time, but by making browser vendors aware of the problems we face as web developers, things do get better.

The problem is that it doesn't matter only to IE, but to every version of a specific browser.

Nowadays people are not only using desktop computers. Many of the computer form factors used nowadays almost never update, yet one needs to support them.

EDIT: Typo version => browser.

This is a big step in the right direction, but I'm afraid it's still broken. Centering things in this way breaks the <BR> tag. It works inside text but now fails between elements. For example:

renders correctly as

foo bar

but <span>foo</span><br><span>bar</span> renders as foobar.

And AFAICT it doesn't work at all in Safari even with vendor prefixes.

The <br> tag is defined as a tag that inserts a newline with generated content using pre-formatted whitespace. It only works between blocks because of anonymous block element generation. I'm glad that the flexbox spec didn't require some sort of anonymous block element generation; it's really complex as it is and adding anonymous blocks to flexbox would have been hideously complicated.

It's just too bad you have to add comments to understand what "justify-content: center" means. I mean, I guess it was too much trouble just to give it the semantically correct names.

Seems semantic to me. What would you suggest instead?

align: center; valign: center;

But what are you aligning? It seems to me that having "justify-content" is more semantic than "align".

Flexbox is nice and makes some things easier, but its still (IMHO) a half assed solution compared to something like QML's anchors.

In QML I can center like this:

    anchors.centerIn: parent
(replace parent with id of item you want to center in if not the parent item). You can also do just vertical or horizontal centering, or you can fill another item or you can anchor eg the left of your item the the right of another item and the right of your item someplace else and it resizes/repositions your item as required.

Flexbox still often requires lots of nesting to achieve what should be (and is in QML) relatively simple layouts. I've also hit a few things that I couldn't do at all with Flexbox (although that could just be lack of CSS/flexbox skill on my part - but to that I say that CSS gets very hard quite fast, while complex layouts in QML are pretty easy).

That is why CSS Grids are coming: http://dev.w3.org/csswg/css-grid/

Like flexbox, this looks like a definite improvement over what we have now, but it looks quite complicated with less than ideal syntax. I imagine that's mostly to do with playing well with existing CSS (syntax and semantics) but its rather unfortunate. I looked at a bunch of the examples and found them quite difficult to figure out, but when I started with QML, I saw one snippet of sample code and immediately was able to create complex layouts myself.

Don't get me wrong, I'm glad CSS is getting better and will look forward to the day when I can use this (but lets be realistic, it'll be a while yet before enough browsers support this to be usable), but I can't help but feel that its cruft built on top of cruft and that it won't ever be as slick and simple as something like QML.

Are they really coming? I only see it in IE.

I would love a flexible anchoring system like QML for CSS.

Flexbox has made our life much better. But we still run into a bunch of implementation bugs, meaning that it will take a few more years for the promise to become reality: https://github.com/philipwalton/flexbugs

i use this waty to solve my center problem,truly it works,but it lead other problems,like this:<div>test test <span>test test</span>test test <span>test test</span></div> the flex will ruin the layout of the div,so how can i solve this problem?thank you

Spans are stripped out by Outlook 2010 in HTML mail. This is not edge case, as you may think. Most corporates are still on Outlook 2010 (and IE 6, especially large banks in the UK).

Outlook 2007+ use MS Word as email layout engine, instead of Trident (Internet Explorer). MS Word "web view" is based on Frontpage (which itself forked of trident) and produces broken HTML 4 output.

The HTML email world is stuck with HTML 4.1, inline CSS and many corner cases (worse than the IE6 era!).

> The HTML email world is stuck with HTML 4.1, inline CSS and many corner cases (worse than the IE6 era!).

It might be for the better, actually. HTML5 and CSS3 are Turing-complete[0] so I can imagine that the moment they would be allowed, some clever marketing company would figure out new and impressive ways to use the new features to scam people. Er. I meant, "provide value-added content".

[0] - with user closing the loop, see http://beza1e1.tuxen.de/articles/accidentally_turing_complet... for links to an example.

Even if the user didn't have to click on each box, that's not even close to turing complete in the problematic sense. It requires a new line of html for every cycle. O(n).

You can do worse with less.

It doesn't belong on that page.

(Hint: basic arithmetic is turing complete if you give it the same affordances)

First, thank you for the information. It is still very much an edge-case, though. Most HTML ist published on the web, not in emails and most emails are plain text. A few have very simple formatting in HTML. Very few actually have a complex layout, and how many of those could possibly benefit for vertical alignment? And that tiny fraction, if viewed in Outlook 2010 will display - well - not centered.

Sorry for my late reply. HTML email is separate media and separate (very large) business. Cost per lead acquired by using HTML mail is high. So is its market value. So any tool that makes life of HTML mail designer easier will be very much appreciated. Look at litmus.com business.

And if you use something like Compass, the prefix stuff is taken care of for you http://compass-style.org/reference/compass/css3/flexbox/

Funny, because you say he's in luck and yet, that isn't at all what he wrote. At all.

The only differences are that you have to opt into the new box model (required, because "justify-content" and "align-items" are incompatible with the old box model) and the names are different (which is a good thing, because one of the important features of flexbox is that you can switch from vertical to horizontal layout very easily).

I think I'd still CSS is badly broken, until this is available everywhere.

Every 4 years: "lets check if latest css can center dynamic sized things without a bunch of #container_of_container cruft". Just stick with:

<table height=100% width=100%><td valign=center align=center>

And what the hell does "margin: auto" mean? I'd like to hear some print designers using that in normal conversation. "oh and also i'd like these margin's auto'ed".

At this rate the table tag is going live longer than the copyright on mickey mouse.

> And what the hell does "margin: auto" mean?

It means "calculate the margins automatically according to available space". Nothing complicated about that.

Print is quite different from web. The most noticeable difference is that paper cannot be resized, nor does it adapt it's content when you rotate it.

Comparisons to print designers misses the biggest point about web design, that is that we have no way to guarantee a width, a position or even choice of font. Print designers know an A4 page is always 210x297mm, web designers have no idea what to expect.

By the same dint, web designers don't talk about paper weights and finishes. It's crackers, almost as if the two sets of designers are using different technologies.

But if you are still using the table tag for anything but tabular data, you're living in the 1900s and arent cut out as a modern day web designer /snark

Your example does not align vertically, so I am not sure what you are trying to prove. This CSS will put something in the center of your screen quite easily

    position: absolute; top: 50%; left: 50%; 
Is that so hard? Having poor CSS skills is not the same as CSS being broken.

Unfortunately, that's telling your div to start halfway. Following your suggestion leaves me with an element with its top left corner in the exact center of the containing div.

I'm not a fan of CSS due to issues like this. It falls in the same line as issues where, for example, paddings and margins (and borders) are added to the size of your div rather than subtracted. There's a solution for that that makes sense nowadays but by the time that came about, I'd already stopped liking CSS.

I also find it crazy how there was a huge campaign to remove use of the table tag for layout. 'It's non semantic! You're mixing layout and content!' people would cry over and over.

.. But then we've ended up with bootstrap and it's grid layout, where we're doing exactly that, and for some reason it's perfectly fine.

The problem with tables for layout is that the layout algorithm is incredibly complex. People seem to think it's simple, because it kinda does the "right thing" in many cases, but it's actually ill-defined, varies between browsers, and has only a work-in-progress spec [1]. Width calculation is defined in terms of linear interpolation between the closest of four "candidate guesses" which bound the available width. And that's the simple case, when no colspans are involved; check the WIP spec for details on the recurring sequence that is involved when there are column spans…

Regardless of how you feel about CSS 2.1, it's indisputably better than the table-based layout we had before. Speaking as someone who has implemented both table-based layout and CSS 2.1, it's really unfortunate to see people want to return to the bad old world.

[1]: http://dbaron.org/css/intrinsic/

A basic rule of universe is that complexity remains, you can merely shift it around. The table layout algorithm might be incredibly complex, but I'd rather have a browser writer have the headaches than me.

> The table layout algorithm might be incredibly complex, but I'd rather have a browser writer have the headaches than me.

Completely disagree. The Unix philosophy is right when it comes to layout: you want to be simple, fast, and predictable.

This attitude is also why we are in a situation where the Web is slow compared to native platforms. Simple things tend to be fast things. Complex things tend to be slow things.

And the things you do to properly align stuff in CSS are anything but simple. You took the complexity from the place where it could be well-defined and heavily optimized and have it to the hands of every developer to do it in their own, broken way.

I fail to see how centering something in flexbox is complex. It's literally one property once you've switched to the new mode. And absolute centering is really simple once you understand how containing blocks work.

Your implications that table layout can be "well defined" or "heavily optimized" are both false. The problem is that table layout is ill-defined: it's really a pile of hacks upon hacks that were invented at Netscape a long time ago and still not standardized or consistent between browsers. And, speaking as someone who optimizes layout engines for a living, complexity is the #1 enemy of "heavy optimization". Spec complexity is the #1 reason why layout is so slow, because it makes layout engines large, complex, and brittle.

The attitude is the result of a thing that just keeps annoying people. It's certainly not a cause of a slow web.

Given that the problem is not simple, I'm happy to have fast and predictable.

A basic rule of universe is that complexity remains, you can merely shift it around.

You can always increase complexity. For instance, by doing all math in Roman Numerals. Thus, in at least some cases you can decrease it. So your statement doesn't hold.

I think you were referring to something like inherent complexity, but then you would have to somehow prove that all this complexity is inherent.

> A basic rule of universe is that complexity remains, you can merely shift it around.

Not really. CSS grid systems (like in Bootstrap) require some ugly and non-semantic markup, but they're not very complex.

They don't require non-semantic markup -- as I said in a comment that was downvoted for some reason. There's a whole set of best practices that people aren't mentioning in this thread.

If you write your styles in the same preprocessor as the Bootstrap package you chose (Less by default, but optionally Sass), you can mix Bootstraps grid classes into your own semantically meaningful classes, and drop all the col-xs stuff from your markup. Your markup elements can have class names that are purely semenatic. Almost every modern grid system offers preprocessor mixins that can be used in this way.

There are methodologies like BEM that are great for providing a semantically meaningful layer of classes in your markup.

It's true that the complexity remains and is shifted. The important part is that it's no longer interlaced with the complexity that describes the fine-scale structure of the page.

There have been some huge deficiencies in CSS over the years. It is frustrating to have to use complex sets of counterintuitive rules to achieve seemingly simple effects. But there are techniques for helping to manage it in modern web development.

Also, [0], since “All problems in computer science can be solved by another level of indirection, ...”.

[0]: https://www.ostraining.com/blog/coding/bootstrap-right-way/


No, what he really meant by complexity is information content - will always remain - you can compress it (akin to writing complex code) or uncompress it (akin to writing more code), but whatever you wanted to express you'll still have to express. This principle you can also find in all domain specific languages and in all frameworks that started out as easy and lightweight and become groteskly inflexible and ugly monstrosities after a while when the rest is being added to make them complete in all respects.

> because it kinda does the "right thing" in many cases, but it's actually ill-defined, varies between browsers, and has only a work-in-progress spec

Which is completely not like using CSS at all, right?

Like I said, I've implemented both. CSS 2.1 was much easier than tables. Almost everything I implemented in CSS 2.1 made sense (with some notable exceptions, such as the hypothetical box, margin collapse, and border collapse). Tables were nonstop backwards compatibility hacks.

Thank you for saying that. The last 15 years have seen tremendous heat and noise exhausted in fantastical debates the end result of which brings no obvious improvement. If we were honest, we would say something humble, such as "Sir Tim Berners-Lee is a great genius, and we are all grateful for what he gave us in 1989, however, since that time, we have learned many things, and the technologies proposed then did not give us what we actually need. HTML strains to fulfill two discordant goals, one is to give us structured documents, and the other is to give us a GUI for TCP/IP. But we now realize these two goals would be better served by two separate technologies, and HTML should be retired."

> But we now realize these two goals would be better served by two separate technologies, and HTML should be retired."

This. And the confusion around those two goals is what drives a lot of useless arguments with people who have Stockholm syndrome towards HTML and CSS. Those arguments can often be summarized like this:

- Hey, we're complicating things too much, how about just focusing on rendering a text communicating a message?

- No no no, the web is not just about documents, it's so much more now! It's about applications.

- Ok then, so let's drop the nonsense about separation of concerns, that you can have layouts separate from content.

- No no no, HTML is for describing documents, and CSS is for describing its layout!

The objection to tables for layout was never on the basis of grid layouts being bad, it was on the basis of separation of concerns.

The primary problem with layout tables was that they involved tightly coupled inlining of your layout rules.

I have not found a project yet that I could divorce the layout from the content without the use of javascript. i gave css many attempts at this. mainly from the desire to make the content easy to manage for others. or just for aesthetics. but css was (is) too clunky to make that separation. yet people still argue that not limiting yourself to what css can provide you, thereby giving up on the purity of content vs layout separation debate, is somehow blind use of web standards. i've since assumed css's goal was lofty from the start.

Have you seen some of the amazing things that can be done even in css 2.1?

Honestly sure you need js for most interactions and animations still, but layout? I wouldn't merge any pr that uses js for layout. Including fully responsive layouts.

I'd agree it's not completely divorced, but it's much, much better than it used to be. If you've worked in environments where the only access you have is CSS (for instance, locked down CMSes, or editing subreddits), you'll find that many solutions are possible without manipulating HTML. CSS can be very powerful; especially with the advanced selectors of CSS3.

I think I'd rather just manipulate HTML with Javascript. At least then I only have one problem, which is HTML with inline styles. No separate CSS file to maintain or CSS rule precedence to worry about.

You forgot the performance problem....

And anyone who wants to browse with JavaScript disabled…

I stopped worrying about those users years ago. Don't even bother with <noscript> anymore. It's 2015 and all browsers support JS these days. If you disable browser features then you really shouldn't be surprised when functionality breaks. The same would happen if you disabled CSS or images.

Funny you should invoke turning off CSS and images -- a lot of people have actually worked pretty hard to make standards that would work for cases where visitors had them disabled, or want low bandwidth options, or had their own custom style sheets, or weren't using a visual user agent (or even, for that matter, directing the user agent manually).

A failure of function availability from turning off images or CSS is a failure of developers, not a failure of the platform or user agent. You can find sites even in 2015 that either straight up work or degrade gracefully when being browsed by Lynx (a browser that I don't think has seen even a dot-release update since 1999) because they were put together by thoughtful professionals who understand the platform.

If you're trying to deliver an application that absolutely requires client side computation or specific browser APIs, you can have a pass for choosing the have your site not work without JS.

If your site really is just a series of documents (either static or dynamically computed), though, there really isn't much of an excuse.

>a lot of people have actually worked pretty hard to make standards that would work for cases where visitors had them disabled, or want low bandwidth options

In cases like this, wouldn't it make more sense to have that information available in an API? Once you've removed all styling and interaction, it seems like something that would work better as simply sending raw data, and letting the client decide what to do with it.

Schema.org is a good example of how this would work with the modern web. Markup relevant data (eg. product ratings, movie times) and let the clients render it as desired. You can still provide CSS/JS for modern browsers.

Seems a lot more elegant to me than designing pages to gracefully fallback when JS/CSS is missing, as that would seriously restrict design.

When you say "simply send raw data, and let the client decide what to do with it," you're more or less describing the original vision behind delivering markup before we got obsessed with instructions of one stripe or another to control visual presentation.

The crucial question is probably what's considered "raw" -- or perhaps to talk more in terms of web-related philosophy, which media type you'd expect most user agents to be able to handle by default... and despite the (reasonable) popularity of JSON, the answer is pretty much HTML with some kind of microformat information embedded via attributes.

In other words, the schema.org approach is arguably pretty much what you're supposed to do in order to design pages to gracefully fall back. I'm not sure why you might think those two concepts are at odds. :)

People who disable features of their browser on purpose will always be getting a degraded experience. No way around that.

People have JS disabled without their intent. Corporate security standards, broken JS in CDN served libraries, mobile proxy browsers, the list goes on…

With the rate CSS is accumulating kludges and the fact that, when together with HTML5, it has already crossed the Turing-completeness threshold, I wonder how long it will take before companies start requiring browsers to disable subsets of CSS...

I think CSS Zen Garden still exists...

And this is absolutely the only place where "separation of content and layout" works. In real world, layout often is a part of content - but instead of accepting that, a lot of developers like to proclaim that their code is soo semantic, and the metric ton of grid layout divs in their "content" is not tables in disguise, but definitely has some important semantic meaning...

Seriously, I don't know what's more broken - CSS itself or the web developer community, with the amount of self-deception, cargo-culting and stockholm syndrome cases present there.

It worked perfectly fine for me from ~2004 and forward. I guess the bigger problem is that web tech is considered somehow not important so lots of developers did not really bother to unserstand CSS. I think around 2005 we had a golden times of the web. It went downhill since, sadly. Prolifereation of one-page web apps, stupid desire "to win mobile", mindless spawning of all kinds of frameworks turned out into complete mess :(

Funnily, 2005 was the time when people were misunderstanding JavaScript. I still have nightmares from all those animated snowflakes and rainbows following my mouse cursor, or date calculators embedded on every other page for no reason except to show off...

Unfortunately, CSS doesn't really fix that problem.

If you're writing it properly (i.e. not inline), it actually does. Even more so now with SASS & variables.

Check out http://camendesign.com/ The last time I looked it had no ids nor classes.

That's pretty nice, actually.

Open up any webpage and count how many divs with no other purpose but to serve as CSS anchors there are. We traded in non-sematic tables for non-sematic divs.

The <div> element has no semantic meaning, screen-readers don't read them and they have no intrinsic behaviour unless associated with an aria tag.

Why couldn't we just have made non-semantic tables? In addition to the semantic tables, I mean.

Divs with display:table/table-row/table-cell _are_ non-semantic tables.

except divs lack colspan

I came across this issue recently and was surprised after all these years there still isn't colspan support. Ended up having to create additional containers when I should be able to style it using CSS.

There's (almost) always a way round a problem. In the case of colspan, try this:


Which would actually be somewhat helpful, come to think of it...

adding role="presentation" to a <table> element will tell screenreaders to treat the element and its required children as non-semantic. I still say using a table for layout (of non-tabular data) is should be a last resort but it's easy for me to say since making a layout is rarely my job.

Except that div have no semantics by definition.

I agree and it really bothers me that all the markups in modern web pages are littered with COL, span, md, lg, xg, 1/2 2/3, with gibberish nestings. Semantic web went out the window, in favor of responsive web.

The whole web is fad-driven, so I'm glad at some point, pendulum will swing back.

Meanwhile, I'm just happy parallax fad is dying out.

Allowing an arbitrary website to work on a phone isn't really a fad, though. In a few years time, there's not going be a huge sigh of relief as everyone gets back the fixed-width websites they've been crying out for.

"Allowing an arbitrary website to work on a phone isn't really a fad, though." Agreed, but current implementation is mostly terrible, with 6 break points, 1-2MB downloads, everything = single page app, etc. So the concept of write-once, run everywhere is not a fad, but the implementation is very fad-driven.

Ah, that's fair enough; I was thinking at a more conceptual (or even just CSS rather than JS) level.

Browsers should e.g. allow tables to be sorted by clicking column headers. They can't, because tables aren't always tables.

How about an opt-in attribute to enable ordering then?

<table sortable >...</table>

Tables nested in tables nested in tables was a fate worse than divs. Even in the simplest case (one box) a table stinks: <table><tr><td></td></tr></table>. I personally found that trying to debug which table a <td> belonged to was hell on earth.

Just starting to realize how out of touch HN readers are with CSS. This mindset does not belong in a conversation about CSS in 2015.

This owes at least in part to the fact that tables are not optimized for page layout. And that was especially true 10 years ago. Popular browsers couldn't render partial tables, and you had even more performance problems nesting them.

Grid based layouts are obviously useful but the table tag isn't the right tool.

Kinda. I used to agree with you for the longest time, but I can relatively easily make a CSS bootstrap page responsive, because I can override the bootstrap CSS, but there is no way to override the behaviour of <table>.

You can use semantically meaningful class names and use the mixins from the Bootstrap source. Even though it's probably common practice and great for you know, bootstrapping, I don't think it's good for maintainability to leave the column classes in the markup. In a large, modular, front-end heavy project, proper separation of content, presentation, and other cross-cutting concerns really pays.

and I wonder how the <ul><li> somehow survived unscathed and free from the semantic witch hunt of yore. shouldn't we replace them with:

<div style="display:list-type; type-of-list:unordered"> <div style="display:list-item;">


The "semantic witch hunt" against using tables for page layout exists not because the table tag is a semantic tag, but rather because pages are not tables. Likewise, ul and li tags are semantic, and I think most people would advise against using them for something other than unordered lists and list items.

Of course, the issue would probably come up rarely, since the browser stylesheets for those tags don't do anything particularly useful for anything other than lists and list items.

This comment doesn't make any sense. A list is a thing, just as a table is...

What are you trying to say?

Down vote for "doesn't make sense". It made perfect sense to me.

The phrase you were looking for is " I don't understand what you're saying."

Then perhaps you would like to explain it? The most meaningful interpretation I can see is that the commenter completely misunderstood the nature of the "semantic witch hunt" to which he referred. It seems charitable to assume that something was lost in translation and to ask for clarification rather than to assume that the commenter was just saying something stupid.

Very true, and such charity doesn't help the discussion. Insisting on the polite path, "I don't understand" instead of "your comment makes no sense" wrongly assumes that all comments written on forums are carefully considered and fact-checked before posting. It's taking the long way to resolution of that point, and you might never get resolution if bogged down in overly-polite discourse for fear of being "negative".

The phrase the poster was looking for was that "the example provided was hyperbole." Your comment is far too confrontational.

If you go down that path, there are no semantic elements left at all.

Yes, you are right. As long as people are using HTML mail, tables for layout are the only way to go.

You just made the best case for Markdown email that I've seen.

Author email in straight text? Markdown is what you're writing already.

Author it in WYSYWIG/GUI clients? You only care about presentation.

I have a gift for you! : /s

No, use divs and table-cell display values if you want to have non-tabular data displayed like a table.

Indeed I have non-TABular data and yet I should use TABle-cell? I'll just stick with the actual <table> then. cleaner. But the real problem is "use divs". plural. so already breaking the #container_of_container cruft rule. I'd rather write some javascript with overly nested callbacks and leave the html clean. thanks.

<table> is content, table-cell: is presentation. Semantic tag use matters because some people are blind and their screen reader will start randomly start talking about some structure that makes zero sense in context

I understand and agree with the general argument, but is it actually true that screen readers for the web are that naive? I would expect them to render a page (like with WebKit) and try to figure out the layout of the page, which things are actually visible, etc., or at least use heuristics to figure out what is and isn't content (in the same way that Readability-esque algorithms presumably do).

The browser, not the screenreader, does the rendering, figuring out what's visible, etc. The results, an "accessibility tree" which is sort of a subset of the DOM, are then presented through an accessibility API to screenreader software. Screenreader software is pretty naive, there might be some that initially assume a table is being used for presentation, not data, if it lacks good semantic structure (e.g. no <th> header elements). Case by case, it's hard to tell in which way the author is bad at their job, using a table for presentation or poorly marking up a table for data.

The stakes are much lower for Readability-esque algorithms, when they fuck up the user can just go back to the site's native presentation; screenreader users don't have that choice.

> Readability-esque algorithms presumably do

They look for the div with the most text/paragraphs in it and assume that's the article. At least, that's what the open source ones I looked at a while back do -- the proprietary ones that force you to go through their own server could use other tricks.

Just a practical consideration, but the HTML table tag is actually a lot more restrictive (<table> can only contain <thead> <tbody> or <tr>, so no wrapping span to regroup some table rows) than using <div>s. Can be important depending on third party libs.

(…and <tfoot>, <colgroup>, <caption>)

Yeah, it's obnoxious when people get up-in-arms about specifics. But, you have to admit that it's correct. Why use explicit tables when you can use style overrides to get the look you want and your HTML markup is more meaningful to robots?

But then just admit it, you broke the web separation of concerns rule ("HTML is for content, CSS is for layout"). Which is load of nonsense, if you ask me, but people seem to treat it as a kind of religious dogma.

Do you mean the requirement for a container `div`? If so, IMHO, that is the most routinely broken "rule" in web page design that I can think of. It should be obvious that the technologies involved in web pages are not perfect. I'm not claiming otherwise. It's a question of trade-offs. You're going to break the HTML is content convention whether you use a `table` element or a `div` element with "display: table". So why not just go with the one that's more correct? It's up to you either way I guess.

`display: table` and `display: table-cell` are just layout algos, commonly used for creating a table-like layout.

You'd rather write unncessary Javascript and/or three nested HTML elements (table > tr > td) instead of two divs and some simple CSS? Man, I'd hate to be one of your clients since you don't really understand front-end development.

Ok, now make it repsonsive, e.g. one column should be below the other on the narrow screen.

The mere fact that the site exists means nothing. Any problems around centering have been completely solved by flex box. If you're targeting obsolete browsers, you're going to have to expect to do some legacy hacks.

Heh, generally any time there is a site with a name that is a search query it is an SEO hack. I was surprised it wasn't plastered in ads :-)

That said, centering (and typography) in CSS and elsewhere is that you mix passionate people with a really hard problem and you don't get answers, you get a lot of debate. I used to read the alistapart mailing list and it was intense at times. Suffice it to say that when the content of part A and part B are different by 1 screen pixel, and you're centering, do you assume +1 pixel or -1 pixel? (You don't get 1/2 pixel resolution) a typically large debate

A tool is not broken if people insist on using it in ways it was not designed to be used.

The fact that you say there is no easy vertical center, of which I disagree, doesn't make it broken. It means it's missing a feature you wish existed.

> it's missing a feature you wish existed.

indeed, an extremely basic and fundamental feature than any site that implements popups could use.

And yet, popups seem to work just fine without this missing "basic and fundamental" feature. There are numerous ways to handle the problem that is legitimate and valid.

It really isn't.

There's this misconception that CSS is a display language; it's actually designed as a typesetting language that must degrade nicely.

At least you can do horizontal alignment by throwing in the towel and using <div align='center'>.

Vertical alignment is the real killer.

It's actually a consequence of the CSS box model, which makes a lot of other things simpler, and means that figuring out how to position things isn't turing complete or something.

I think the secret is that maybe 10% of CSS writers actually have read more than the bare minimum to getting their layouts to work ( I am not among them, mind you).

Pretty simplistic/naive.

I am reminded of one of my favorite tweets of all time:

“The easiest way to vertically center something in CSS is to close your laptop and go to the bar.” - @jakeboxer


This one cracked me up too:

    “How to choose between rem and em”
    1. question css
    2. question your life
    3. throw away laptop
    4. scamper into forest

As others said, flexbox is a complete replacement for all layour hacks in CSS. This site helped me understand flexbox: http://flexboxin5.com/

Browser support: http://caniuse.com/#feat=flexbox

I've understood that Flexbox is what you should use for 'small layout' (controls, etc) but ultimately we should be using the new CSS grid module for 'large layout' (pages).


Of course, it might be a while until there is broad browser support!


I'd think you should use flexbox for what it's good at --calculating and distributing the available space on it's children-- and grid for what it's good at --enforcing strict and precise layout outlines--.

That site is completely broken in Safari. Don't think we're ready for flexbox just yet.

It's not the site that's broken, but Safari.

What's broken is not Safari but people who buy Macs. ... I can't go any deeper. Still I'd like my site to look good to a meaningful market share.

True, but I wouldn't say 4% is a meaningful market share, so fuck Safari. It's the new Internet Explorer.

Leaving the sites broken in Safari (and maybe adding a notice that explains why it's broken) also helps keeping it at 4%.

Safari is also the native browser for iOS. I don't know where you got 4% from but Safari (both for OS X and iOS) is more than 4% market share.

For starters the market share is far higher than 4% on the desktop, and even more when looking at the mobile / tablet market.

It's more like Chrome is the new Internet Explorer, because lazy web developers decide to only target it, so we end up with sites specific to one web browser.

Yeah, the 4% was wrong, sorry. Anyway, things seem to just work in FF and Chrome, but Safari often requires fixing because of bugs, missing features or Apple doing things differently for no reason. It's annoying.

And like Microsoft, they are so damn slow to release updates and older machines don't even get any.

As a web dev, I get it - but if you have a million visitors then you're saying "fuck you" to 40,000 people. If I was _paying_ a web dev, I'm not sure I'd be satisfied with this response.

Safari needs prefixing and I think that site doesn't have prefixes.

How is it "completely broken"? What version of Safari are you using because it is working perfectly fine when I use that site in Safari.

Ha, the first time I saw he site I was incredibly confused for that reason.

Hmm, that http://flexboxin5.com/ site didn't work in Chrome at all. Claimed it was going to resize when I pressed resize it early on and did nothing.

No issues with Chrome 42 on OSX 10.10. That said, that particularly site its quite complex in how it handles updating the DOM, so might not be the best example anyway.

Works fine here. You might have an extension that's breaking something? Try an incognito window as a quick test, which should disable extensions.

Same. Debug console:

main.js:769 made it this far

main.js:1182 nope, not happenin today sir.

Hmm...I didn't have any problems with it in Chrome.

What's the best polyfill for flexbox?

Add autoprefixer to your build chain: https://github.com/postcss/autoprefixer


So: is it not degrading gracefully a property of the site, or a property of Flexbox?

Doesn't Flexbox pretty much solve this problem? I mean, if you need to maintain backwards compatibility this might be reasonable, but "justify-content: center" and "align-items: center" seem to work unreasonably well for this exact purpose.

Flexbox solves this problem but it's still a bit unwieldy and verbose.

Verbose? Compared to the other solutions it's a godsend, just use the CSS-tricks guide for it and you'll have nearly zero problems. I absolutely love it and pretty much refuse to use anything else for layout in CSS now.

IMHO constraint systems like GSS (http://gridstylesheets.org/) handle centering in a much cleaner way. Pity that approach hasn't gotten any traction (though some people smarter than me say it's a bad idea, so who knows what the right answer is...)

When I first heard of GSS I thought it was the solution to layout that we'd all been waiting for. Unfortunately it's not all roses. It's possible, and quite easy to inadvertently create cyclical constraint dependencies. Depending on how your constraint solver is written this might mean that a layout will fail or that your system will lock or crash.

I'm subscribed to a couple of constraint solver mailing lists. A common question is "why is my constraint solver doing this...?", or "how do I massage my constraints to achieve this...?"

With CSS You can't build a layout that 'fails' (in the sense that a solution cannot be computed due to improperly defined dependencies), and you certainly can't send your browser into an infinite loop by applying an incorrect style.

I still really like the idea of constraint based systems, but I think they are more suited to (web)applications rather than documents.

> I still really like the idea of constraint based systems, but I think they are more suited to (web)applications rather than documents.

Which is what some people will tell you web is about when you point out to them they're doing something weird instead of writing a document communicating a message. Maybe it's time to separate those two use cases - web pages and web applications - because otherwise people will keep getting confused between the needs and problems of the two?

Anyway, GSS looks pretty cool.

I much prefer the deterministic flex box to the mysterious auto layout, even if you might have to use a container div here and there. I think constraint solving is a fascinating idea, but it always seems to end up involving me setting magic priority numbers with little understanding as to why.

I agree, flexbox is refreshing. Couple it with autoprefixer or a flexbox scss mixin, layout a design with it for the first time and you won't go back.

For people that are use to hacks + grid systems, it seems weird at first, but over time you will become familiar with a rich layout system and stop thinking left-to-right, it will become more natural. The language of the spec and the declarations (align/justify distinctions, etc) can be weird at first, but you get used to it.

Just remember IE10 only supports the 2010 flexbox spec (you can't inline-flex, need -ms-prefix etc.)

Compared to the rest of the CSS spec, I'd say so. It certainly solves the problem much better, though.

Flexbox can be a bit low level, but with it you can build abstractions (eg. classes or preprocessor mixins) for common use cases, which I think is preferable to having only a high-level tool which can't cover all use cases.

write using modern/stable flexbox syntax and use autoprefixer for older browsers: https://github.com/postcss/autoprefixer


I know the web is not print, pages are not static, user screens vary and one shouldn't try to control everything bla bla bla, but it seems all my layout woes ultimately boil down to difficulty in lining things up.

That's what 'layout' means after all, isn't it? Aligning one thing with another, to show they're related. I'm not a classically trained graphic designer, but doesn't any explication of visual fundamentals include 'alignment' somewhere up near its top?

Yet CSS really, really sucks at lining things up.

Anyone designing a better system might do well to start with the notion of alignment as a basic primitive/operator. To be able to say, item A here ought to line up with item B there (and if not possible, predictable behaviour C results).

My gut feeling is that one could then derive all other types of layouts from there. I admit that might be naive. Also, I realise that I've probably just described constraint-based layout, but as yet I haven't tested one of its implementations such as GSS in a real project.

As a classically trained graphic designer, I find the biggest problems to layout is more due to the fact that the display is completely unknown. It can range anywhere from hundreds of pixels in width/height to thousands of width/height in pixels. Not to mention the differences in pixel densities and orientations.

If one were to consider these problems alone, CSS works quite well for what it was designed to do. Most designers I've discussed these problems with have problems more in their thinking than with the tool itself. They mostly try to apply print design thinking to web design, which simply does not work.

The table-cell solution for vertically centering text is incorrect. You need to put that display:table-cell div inside a display:table div. It requires the parent in order to work properly.

Example: <div class="item"><div><p>Your text here</p></div></div>

.item {display:table;} .item > div {display:table-cell;vertical-align:middle;}

I use this method on justindocanto.com to vertically center an unknown amount of text/elements inside a div that changes its size based on the size of the image that's inside it. Really nice technique when used correctly.

Yes. This page gives wrong solutions for unknown size of centered block but known sizes of container.

Wow CSS is unfriendly, you really realise how poor it is once you learn other layout systems (android's XML and iOS auto layout, etc).

Wish there was another standard that could co-exist side by side on the web, something simple enough to be implemented reliably by the browser vendors.

> Wish there was another standard that could co-exist side by side on the web, something simple enough to be implemented reliably by the browser vendors.

That standard exists. It's called flexbox. It was designed to solve exactly this problem (among many others), and does.

That said, as I never tire of mentioning, vertical centering was a part of the design of CSS 2.1. The technique is called "absolute centering". See CSS 2.1 10.6.4 [1]: "If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under the extra constraint that the two margins get equal values."

[1]: http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-hei...

But then what happened to it?


do...do they know...how many manhours could've been saved...?

Nothing happened to it. It gets used by front-end developers every single day. I personally can't follow the CSS complaints. It is easier to learn than any other front-end dev language in one's toolkit.

Yeah, everyone did a really bad job of evangelizing absolute centering back in the day, leading to lots of angry Web developers and awful hacks like the inline-block/vertical-align trick. It should have been the first example given for "position: absolute"…

How do Android's XML and iOS's auto layout compare to Microsoft's WPF? I used the latter around 10 years ago and found it pretty nice.

Exactly. I haven't done HTML layout since circa 2000. I tried WPF about 8-9 years ago and well, it was just simple to get layouts right. I'm sure there's some reasonable reason for it, I just don't understand why browsers couldn't do similar, or just rip off WPF.

I haven't used WPF in about that time myself, but Android's XML is a roughly similar experience. No idea about iOS's auto layout.

I've heard that android's XML layout is terrible (from an android developer) and that iOS auto layout is borderline magic (from an iOS developer).

Personally, I don't find css to be that bad at all, but I work in it at least a little everyday so it might just be stockholm syndrome.

as someone who's done both (and web) -- Android's XML layout is easily the best of Android, iOS, and web, while iOS's AutoLayout is a complete mess that basically only works because there are still so few iOS screen sizes. Android coding in general is a pain compared to iOS, but they definitely got the declarative layout system right.

iOS developer here. AutoLayout is definitely not borderline magic, and some people hate it.

It is inefficient. It is awkward to set up in code, so many people write their own syntactic sugar around it. It crashes hard when it isn't 100% sure what to do with its constraints. Working with multi-line text is still a pain, so you often run into clipped text on iOS if you dare to increase the font size. etc.

Anonymous downvoters, AutoLayout may work great for you, but it is definitely controversial among iOS developers (more so than e.g. ARC). Nothing wrong with pointing that out.

Hey thanks for the reply. I don't work on mobile apps at all, so I really wasn't aware. It's definitely interesting to see your point of view,

I remember when I was first learning CSS and I found out this wasn't easy. I thought "oh my god, this learning to code stuff is gonna be HARD!"

A few years later and I don't think anything but the occasional third party api with undocumented behavior has been nearly as hard.

To save people a bunch of time, here's 90% of the comments:

>Just use flexbox!

Which is great, except it isn't supported at all by IE8 or 9 and is only partially supported in IE10 (by prefix only). Which means a lot of people simply can't use it. I'm hesitant to use it myself, and I've got a very lax policy on supporting old IE.

My company recently went all in with flexbox, and you should too. We had the same concerns, but even IE 9 is 4 years old at this point, and we decided we shouldn't be held back because of it. If a client wants IE9 support, they can pay extra.

I have run into a few IE10 gotchas, but they're all solvable. IE10 just uses an older version of the spec.

and IE itself will be cut loose from MSFT in a few months.

It's a business decision to limit forward progress to support browsers 3-4 major versions behind. One that multi-billion dollar companies like Google have decided isn't worth it.

"A lot of people" = 4% on IE 8 & 9 (http://www.w3counter.com/globalstats.php)

Really depends on the business and their clients. If you've got a lot of corporate clients stuck on IE8/9, why disenfranchise them? Although I will say this has me re-considering flex.

I can't think of a technology that has both saved and wasted more of my time than CSS.


I often use this as an interview question for CSS people: "How would you vertically center a box inside another box." I like it because there's like four correct answers, each with drawbacks. The general answers, from worst to best, are usually:

  1. margin: auto (wrong)
  2. top: 50% (mostly wrong)
  3. negative margin-top (correct if you know the size)
  4. table-cell or translateY (correct)
  5. a correct answer plus a discussion about why it has to be a hack
FWIW, when you set everything to "Unknown", this site tells you to use display: table-cell. If you don't have to support IE8, I generally prefer "top: 50%; translate-Y: -50%"

[Edited for spacing.]

This actually proves that CSS is broken. I just want to say: 'put this content in the middle' nothing else. That is the reason why I am trying to avoid doing frontend whenever possible - it just sucks. Luckily Elm(http://elm-lang.org/Learn.elm) tries to solve that problem and i hope it will get some traction very soon.

This should also have an option for 'what browsers do you need to support' and just provide flexbox output instead if you don't need to support legacy IE.

Don't forget the need to support HTML email clients. Say, Lotus Notes.

Using some sort of service (i.e. Mailchimp or any of the other numerous email sending services) surely takes care of this, no?

This looks really useful. In case the author reads this, one addition it could use is explaining why the given css works. And, like someone else already mentioned, indicate browser support. I haven't used this display:table-cell before and I wonder about its support. A small thing to lookup, sure, but it would be nice built-in. Or selecting which browsers you need to support and using flexbox when possible.

This site doesn't seem to be suggesting absolute centering [1] when it would be the easiest way to center things.

"margin: auto" seems to be the way that the designers of CSS 2.1 intended to center things. 90% of the time, absolute centering is the easiest way to center in CSS; you should prefer it when possible.

[1]: http://codepen.io/shshaw/full/gEiDt

Would this technique work to center, say, an <img> tag with undeclared dimensions inside of a div? Or do you have to jump through hoops?

No, if you don't have a defined height you will need to either use "display: table", the table-cell technique, or flexbox. When I told the site that I had a defined height, however, it still suggested the table-cell trick, which was not the optimal solution because of the extra markup required.

In my experience, most of the time when I do want to center something vertically, I have a defined height (which can be a percentage!), so absolute centering is the solution of choice.

With no defined height you can still use the `translate(-50%, -50%)` hack, right? I'm kinda surprised it hasn't been mentioned in this thread at all; I use it all the time. http://codepen.io/padolsey/pen/NqKzVG

An image can be vertically aligned with vertical-align: middle; and centered with text-align: center;

Firefox uses pcwaltons method for images (resource://gre/res/TopLevelImageDocument.css). Do you want the image to be in the center/vertical of the div (with the div having a specified height)? If so, then pcwaltons method should work, as long as you have position:relative; on the div.

Another way to center flexible boxes is to use css transforms http://zerosixthree.se/vertical-align-anything-with-just-3-l... CSS transforms have pretty good browser support http://caniuse.com/#feat=transforms2d

I really miss the HBox and VBox of Adobe Flex. They made aligning content so damn easy (and it was responsive, no media queries either)

   <HBox height="100%" width="100%" horizontalAlign="center" verticalAlign="middle">
        <VBox>Col 1</VBox> 
        <VBox>Col 2</VBox>
        <VBox>Col 3</VBox>

Ew, Adobe Flex

Unfortunately, this page does not give a solution to a long-standing centering problem I've had: Given a single DIV of unknown width and height, how do I center it in the middle of the screen (floating, i.e. fixed)? Note the "single DIV" so no wrapping in additional container DIVs!

The only approximation I could find was this:

  .mydiv {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
This, however, looks horrible on most browsers as they either use hardware acceleration (resulting in blurry output) or they drop pixels (e.g. single-pixel lines) falling between the grid.

This also relies on a container DIV (".overlay"). So Flexbox doesn't help here.

What exactly is your centered div centering to if there's no container div? The .overlay div is the container, the .dialog div is centering itself as defined by constraints of .overlay.

I'm failing to understand your expectations.

Let's say this is a modal dialog which is supposed to appear in the center of the screen, fixed (but the size is unknown and may scale with its contents). With any of the existing solutions, the HTML code for the dialog will always be <div><div>...</div></div>, i.e. unnecessary DIVs due to the limitations of CSS. Since it is supposed to float on top of everything else, it does not matter what its container is. May as well be the <body> tag but applying flexbox to that tag is likely not an option.

But the HTML you describe is required for the modal as you describe it. I guess I'm assuming you want something to darken the body content behind the modal, which is what the first div would be for.

Otherwise, if you don't need the darkening div behind the modal, you can easily create a centered modal with the container being the body tag. Without flexbox. Today.

Again, I don't understand your expectations.

Why is that a problem? In real life you always have a container div.

+1 more reason to avoid web development whenever possible. ;-)

My personal trick is to position the content absolutely at 50% (both left and top), and then transform the content using a -50% translate in both directions.

Works for dynamically sized content (and statically sized content as well, obviously).

But then people whine about no support for a six-year old browser.

This is the sort of thing that makes me conclude that the right way to teach oneself html+CSS is to read about the basics and then just find 100 increasingly-difficult layouts to implement and grind through them.

Finally! I can't believe this is still such a big problem in CSS today.

All the people who are still perplexed by this, have to admit that they haven’t heard of or tried flexbox. It works beautifully (in conjunction with Autoprefixer).

Here's the thing: Most of us who are perplexed are actually perplexed because is was something you used to be able to do trivially and then a new standard came along and made it unreasonably hard for about 15 years. An eternity in software development. Entire generations of paradigms have come and gone in the time it's taken for CSS to fill this gap.

That will never stop being perplexing, no matter how many new models they throw on top to try to fix it.

Heard of flexbox, it's nice but here's one thing I haven't been able to do with it:

Center a bunch boxes in a row and have overflowing boxes show up on the next row to the left or right. Doesn't work, it will center the next row as well.

I haven't found a non JS solution to this yet.

Not sure if I know exactly what you mean, but can you use :nth-child for the nth box that shouldn't be centered?

not sure excalty what you're descibing, but shouldnt flex-wrap work to fix this?

flexbox will be nice. once widely supported.

<div style="display:flex; align-items:center; justify-content:center; width:100%; height:100%">dynamic both v and h aligned center</div>

oh man, that's a mad world we live in. look at that.

it's just sad to think that a browser can do so much stuff, yet it's unable to provide a good layout system.

It's good at what it was originally designed for: flowable text documents. And, honestly, it's come a long way since its early days. Used to be much worse.

This site should give HTML and CSS separately, rather than giving inline CSS.

Maybe it's just me, but I find it much easier to understand exactly how a proposed solution works when it uses inline CSS. If the HTML and CSS appear separately, I have to look back and forth a lot to make sense of the whole.

Of course, when I actually implement it in my design, I prefer to separate my CSS from my HTML.

I wish the solution was presented in both flavors, side by side.

Wow, this IS a huge pain solver. I can't simply recall how many nights I've been spending trying to fix the centering in CSS during my early days as a frontend dev. Thank you,bookmarked!

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