Discuss the Drupal Markup Style guide

Bevan's picture

Discuss the Drupal Markup Style Guide

For reference, here is the discussion that has already occurred on that wiki page:

Bevan said:

I reworked this to add my two cents. I incorporated all previous ideas in this -- I think. Let me know if I missed something. - B/

Elv said:

It's better to have too many classes than not enough

I don't necessarily agree. Theme overrides will be far easier in D6, so it will be easy to add some in specific cases. Think 20/80 here to find a good balance. Let's not be contaminated by "classitis". And yes, bloat fighting is my hobby :) elv)
Also check this article, there is a section named "Finally: A comment on CSS development in Drupal" that explains why too many classes can be bad.

Bevan said:

We need revisions, diffs, and discussion pages on these wiki pages. without these it's very difficult to collaborate :( B/


Elv, Sorry I couldn't find

Bevan's picture

Elv, Sorry I couldn't find your user link. :(

He he!! 'classitis' -- nice word. I agree. Perhaps I was a little extreme in the way I expressed it. I think the place to stop with classes, is when they stop having meaning that other classes (in the same element or an ascendant element (parent, grandparent, ...)) don't already imply or classify. In this way I think classes are very similar to the taxonomy terms of a structured hierarchical vocabulary.

I read the bit about CSS and drupal markup in that article. My understanding was that the developers had trouble with the markup -- not the CSS classes. So I'm not sure how it applies to the idea that more classes (while still meaningful) are better than less classes. I agree that drupal's markup can sometimes be on the verbose side -- but I generally don't find it too verbose (with the exception of some contrib modules and themes). And I agree with his conclusion that

The only real sollution to the problem was simply to learn and to live with the Drupal style. It may not always be pretty, but if you spend enough time theming, you"ll eventually understand how to work with the code.

At the end of the day, a div with no css has no style. No borders, colors, margins or padding. It's just a plain vanilla block element. Therefore it shouldn't need to cause problems at theme level or even for a xml parser. At worst, extra divs might inherit (directly or indirectly, through ascendants) style. In this case, 'fixing' the div should just be a matter of removing that style.

I believe that is the ultimate goal of some recent discussion and patches -- to remove CSS that may be unwanted by a themer. Or at least make it easier to remove or override, by making it less specific and less brand/design oriented (i.e. less color and generally less CSS).

"At the end of the day, a

elv's picture

"At the end of the day, a div with no css has no style. No borders, colors, margins or padding. It's just a plain vanilla block element."
...unless it's styled by drupal.css :)

I also added a few things to the "rules" list.

Core vs contrib

elv's picture

I agree core modules generate much nicer code than the average contrib module.

<div id="block-block-1" class="clear-block block block-block"> looks weird but is perfectly correct.
The ID makes sense here as block-block-1 is a unique identifier. If you want to style this particular block only, you can use #block-block-1 {...}.
Without the ID you could use a CSS rule like .block-block-1, but you would also have to make sure it comes after the styles for all blocks (.block {...}).
Or use .block .block-block-1 to get a higher specificity, but then another rule like #sidebar-left .block {...} could override it.
This is a case where the ID is really convenient.

So I guess we should be careful when we say "As a general rule; don't use the id attribute".

3 div classes

elv's picture

To expand on the "3 classes" rule, I think the way blocks get their IDs/classes in core themes is nearly perfect :

Let's imagine foobar.module creates a block :
<div class="foobar block block-foobar" id="foobar-block-1">

  • with foobar class we can give styles to any element generated by foobar.module, whatever the type of element: a block, inserted div, you name it... It has the largest scope.

  • block is the element's type. So if you add styles for any block, they are also applied to this block.

  • block-foobar narrows the scope to only one kind of elements, here all the blocks that are generated by this particular module.
    Or should we use .foobar. block {...], instead of .block-foobar {...} ? This class is not absolutely required I guess.
    Edit: IE6 incorrectly handles multiple class declarations, see here, so this class is required.
    (Should we use block-foobar or foobar-block? I think I prefer foobar-block for consistency with the IDs)

  • foobar-block-1 is a unique ID and enables you to style this particular block easily, without the need to care too much about specificity. The way the ID is generated is key to ensure it's really unique, and including the type of element in the ID is great. An image block would then have an ID of foobar-image-1.
    (required only if multiple elements are possible, or always, just in case...?)

So far, the ID/class rules could be

most divs should have:

  • class: module_name, the module that generated the container - required - class="foobar"
  • class: object_type of object , e.g. node, menu, block..., module_name + object_type - required - class="menu"
  • class: module_name+object_type of object , e.g. node, menu, block... - required - class="foobar-menu"
  • ID: a unique identifier, module_name + object_type + unique_ID - optional? required? - id="foobar-block-5"
  • class: variation/permutation/state one or more class to further describe it, e.g. full/teaser/apple-tree/collapsed - optional - class="active expanded"

I just reviewed the section

Bevan's picture

I just reviewed the section on classes and made a few edits including what I discussed in my previous comments.


elv's picture

All this should be rewritten in two sections IMHO :
1. rules
2. further explanations for each rule

