h5bp / html5-boilerplate

A professional front-end template for building fast, robust, and adaptable web apps or sites.
https://html5boilerplate.com/
MIT License
56.44k stars 12.23k forks source link

Replace IDs with classes in index.html #203

Closed ericdfields closed 13 years ago

ericdfields commented 13 years ago

I'm thinking we don't need IDs in index.html. For writing CSS, IDs should be avoided as they add unnecessary specificity. They're great for quickly targeting elements we want to manipulate the DOM with Javscript, but its unlikely to be the "container" or "main" elements. Replacing the IDs with classes would simply discourage people from using them in your CSS later.

I can't find this article now, but there was a good read from this year on avoiding "container" divs altogether, as you can accomplish the same thing by styling the html tag as your background canvas and using the body as your primary container. Of course, I can't find that article at all right now…

joeybaker commented 13 years ago

Interesting, but I'd vote against. IDs for divs like "wrap" or "container" (irrespective of their need to exist in the first place) make a lot of sense. An ID, as you say, is meant to only appear once in the DOM – which is exactly what those container divs are meant to do. We may never target them in the CSS, but if we do, IDs perform faster than classes.

paulirish commented 13 years ago

nicole sullivan would agree here.. she's very anti-ID as it fucks with your selector specificity. personally i dont think specificity will be a problem with the container and main that we have... i also think many people prefer IDs on these... but i'd love to hear from folks like eric who like the class approach. :)

rizkysyazuli commented 13 years ago

since I'm a fan of Blueprint. i'll vote for this. BP use a class for the container element. already change it to class in my fork.

960.gs also use a class for specifying the number of grids from the main container. something like "container_12" and "container_16".

joeybaker commented 13 years ago

So I hear ya'll – just dealing in classes can be a lot easier, but let me give three arguments against:

1) Speed. Jquery can be up to 100x faster using IDs instead of classes. http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#tip8

2) :target. Jeebus do I love that CSS3 selector. It basically eliminates the need for a lot of $().fadeIn() etc… Which means that the browser is using CSS instead of JS which means more speed.

3) These are primary, main, elements, that should never, ever, be replicated again in the DOM. That's the definition of an ID.

ericdfields commented 13 years ago

Both of these are good arguments for IDs... in your own markup. We're not really assuming you'll be acting on #main or #container, nor should we be.

Riz brings up a good point about container being a standard class name in two of the most popular CSS frameworks. It'd be nice to show solidarity :)

nimbupani commented 13 years ago

3 of joeybaker's list makes sense to me. These are primary elements of the template which shouldn't be repeated. That said, you could add a class to those elements for OOCSS.

kswedberg commented 13 years ago

I agree with nimbupani's last comment. In fact, I'd recommend adding a class to those elements in the index.html boilerplate, e.g. <div id="container" class="container">. Best of both worlds.

nimbupani commented 13 years ago

My only concern is if someone uses the class "container" for any other element, it would inherit from the same author styles used to define the #container. It is a situation I have fallen into frequently especially when you have multiple widgets in your screen, and they dont use iframes (but use such universal classnames) :/

ericdfields commented 13 years ago

The OOCSS argument is a good one. I think adding a class to the ID'd elements is a good compromise. @nimbupani I haven't encountered that too much. Most widgets I've used namespace themselves properly. Anyone else? Specific examples?

ericdfields commented 13 years ago

There's not a lot of persuasive motion here. I'm going to close it.

impressivewebs commented 13 years ago

I know this is a bit late to the game here on a closed issue, but I think the argument that the container is a "primary" non-duplicated element is not really a valid one.

Yes, it's true, the container with all of it's full styles is not going to be duplicated. But that's not what OOCSS is really about. OOCSS abstracts certain characteristics of elements and reuses them in multiple places. So the container might have something like:

<div class="container-main basic-border shadow rounded">.

So in that example (which is very over-the-top for illustrative purposes), the class .container-main would have some very rudimentary styles that apply only to the container, then the other class names would represent the reusable elements that might appear elsewhere.

Of course, the same thing can be accomplished using:

<div id="container" class="basic-border shadow rounded">.

But why would you do that? What would be the point (from a CSS perspective) of using an ID of "container", which could cause problems with specificity and the cascade? When you use the class-only method, you avoid any possible specificity issues, and you encourage all developers to recognize the importance of abstracting common styles.

And naturally, if someone wants to grab the container with JavaScript, then by all means, they can add id="container" any time they want. But that's optional, so it would seem less practical to include that and not the class, which is definitely going to be used in the CSS.

paulirish commented 13 years ago

reopened for louis's comment.. i'm pretty content with dropping #id's currently.

joeybaker commented 13 years ago

While I don't feel all that passionate about this, I'll argue the counter passionately anyway :)

The argument that the container is a primary, non-duplicated element is perfectly valid, you've just proven that there are some advantages to having classes on the container as well … which is useful if you follow a particular style of CSS writing.

