Вы здесь

Кодирование HTML и CSS

Создание правильного кода

Весь CSS-код должен проходить проверку на соответствие стандартам, предпочтительнее CSS 2.1. Допустимо соответствие стандарту CSS 3.0, если его использование оправданно. Терминология, используемая в этом стандарт:

селектор {
  свойство: значение;
}

Селекторы

  • Размещайте селекторы на отдельных строках
  • Отделяйте селектор от открывающей фигурной скобки пробелом
  • Размещайте закрывающую фигурную скобку на отдельной строке (без отступа)
  • Отделяйте группы логически связанных селекторов пустой строкой

.book-navigation .page-next {
}
.book-navigation .page-previous {
}

.book-admin-form {
}

Использование нескольких селекторов

При использовании нескольких селекторов, каждый из них располагается на новой строке.

#forum td.posts,
#forum td.topics,
#forum td.replies,
#forum td.pager {

Свойства

  • Каждое свойство начинается с новой строки и использует отступ в два пробела
  • Значение свойства отделяется от его названия одним пробелом
  • Каждой свойство заканчивается точкой с запятой (включая последнее)

#forum .description {
  color: #efefef;
  font-size: 0.9em;
  margin: 0.5em;
}

Упорядочивание свойств по алфавиту

Несколько свойств в одном селекторе перечисляются в алфавитном порядке. Значение цвета предпочтительнее писать в нижнем регистре (особенно HEX-значения).

Правильно:

body {
  background: #000;
  color: #fff;
  font-family: helvetica, sans-serif;
  font-weight: normal;
}

Неправильно:

body {
  font-weight: normal;
  background: #000;
  font-family: helvetica, sans-serif;
  color: #FFF;
}

Использование в свойстве нескольких значений

При использовании в свойстве нескольких значений, они отделяются друг от друга пробелом после запятой.

  font-family: helvetica, sans-serif;