Rules should be clear and concise, there should not be too many rules, otherwise nobody will apply them (Isn't that what I also said about user interface rules during the UI meeting in Barcelona? :)

Attempt at rephrasing the rules list for classes:

  • As a general rule don't use IDs, use classes
  • Use classes on containers, not elements, unless necessary
  • Most divs should have three classes :
  1. what object it contains, e.g. node, user, block...
  2. what variation, permutation, or state it describes e.g. teaser, collapsed, active
  3. a unique identifier, where appropriate; e.g. node-123, block-15

* Semantic elements like <strong>, <em>, <p> usually don't need a class
* If you can't think of a class for the div, then you probably don't need it.

(I didn't include redundant rules, nor the ones about more/less classes, for now)

Hmmm. Maybe I'm not the

Bevan's picture

Hmmm. Maybe I'm not the technical writer I thought I could be.. :)

I didn't make it to BCN :(

I have a couple of deadlines to focus on this week, but hopefully I'll find time to come back to this later.


elv's picture

By the way, in the end everything should be re-written by a native english speaker, and not in broken english by a snail-eater like me :)

This Markup Style Guide

klaasvw's picture

This Markup Style Guide sounds great! Fantastic work so far.

One issue that really bugs me when theming is the abuse of general purpose HTML elements like span and div. I think it's important to stress the importance of semantics. So perhaps also include that divs or spans should only be used when there are no existing HTML elements fit for the type of data.


elv's picture

I agree. There is also a Microformats in Drupal group.

I wonder if this should be another "rule": use microformats or equivalent, if possible.

Element hierarchy

Crell's picture

Another important factor is the element hierarchy. Vis, when to use h1, h2, h3, etc. I started a preliminary set of rules at the bottom of the wiki page, based on what I understand to be the de facto standard currently. Modify as needed.


elv's picture

What do you call "site-title"? If it's the website's name, like "Drupal" on drupal.org, I'd tend to disagree. There's hardly a consensus on this topic, it's a bit like OOP or not in Drupal Core :) And in the HTML specs, headings are supposed to indicate a level of importance, not a hierarchy. It's tempting to use them as a site hierarchy, but they're really not good for this purpose.

On simple sites, the name of the website could well be the "top element", like a (paper) book title, if the site focuses on a single topic. Then an H1 would suit.
But on complex/social/community sites with lots of documents and sections it's a bit different. Is a page in Corporate > About Us > Our Team supposed to begin with an H4?
On Drupal.org and most big websites the hierarchy is materialized by menus, breadcrumb, URLs, not by the headings.

We must also keep in mind a page can be displayed out of it's original context (as a forum topic, promoted on the home page, inserted in a Drupal "book"...).
So IMHO it's safer to use H1 as the top element of the current "content", "content" being any page/node/$content/taxonomy list.
The home page could be an exception, but I wonder if the benefit is worth the theming and templating work.

Also nothing forbids to use several H1s in a page, and it could sometimes make sense, like in a list of nodes (taxonomy or views list). But I agree that inside a particular "content", the top-most heading should be unique.

page structure, not site structure

JohnAlbin's picture

Since Drupal wikis don’t provide revisions, I don’t know for certain what Larry added to the Markup Style Guide. But let me quote what it says currently:

Page structure

  • The site-title should use an <h1> tag. No other element on the page should use that tag.
  • The page-title should use an <h2> tag. No other element on the page should use that tag.
  • Sub-headings within the content body should use an <h3> tag.

I don’t see anything in the above words that would mean Heading tags should be used for site hierarchy. Phillippe, perhaps you missed the “Page structure” heading (which ironically wasn’t a heading) and misinterpreted "content body should use an <h3> tag” to mean that a site’s content should use h3 tags. I've edited it “the page’s content body” as I’m sure that’s what is meant.

Advocating that section pages should start with h2 and sub-section pages should start with h3 is just silly.

  - John (JohnAlbin)

  - John (JohnAlbin)


elv's picture

I probably went a bit too far :)
I thought, if you try to maintain a strict header hierarchy in any page starting from the site's name, then you have to enforce it through the whole site so you won't end up having a page like a node list with H2s both as the page title AND the listed node's titles. Or even a page title in an H2, and listed nodes as H1s.

On the other hand if you consider headings just indicate a level of importance, it doesn't matter if the page title is an H2 and the listed nodes titles are H1s. They are probably really more important that the name of the list itself.

Backward compatible (horrors!)

Crell's picture

I put h1: site, h2: page, and h3: subsection in as a starting point because that's what most themes do currently, AFAIK. It seemed like a good starting point.

Moving things down a level to page-title as h1 and subsections as h2 makes some sense, but that's going to change a lot of existing theme logic as well as impact search indexes. We would also then need to come up with a different standard (div with some special class?) for the site-title, which should be standardized to something, whatever it is.


elv's picture

I checked in D6 beta 2: Garland and Bluemarine have h1 for both site name and page title, Pushbutton has h1 for page titles only and a class for site name. Only Chameleon has the headers you suggest, but it's not a PHPTemplate theme (is Chameleon considered legacy?). Contrib theme can use headers any way they want imho, if they don't like how it's done in core themes they're free to do it another way.