My css for the container is most projects is just #container {min-width: 960px; background: #fff; }. Even if you're a OOCSS fan (I like the concept, but find it frequently doesn't work in practice),

  1. I can't think of a case where @impressivewebs's second example of <div id="container" class="basic-border shadow rounded"> wouldn't work since #container is at the (near) top of the DOM.
  2. Maybe it's just me, but I can't remember a time where I've done anything more than the most basic styling to #container

Further, I do sometimes use javascript to get the #container (jquery's .load() for example), why complicate the issue with classes?

I'll add one more point that I think has been implicit, but hasn't been stated: simple is good. Ids are the simplest selector, why complicate matters?

IMHO

Edit: I still don't feel all that strongly about this, since it's an easy thing to change, but meh… the argument is half the fun?

necolas commented 13 years ago

IMO, we should drop all the placeholder HTML between the body tags anyway.

joeybaker commented 13 years ago

@necolas nihilism FTW :)

impressivewebs commented 13 years ago

@joeybaker:

I agree with one thing: The argument is at least half the fun. :)

Regarding the container being non-duplicated: This really has nothing to do with removing the id from the container. I am in 100% agreement that the container is unique. This has to do with best practices in CSS.

For example, which of the following two code snippets is more efficient?

This one:


#container {
    margin: auto;
    width: 60%;
    box-shadow: #000 3px 2px 2px;
    border: solid 1px #ccc;
    min-height: 60%;
}

Or this one:


.container {
    min-height: 60%;
}

.center-full {
    margin: auto;
    width: 60%;
}

.shadow-border {
    box-shadow: #000 3px 2px 2px;
    border: solid 1px #ccc;
}

The answer is clear: The second one. The reason? Because the non-container styles can now be re-used. This is not to say that they definitely will be reused, but this encourages the possibility of re-use, which is really what best practices are all about.

You mentioned that you only do basic styling to the container. Well, that's why OOCSS should be used! :) Because those 'basic styles' can be moved into a reusable module that you can 'call' when you need them. Yes, it's true, the container is quite unique, but it has the potential to have reusable styles (like a border/shadow or something else). The point is that, for all practical purposes, .container is exactly the same as #container in your CSS, except for the fact that .container doesn't have the potential for specificity conflicts that #container does.

And yes, you will sometimes need to grab the container using an ID. But that's not a requirement, so it shouldn't be there from the start. Especially if it discourages the best practice of abstracting common styles and making the CSS faster and more efficient.

Finally, you said "Ids are the simplest selector". That's not really true. Is .container not just as simple? Also, as mentioned, the specificity problems can be troublesome. But again, those specificity problems don't exist with classes that abstract common styles.

Well, this has somewhat turned into a debate on OOCSS, but in my opinion, changing id="container" to class="container" would go a long way to encouraging the better practice of writing reusable CSS. And hey, maybe the container isn't the right element to argue for OOCSS, but if .container is no different, then why not do that? What exactly is lost from using the class instead of the id?

I think in some sense, many developers are clinging to the tired old habit of putting an ID on everything, but I'm starting to sway in the other direction nowadays.

joeybaker commented 13 years ago

@impressivewebs:

I can't tell if we've wandered down a rat hole or not, but since we both agree the argument is worth having, if not just fun …

You're points on OOCSS are of course valid, but you also lead into it's inherent weakness: classes that might be used again. Classes that are used only once are likely wasteful and lead to code bloat.

CSS should be optimized not for the developer who has to maintain the code base, nor the user who just wants a fast experience, but a practical mix of both.

With that in mind, classes like .center-full & .shadow-border may be used again, they may not be. If they're used again, they're worth abstracting into a class, but until then, your first example is actually more efficient – both for the dev and the user.

That's the main problem with OOCSS – this isn't server-side where additional code just makes the code base more verbose. Every character is a performance hit. Every additional class is a detriment to the user if it's not needed. Not for nothing, extra class can also really complicate your "API" – I'd have trouble remembering all the different options I'd built for myself and duplicate functionality.

Further, in the example you gave, you're OOCSS wouldn't be affected by #container since it's at the top of the DOM.

Don't get me wrong – I'm not advocating styling a bunch of Id's separately each time – that's also wasteful. But, in the interest of reducing bloat, I'd say that as a default we can assume that the container will both 1) have unique styling and 2) can safely be an id without messing up the cascade.

impressivewebs commented 13 years ago

@joeybaker

Okay, good points. However, what's the problem with using class="container" instead of id="container". Even if you are going to clump all your styles into one block, the class is almost exactly the same, except for a very small performance benefit in favour of the id. But it seems that many are arguing that the small performance benefit to using an ID over a class is trumped by the potential problems of using IDs.

Anyhow, this is not a huge deal to me, but I just can't see many reasons for leaving it as an ID, since an identical class would be almost exactly the same and would encourage what I believe is eventually going to be a universal best practice (that is, OOCSS).

Gavrisimo commented 13 years ago