CSS3 properties, vendor prefixes, progressive enhancement

  • Order all properties alphabetically.
  • Group vendor-specific with their respective standard CSS3 properties.
  • Order vendor-specific properties alphabetically.
  • Declare vendor-specific properties before standard properties.
  • Declare potentially unsupported values after known to be supported values (progressive enhancement). (see w3.org/TR/2009/CR-CSS2-20090908/syndata.html#unsupported-values)

The special case of filter: should be grouped with ms-filter: and ordered before it (as in above example).

Vendor specific extensions may cause browser inconsistencies when declaring CSS3 before the standard has reached recommended status (a.k.a. finalized). Do not take for granted that a -vendor-xyz-property is and works the same as the final xyz-property.

.progressive-enhancement {
  background: #000 none;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#E5000000,endColorstr=#E5000000);
  background-color: rgba(0, 0, 0, 0.9);
}
.progressive-prefixes {
  background-color: #003471;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#003471), to(#448CCB));
  background-image: -webkit-linear-gradient(top, #003471, #448CCB);
  background-image: -moz-linear-gradient(top, #003471, #448CCB);
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00003471,endColorstr=#00448CCB);
  background-image: -ms-linear-gradient(top, #003471, #448CCB);
  background-image: -o-linear-gradient(top, #003471, #448CCB);
  background-image: linear-gradient(to bottom, #003471, #448CCB);
}
.vendor-prefixes {
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
  -moz-box-shadow: 0 3px 20px #000;
  filter: progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10');
  -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10')";
  -webkit-box-shadow: 0 3px 20px #000;
  box-shadow: 0 3px 20px #000;
}

It is recommended to avoid features of proprietary vendor extensions that are not supported by CSS3 standards.

Комментирование кода

В общем, все комментарии должны следовать стандарту Doxygen, чтобы оставаться совместимыми со всем остальным кодом Друпала. В случаях, когда общий стандарт не может быть применён, мы прибегаем к CSSDoc syntax (draft): cssdoc.net/wiki/DocBlock.

Файлы CSS должны использовать комментарии в соответствии с правилами CSSdoc. Комментарий идёт перед кодом, к которому он относиться. Блок/секция кода комментируется также, как в PHP.

/**
* Documentation here.
*/

Короткий комментарий может быть добавлен после свойства, отделённым от него пробелом:

  background-position: 0.2em 0.2em; /* LTR */
  padding-left: 2em; /* LTR */

Письмо справа налево

Друпал поддерживает загрузку .css-файлов по условиям, которые могут переопределять правила для языков с направлением письма справа налево. В модулях, правило переопределения должно быть определено подобным названием файла: MODULE-rtl.css, например, node-rtl.css. В темах, правило переопределения должно быть определено подобным названием файла: style-rtl.css. Правила переопределения могут быть также закомментированы в стандартном файле стилей вашей темы. Из файла node-rtl.css:

#node-admin-buttons {
  clear: left;
  float: right;
  margin-left: 0;
  margin-right: 0.5em;
}

Правила node.css, которые будут переопределены, если файл загружен файл rtl.css:

#node-admin-buttons {
  clear: right; /* LTR */
  float: left; /* LTR */
  margin-left: 0.5em; /* LTR */
}

Смотрите также: drupal.org/node/132442#language-rtl

Если вы определяете свойства для языка использующего письмо справа налево, то добавляйте комментарий /* LTR */ в файл стилей вашей темы в случаях:

  • Когда используете в свойстве значения left или right (например, float: left;)
  • Когда используете неравные значения полей, выступов или границ элемента (например, margin-left: 1em; margin-right: 2em;)
  • Когда определяете направление языка (например, direction: ltr;)

This guide is intended to tell all Drupal developers how to

  • Create good HTML/markup
  • Create good base templates for themers to stylize
  • Create good CSS classes

This guide is not intended to tell Drupal developers how their applications should look -- that would be a design guide or an interface guide. This guide is only intended to explain the considerations how to create HTML, templates and CSS that are easy for a themer to deal with.
This guide will serve as a basis for creating patches to Drupal 7 that will standardize the HTML and CSS classes.

ID

As a general rule; don't use the id attribute.

Unless you are absolutely 100% sure that your template file or theme function will only be called once per user-request, then your ID might cause the markup not to validate (the value must be unique to every other DOM element's id in the whole DOM tree).

That means, don't use the id attribute on templates of nodes and users and even common forms like search and login forms. Even if you include the object ID in the id attribute. You, as a developer, can not guarantee that particular node, form or user will only be on the page once. Remember that views and panels can pull lots of stuff into blocks and pages.

If you need an ID for javascript, consider refactoring the javascript to use a class. If that is not an option then run the id through a static incrementer so that it gets an indexing integer appended to it; #your-id-0, your-id-1, #your-id-2, etc. See how the zen theme does this with zen_id_safe(). (This function should really go into core for d7 -- search and/or open a ticket please someone. Please see also drupal.org/node/111719)

Classes

Remember that id of the id="" attribute stands for identifier, while class in the class="" attribute stands for classifiers. So CSS classes are just taxonomy terms for DOM elements!

Rules of thumb for module developers;

  • every div must have at least one identifying class.
  • most divs should have three;
    • what object it contains, e.g. node/user/message/tree
    • what variation/permutation/state of that object/markup it contains e.g. full/teaser/node-typ/apple-tree/collapsed
    • a unique identifier, where appropriate; e.g. node-123/tree-456
  • 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. Rephrasing: Use classes on containers, not on elements. /elv
  • use more classes if they provide a further classification that other classes have not covered, and are not inherited by ancestral DOM elements. (I wonder if this is necessary, when is a class not inherited? /elv)
  • the name of the theme token, vis, theme('foo') would be wrapped in a div of class "foo". (<- where? is a class on the body element enough? Is this really needed as website usually use only one theme?)
  • strings always make better identifiers than integers. (seems redundant with the "most divs should have three" rule)
  • it's better to have too many classes than not enough, as long as they have unique meaning not already defined or implied by other classes in the element or on of it's ascendants
  • elements that aren't divs usually follow the same rules as above -- with the exception of extremely explicit elements like <strong>, <em>, <p> etc. If they are used correctly then they normally wouldn't need any/many classes.
  • to indicate variation/state, use the class on the outermost element. ie: on a list of link use "active" on the <li>, not on the <a> (This is now the case in Drupal 6 core menus). (redundant with rule 3?)
  • if you can't think of a class for the div, then you probably shouldn't have a div for it. (However divs are usually useful to themers (better too many than not enough), so first try harder to think of a meaningful class.)

Examples; A div wrapping a teaser might have class="node teaser blog-node node-123". The apple tree in the example might have class="tree apple-tree ready-for-picking tree-456"

Check out the html5 spec for motivation as to what classes might be useful;

  • W3C working draft: whatwg.org/specs/web-apps/current-work/">W3C working draft
  • IBM's article (ibm.com/developerworks/library/x-html5/) sums it up better than reading the draft could. Just looking at the example's will give you a good enough idea of what it's all about.
  • This view on the Working Draft (simon.html5.org/html5-elements) might be useful.

Markup

Spans vs. Divs

Spans and Divs have default properties that you should bear in mind:

  • A span works in-line.
  • A div works as a block element.

In other words, spans can be used to affect styling of content without taking it out of its place in the flow (e.g., for targeting a phrase or piece of jargon within a sentence). On the other hand, divs operate as block elements by default, and thus are best used to define page content that should be handled as a block somehow distinct from its surrounding content (e.g., the node and block divs that are generated in core Drupal).

Use the regular mark-up before using a div or span

When you can avoid it, don't add a div or span to an element already defined in the mark-up. Instead, simply add a class or id, as appropriate (see above), to the existing element. For example:

Don't:

<div class="foo-title"><h2>example</h2></div>

Do:

<h2 class="foo-title">example</h2>

Don't:

<div class="foo-box"><p>example</p></div>

Do:

<p class="foo-box">example</p> [in this case if it's all in one paragraph]

Don't:

<span class="foo-link"><a href="foo">example</a></span>

Do:

<a href="foo" class="foo-link">example</a>

If you're in doubt, put it in a div (and give it classes)

Don't leave content adrift on the page with no mark-up at all. Every chunk of html whether in a tpl file or a theme function should have a root DOM element. For module developers this is a div 95% of the time. In page.tpl.php it's the element. (or ?)

<?php
<div class="stuff stuff-summary stuff-ID your-module-name ">
  <!--
summary of your stuff here -->
</
div>
?>

Each chunk of cohesive html gets it's own containing element.

<?php
<div class="stuff stuff-summary stuff-ID your-module-name ">
  <
div class="stuff-name">This is some stuff</div>
  <
div class="stuff-summary">
    <
div class="stuff-description">Here is the stuff that I need to plant, grow and pick my apple tree</div>
    <
ul class="stuff-items">
      <
li>apple seeds</li>
      <
li>pitchfork</li>
      <
li>ladder</li>
    </
ul>
  </
div>
</
div>
?>

Wrap dynamic values in sentences in inline element (span, strong, a).

<?php
<p>Posted by <a href="/user/123">Johnny Appleseed</a> on <span class="date yesterday">1 October 2007</span></p>
?>

Leave out presentation formatting

In the interest of maintaining the separation of logic and presentation, and moving all formatting control to the theming layer, avoid using presentation mark-up like and . Not only are these deprecated tags, they force formatting that may not be appropriate in all contexts. Better to use <strong>, <em> or even <span> to provide handles to themers for distinct stylings.

Page structure

  • The site-title should use an <h1 id="site-name"> tag. No other element on the page should use that tag.
  • The page-title should use an <h1 class="title" id="page-title"> tag. No other element on the page should use that tag.
  • Sub-headings within the page's content body should use an <h2> tag.
  • Block titles should use an <h2> tag.

Validation

Before publishing your theme to Drupal.org validate your site:

  • W3C's CSS Validator (jigsaw.w3.org/css-validator/) - CSS 2.1 should be the standard unless it is for an experimental theme
  • W3C's HTML Validator (validator.w3.org) - XHTML 1.0 STRICT should be the standard
  • WAVE Web Accessibility Evaluation Tool (webaim.org) - identified accessibility issues should be removed

Tables

Tables shall not be used for structure, only for tabular data output.