So the best answer is probably "it depends on both content and context". But still we have to choose a consistent way to do it, even if it's a bit arbitrarily.

I think I've read every bit about this during the last years, looked at the source code of thousands of websites, and couldn't get a consensus from that.
Even if you look at famous standards supporting websites you'll find several takes on it:

  • W3C uses h1 for page titles (except on the home page where it's on the logo/site name)
  • WebStandards.org uses H1 for site name and H2 for page titles
  • A list Apart uses h1s for both site name AND page title.

So which one is the best compromise for Drupal?
Personally I prefer the W3C way for a fews reasons, but it requires an if statement (are we on front or not?). Should we keep things simple and use the same headings on all pages?

Old code

Crell's picture

Hm. Looks like that did change from Drupal 5 to Drupal 6. I just updated the guide to follow what the default page.tpl.php and block.tpl.php templates do. Whatever the standard is, those templates should match it. (And it's probably too late to change those templates anyway, esp. as they were designed with CSS-only themes in mind.)

The use of h1 tags

JohnAlbin's picture

I have to agree with Philippe about the best practices for h1 tags.

Let me quote from the HTML 4.01 spec:

A heading element briefly describes the topic of the section it introduces. … There are six levels of headings in HTML with H1 as the most important and H6 as the least.

The site title does not introduce a section of the page. It's more of a “you are here” marker (related to breadcrumbs.)

Also, from a Search Engine Optimization point-of-view, the site title is already in the <title> tag and doesn’t need double emphasis.

The most important heading in a particular page is the content body’s title. And that heading should get the h1 tag.

On the homepage, the content body’s title and the site title are often (but not always) one and the same. And that’s the only time I see the site title getting an H1 tag.

  - John (JohnAlbin)

  - John (JohnAlbin)

Couldn't agree more

jessebeach's picture

The content title should always be wrapped in the h1 (HTML4) and in an h1 (HTML5).

This will also make a transition to HTML5-geared templates smoother.

Yes and, um, no

Cliff's picture

The content body's title does, indeed, get the H1 according to best practices. But as for:

Also, from a Search Engine Optimization point-of-view, the site title is already in the <title> tag and doesn’t need double emphasis.

Um, not exactly. As I enter this reply, I am on a page that displays "Groups.Drupal" as the site title. But if I view the source code, I see this:
<title>Reply to comment | groups.drupal.org</title>
And that is as it should be. The content of the <title> tag for any page should be the title of that page, not the name of the site. (The name of the site should follow the title of the page.)

John, I realize that you might have meant precisely that — that the site title appears after the content title in each page's <title> tag. But your comment could be read to mean that only the site title, and not the title of the page's contents, should appear in each page's <title> tag. Just clarifying for those who might not know.

Class uniqueness

sun's picture

The module-name should be a class on the root DOM element of each theme_*() function: class "tagadelic" on the div containing the tagadelic block, but not necessarily it's descendants, which can be targeted using ascending elements' class/es.
Use classes on containers, not on elements. /elv

This one could lead to false assumptions. Recently, I had to handle some ill styles of the TrackBack module, displayed in a block:

<div id="block-trackback-1" class="block block-trackback">
div class="title"><h3>Trackbacks</h3></div>
div class="content">
div id="trackbacks">
div class="trackback" id="trackback-2">
div class="title"><a href="URL">SITE</a></div>
div class="author">from <em>NAME</em> on <em>DATE</em></div>
div class="content"><p>Some content...</p></div>
div class="links">
ul class="links">
li class="first trackback_edit"><a href="/admin/content/trackback/edit/2" class="trackback_edit">Edit</a></li>

As you can see, the second .content DIV would adhere to above rule. However, most themes apply styles to meta-regions like .block .content that would be applied twice here (because CSS2's .block>.content is not supported by all browsers). Personally, I prefer to prefix any possible ambiguous names with the module name to avoid such conflicts, for example .trackback-content.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
unleashed mind

too strict?

jessebeach's picture

Sun, I definitely agree the .content .content issue is annoying and pops up frequently. Do you see the scoping of module classes with module name prefixes something that would be done in addition to the generic class names, like .author and .date and such? Otherwise, I see a potential for lots of duplication e.g.

.node-author {
  font-style: italic;

where something like

.author {
  font-style: italic;

would be preferred.

XHTML 1.0 STRICT only?

sreynen's picture

The style guide says "XHTML 1.0 STRICT should be the standard," yet there's one HTML5 theme in CVS, and my custom HTML5 themes seem to validate just fine. As HTML5 (including XHTML5, which is almost entirely backwards compatible with XHTML 1) moves closer and closer to the recommended markup format of the W3C, I think it's worth clarifying whether or not it meets Drupal coding standards. I see no reason it shouldn't, and suggest changing that line to something like: "XHTML 1.0 STRICT is the Drupal default; any valid DOCTYPE is acceptable."

is this wiki page a stub?

momper's picture

is there another place, where the general theming discussions take place?

the suggestion i want to place:

only use PNG as image format (for example for icons) - no GIFs anymore ...