For HTML 4, the answer is technically:
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
HTML 5 is even more permissive, saying only that an id must contain at least one character and may not contain any space characters.
The id attribute is case sensitive in XHTML.
As a purely practical matter, you may want to avoid certain characters. Periods, colons and '#' have special meaning in CSS selectors, so you will have to escape those characters using a backslash in CSS or a double backslash in a selector string passed to jQuery. Think about how often you will have to escape a character in your stylesheets or code before you go crazy with periods and colons in ids.
For example, the HTML declaration <div id="first.name"></div>
is valid. You can select that element in CSS as #first\.name
and in jQuery like so: $('#first\\.name').
But if you forget the backslash, $('#first.name')
, you will have a perfectly valid selector looking for an element with id first
and also having class name
. This is a bug that is easy to overlook. You might be happier in the long run choosing the id first-name
(a hyphen rather than a period), instead.
You can simplify your development tasks by strictly sticking to a naming convention. For example, if you limit yourself entirely to lower-case characters and always separate words with either hyphens or underscores (but not both, pick one and never use the other), then you have an easy-to-remember pattern. You will never wonder "was it firstName
or FirstName
?" because you will always know that you should type first_name
. Prefer camel case? Then limit yourself to that, no hyphens or underscores, and always, consistently use either upper-case or lower-case for the first character, don't mix them.
A now very obscure problem was that at least one browser, Netscape 6, incorrectly treated id attribute values as case-sensitive. That meant that if you had typed id="firstName"
in your HTML (lower-case 'f') and #FirstName { color: red }
in your CSS (upper-case 'F'), that buggy browser would have failed to set the element's color to red. At the time of this edit, April 2015, I hope you aren't being asked to support Netscape 6. Consider this a historical footnote.
2015 update: the flexbox approach
There are two other answers briefly mentioning flexbox; however, that was more than two years ago, and they don't provide any examples. The specification for flexbox has definitely settled now.
Note: Though CSS Flexible Boxes Layout specification is at the Candidate Recommendation stage, not all browsers have implemented it. WebKit implementation must be prefixed with -webkit-; Internet Explorer implements an old version of the spec, prefixed with -ms-; Opera 12.10 implements the latest version of the spec, unprefixed. See the compatibility table on each property for an up-to-date compatibility status.
(taken from https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes)
All major browsers and IE11+ support Flexbox. For IE 10 or older, you can use the FlexieJS shim.
To check current support you can also see here:
http://caniuse.com/#feat=flexbox
Working example
With flexbox you can easily switch between any of your rows or columns either having fixed dimensions, content-sized dimensions or remaining-space dimensions. In my example I have set the header to snap to its content (as per the OPs question), I've added a footer to show how to add a fixed-height region and then set the content area to fill up the remaining space.
html,
body {
height: 100%;
margin: 0;
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 auto;
/* The above is shorthand for:
flex-grow: 0,
flex-shrink: 1,
flex-basis: auto
*/
}
.box .row.content {
flex: 1 1 auto;
}
.box .row.footer {
flex: 0 1 40px;
}
<!-- Obviously, you could use HTML5 tags like `header`, `footer` and `section` -->
<div class="box">
<div class="row header">
<p><b>header</b>
<br />
<br />(sized to content)</p>
</div>
<div class="row content">
<p>
<b>content</b>
(fills remaining space)
</p>
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>
In the CSS above, the flex property shorthands the flex-grow, flex-shrink, and flex-basis properties to establish the flexibility of the flex items. Mozilla has a good introduction to the flexible boxes model.
Best Answer
Most of the roles you see were defined as part of ARIA 1.0, and then later incorporated into HTML via supporting specs like HTML-AAM. Some of the new HTML5 elements (dialog, main, etc.) are even based on the original ARIA roles.
http://www.w3.org/TR/wai-aria/
There are a few primary reasons to use roles in addition to your native semantic element.
Reason #1. Overriding the role where no host language element is appropriate or, for various reasons, a less semantically appropriate element was used.
In this example, a link was used, even though the resulting functionality is more button-like than a navigation link.
Screen readers users will hear this as a button (as opposed to a link), and you can use a CSS attribute selector to avoid class-itis and div-itis.
[Update 7 years later: removed the * selector to make some commenters happy, since the old browser quirk that required universal selector on attribute selectors is unnecessary in 2020.]
Reason #2. Backing up a native element's role, to support browsers that implemented the ARIA role but haven't yet implemented the native element's role.
For example, the "main" role has been supported in browsers for many years, but it's a relatively recent addition to HTML5, so many browsers don't yet support the semantic for
<main>
.This is technically redundant, but helps some users and doesn't harm any. In a few years, this technique will likely become unnecessary for main.
Reason #3. Update 7 years later (2020): As at least one commenter pointed out, this is now very useful for custom elements, and some spec work is underway to define the default accessibility role of a web component. Even if/once that API is standardized, there may be need to override the default role of a component.
Note/Reply
You also wrote:
That's an allowed use of the attribute unless a real role is not included. Browsers will apply the first recognized role in the token list.
Out of the list, only
link
andnote
are valid roles, and so the link role will be applied in the platform accessibility API because it comes first. If you use custom roles, make sure they don't conflict with any defined role in ARIA or the host language you're using (HTML, SVG, MathML, etc.)