What @necolas said. Just drop every placeholder and let people do their things however they want.

necolas commented 13 years ago

Because you can't always tell what is going to end up being reused, you should do your best to make reusable components and sub-components from the beginning rather than having an avoidable period of refactoring and/or bloat at a later date. Some sort of component-based architecture is probably the only practical way to have maintainable front-end code, smaller file sizes, and a product that can be rapidly iterated and modified.

As long as the classnames are semantic - meaningful in some way rather than inappropriately or confusingly abstracted, obfuscated, or truncated (does mod mean module or modify?) - then even non-front-enders should be able to make use of what you create.

However, H5BP doesn't seek to impose any form of front-end architecture upon users of the project. Plenty of people don't employ component-based architectures. Plenty who do, do so in different ways. So, IMO we'd be better off stripping out the placeholder HTML altogether.

Gavrisimo commented 13 years ago

"Plenty of people don't employ component-based architectures."

This.

impressivewebs commented 13 years ago

@necolas

I disagree, because it's not true that H5BP doesn't "impose" things on the user. Yes, maybe (from certain perspectives) it doesn't impose "any form of front-end architecture" (although that's arguable too). But what about the class-based IE styles? What about the inclusion of Modernizr? What about the inclusion of an HTML tag that prevents passing of validation? I could go on...

My point is not to say that I disagree with the inclusion of those things (well, maybe one of them :) . My point is that BP includes those because they're recognized as current best practices. And, as Paul says, BP is "delete key friendly". So, removing the HTML is just going to encourage arguments towards removing other things that are probably only used in half the cases, if not less.

I think it's fine to have an HTML structure in place, and I think it's much better -- and in line with what is recognized as best practices today -- to switch the container ID to a class.

necolas commented 13 years ago

Imposing a front-end architecture is WAY beyond the scope and aims of the project, and completely different to: fixing common bugs, accommodating browser peculiarities, and including common libraries.

But what about the class-based IE styles?

No class-bassed IE styles are included in the CSS

What about the inclusion of an HTML tag that prevents passing of validation?

First, validation is a tool. Second, we recommend removing that code and using the server config version.

So, removing the HTML is just going to encourage arguments towards removing other things that are probably only used in half the cases, if not less.

I don't think so. This is quite different to including common libraries or fixing bugs/problems. And if it encourages discussion on the removal of things that should be removed, there's nothing wrong with that.

I never even use that default HTML, even with a container class, because the structure isn't particularly flexible or universal.

impressivewebs commented 13 years ago

@necolas

Agreed. :) Like I said, I'm not arguing against those things, I'm arguing that it's okay to include stuff that's "delete key friendly", and I think the HTML structure falls in that category. (Also, I was talking about the conditional comments, but I referred to them as "styles" -- my bad; I just personally think it's bad practice to have a conditional comment for IE8, but that's my view).

I think the argument to remove the HTML is a different issue, but I would at least say that if BP is going to include the HTML, then the container should have a class, not an ID.

nimbupani commented 13 years ago

+1 to nicolas's idea of removing anything within body

paulirish commented 13 years ago

isnt there ONE snafu with using the body elem as your wrapper.. .something with IE8 i thought..

AlistairB commented 13 years ago

Some thoughts:

  <body>
        <header>

        </header>
        <div role="main">

        </div>
        <footer>

        </footer>
  </body>

as this gets people thinking about an HTML5 based design without proding them one way or the other in terms of OO CSS.

paulirish commented 13 years ago

WFM.

AndrewHenderson commented 13 years ago

OK, just caught up. A lot of good arguments. I'm gonna second Paul's WFM. I like this.

necolas commented 13 years ago

This change is barely any better IMO.

rcstr commented 13 years ago

cool

mathiasbynens commented 13 years ago

isnt there ONE snafu with using the body elem as your wrapper.. .something with IE8 i thought..

No.

necolas commented 13 years ago

This is nothing to do with using the body as a wrapper. That's perfectly fine if the intended presentation lends itself to that approach.

But the new HTML is no more useful a default than what came before. We're presuming role="main" on the div without any knowledge of the content or structure that someone will use/need...yet we haven't included any ARIA roles on the header and footer. It could also encourage people to place ads and sidebar content into that central div, thereby ignoring the point of ARIA roles.

What is the purpose of having any arbitrary HTML including by default? If the aim to get people thinking about using HTML5 elements and ARIA roles, then IMO it would probably be better served by including a comment with a link to a wiki page with a proper overview, links to good articles already covering this stuff, etc. We already do it for the appcache and the head tips.

AlistairB commented 13 years ago

@necolas

A comment and link would serve the same purpose in some cases, but I think many people wouldn't follow the link and just use what works for them. If all you know is table based layouts seeing a concrete example of a different way of doing things is a good way to prompt people to investigate more modern techniques.

I would like to have them both really. A comment stating that this is just an example of what you might include and a link to more information with the example HTML below.