User:Frank Ralf/Moodle HTML

Jump to: navigation, search

A after posting "Table Layouts vs. Div Layouts: From Hell to… Hell?" and starting a discussion on "Semantic DIV IDs?" I think it is worth digging deeper into this topic.
Any comments welcome! -- Frank

Read the whole story:

  1. Site Admin Block: "Look Ma, (nearly) no DIVs!"
  2. Site Admin Block: Better image placement
  3. Course Categories - The Ugly Duckling
  4. Course Categories - Clearing the Tables
  5. formslib - Checkboxes: A Case of "Divitis"?


Anatomy of Site Admin Block

This is the original code for the Site Admin block plus some additional HTML to make the code valid and viewable in a browser. (For the time being all examples are only tested using Firefox 3.)

This is a static HTML snapshot, created by using the browser's "Save page as..." function. The code, including the necessary CSS and image files, is available here: Site_Administration_2-0_Open_3.zip.

Screenshot of original block

The Site Admin menu block should look like this:

Site Adminstration-Open.png

Original block with CSS turned off

And so the block looks with CSS turned off. Note that the nesting of the menu is gone. And the "Skip" link is visible, and important accessibility feature.

Site Adminstration Original without CSS.png

The original code

<html>
<head>
<title>Site Administration - Open</title>
<link rel="stylesheet" type="text/css" href="styles.css"></link>
<link rel="stylesheet" type="text/css" href="styles_002.css"></link>
</head>
<body >
<h1>Moodle 2.0 - Site Administration (open) - Original Code</h1>
<table>
 
<!-- Begin of original Moodle code -->
 
<td style="width: 210px;" id="left-column">
<a href="#sb-1" class="skip-block">Skip Site Administration</a>
 
<div id="inst2" class="block_admin_tree sideblock">
<div class="header">
<div class="title">
<h2>Site Administration</h2>
</div>
</div>
 
<div class="content">
<div class="admintree">
 
<div class="depth0"><a class="link" href="admin/index.php"><img src="pix/item.gif" alt="">Notifications</a></div>
<div class="depth0"><a class="link" href="admin/register.php"><img src="pix/item.gif" alt="">Registration</a></div>
<div class="depth0"><a class="link" href="admin/settings.php?section=optionalsubsystems"><img src="pix/item.gif" alt="">Advanced features</a></div>
<div class="depth0"><a href="#" name="d1"><img id="vh_div1indicator" src="pix/closed.gif" alt="Closed folder"> Users</a></div><span id="vh_div1"></span>
<div class="depth0"><a href="#" name="d5"><img id="vh_div5indicator" src="pix/closed.gif" alt="Closed folder"> Courses</a></div><span id="vh_div5"></span>
<div class="depth0"><a href="#" name="d6"><img id="vh_div6indicator" src="pix/closed.gif" alt="Closed folder"> Grades</a></div><span id="vh_div6"></span>
<div class="depth0"><a href="#" name="d8"><img id="vh_div8indicator" src="pix/closed.gif" alt="Closed folder"> Location</a></div><span id="vh_div8"></span>
<div class="depth0"><a href="#" name="d9"><img id="vh_div9indicator" src="pix/closed.gif" alt="Closed folder"> Language</a></div><span id="vh_div9"></span>
<div class="depth0"><a href="#" name="d10"><img id="vh_div10indicator" src="pix/closed.gif" alt="Closed folder"> Plugins</a></div><span id="vh_div10"></span>
<div class="depth0"><a href="#" name="d16"><img id="vh_div16indicator" src="pix/closed.gif" alt="Closed folder"> Security</a></div><span id="vh_div16"></span>
<div class="depth0"><a href="#" name="d17"><img id="vh_div17indicator" src="pix/open.gif" alt="Opened folder"> Appearance</a></div><div id="vh_div17">
 
<div class="depth1"><a href="#" name="d18"><img id="vh_div18indicator" src="pix/open.gif" alt="Opened folder"> Themes</a></div><div id="vh_div18">
 
<div class="depth2"><a class="link" href="admin/settings.php?section=themesettings"><img src="pix/item.gif" alt="">Theme settings</a></div>
<div class="depth2"><a class="link" href="theme/index.php"><img src="pix/item.gif" alt="">Theme Selector</a></div></div>
 
<div class="depth1"><a class="link" href="admin/settings.php?section=calendar"><img src="pix/item.gif" alt="">Calendar</a></div>
<div class="depth1"><a href="#" name="d19"><img id="vh_div19indicator" src="pix/closed.gif" alt="Closed folder"> HTML editor</a></div><span id="vh_div19"></span>
<div class="depth1"><a class="link" href="admin/settings.php?section=htmlsettings"><img src="pix/item.gif" alt="">HTML settings</a></div>
<div class="depth1"><a class="link" href="admin/settings.php?section=documentation"><img src="pix/item.gif" alt="">Moodle Docs</a></div>
<div class="depth1"><a class="link" href="admin/settings.php?section=mymoodle"><img src="pix/item.gif" alt="">My Moodle</a></div>
<div class="depth1"><a class="link" href="admin/settings.php?section=coursemanager"><img src="pix/item.gif" alt="">Course managers</a></div>
 
<div class="depth1"><a class="link" href="admin/settings.php?section=ajax"><img src="pix/item.gif" alt="">AJAX and Javascript</a></div>
<div class="depth1"><a class="link" href="tag/manage.php"><img src="pix/item.gif" alt="">Manage tags</a></div></div>
 
<div class="depth0"><a href="#" name="d20"><img id="vh_div20indicator" src="pix/closed.gif" alt="Closed folder"> Front Page</a></div><span id="vh_div20"></span>
<div class="depth0"><a href="#" name="d21"><img id="vh_div21indicator" src="pix/closed.gif" alt="Closed folder"> Server</a></div><span id="vh_div21"></span>
<div class="depth0"><a href="#" name="d22"><img id="vh_div22indicator" src="pix/closed.gif" alt="Closed folder"> Reports</a></div><span id="vh_div22"></span>
<div class="depth0"><a href="#" name="d23"><img id="vh_div23indicator" src="pix/closed.gif" alt="Closed folder"> Development</a>
 
</div>
 
<div class="footer">
<div class="adminsearchform">
<form action="http://admin/search.php" method="get">
<div>
<label for="query" class="accesshide">Search in settings</label>
<input name="query" id="query" size="8" value="" type="text">
<input value="Search" type="submit">
</div>
</form>
</div>
</div>
 
</div>
</div>
<span id="sb-1" class="skip-block-to"></span>
</div>
 
</td>
 
<!-- End of original Moodle code -->
</body>
</html>

Discussion: The good, the bad, and the ugly

  1. <td style="width: 210px;" id="left-column">
  2. <div class="depth0">
  3. <a href="#" name="d1">
  4. <img id="vh_div1indicator" src="pix/closed.gif" alt="Closed folder">
  5. Users</a></div>
  6. <span id="vh_div1"></span>
  7. <div class="depth2">
  8. <a class="link" href="admin/settings.php?section=themesettings">
  9. <img src="pix/item.gif" alt="">
  10. Theme settings</a></div>
  • Table with inline styles
  • No use of nested lists (semantic HTML)
  • No semantic ids
  • Repetitive information in "name" and "id" attributes ("name" should be replaced by "id" in XHMTL, see http://www.w3schools.com/Xhtml/xhtml_syntax.asp) probably only kept for backward compatability
  • Empty (unnecessary) <span> tags
  • Inline images instead of list markers or background images via CSS
  • No empty (null) ALT attributes for images without meaning
  • Superfluous class of "link" for <a> tags.
  • "Skip navigation" link is good practice for accessibility.


Some general rules of thumb

  • DIV and SPAN are generic (block and inline) elements with no semantic meaning.
  • As such they should be used as sparsely as possible.
  • There's no need to wrap single elements in DIV or SPAN tags:

Example: Title

<div class="header">
<div class="title">
<h2>Site Administration</h2>
</div>
</div>

This could be reduced to

<div class="header">
<h2 class="title">Site Administration</h2>
</div>

with attaching the class directly to the H2 tag (which already is a block element).

And as long as the Header DIV only contains one element this could very well be stripped down to

<h2>Site Administration</h2>

as the class "title" doesn't enhance the semantics of a H2 heading or perhaps to

<h2 class="header">Site Administration</h2>

which would provide the context (Header) for the H2 heading.

Example: Search form

The same goes for the search form in the footer. FORM is also already a block element therefore no additional DIV is needed:

Instead of

<div class="adminsearchform">
<form action="http://admin/search.php" method="get">
</div>

we could write:

<form class="adminsearchform" action="http://admin/search.php" method="get">

Semantic HTML: "Look Ma, (nearly) no DIVs!"

Some general notes:

  • We will delete a lot of unnecessary tags, classes, ids, and other attributes. Some of those might be used by some AJAX features. However, for accessibility reasons the code should work without them. In a later stage we will show how to add those features using JavaScript (see Development:Unobtrusive Javascript).
  • We will leave the included CSS files untouched. Instead, we will add our CSS directly to the head section of the HTML file. So you can just copy & paste the HTML, save it as a file, and put it in the same folder as the original HTML file. No further downloads needed.


The modified code: Semantic HTML 1.0

Here's the code:

<html>
<head>
<title>Site Adminstration - Open</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
<link rel="stylesheet" type="text/css" href="styles_002.css" />
 
<style type="text/css">
<!--
li {
color: red;
}
=-->
</style>
 
</head>
<body >
 
<h1>Moodle - Semantic HTML 1.0</h1>
 
<table>
 
<!-- Begin of original Moodle code -->
<td style="width: 210px;" id="left-column">
<a href="#sb-1" class="skip-block">Skip Site Administration</a>
<div id="inst2" class="block_admin_tree sideblock">
 
<h2 class="header" >Site Administration</h2>
 
<div class="content">
 
<ul class="admintree">
 
<li><a href="admin/index.php"><img src="pix/item.gif" alt="">Notifications</a></li>
<li><a href="admin/register.php"><img src="pix/item.gif" alt="">Registration</a></li>
<li><a href="admin/settings.php?section=optionalsubsystems"><img src="pix/item.gif" alt="">Advanced features</a></li>
 
<li><a href="#"><img src="pix/closed.gif" alt="">Users</a></li>
<li><a href="#"><img src="pix/closed.gif" alt="">Courses</a></li>
<li><a href="#"><img src="pix/closed.gif" alt="">Grades</a></li>
<li><a href="#"><img src="pix/closed.gif" alt="">Location</a></li>
<li><a href="#"><img src="pix/closed.gif" alt="">Language</a></li>
<li><a href="#"><img src="pix/closed.gif" alt="">Plugins</a></li>
<li><a href="#"><img src="pix/closed.gif" alt="">Security</a></li>
<li><a href="#"><img src="pix/open.gif" alt="">Appearance</a>
 
<ul>
<li><a href="#"><img src="pix/open.gif" alt="">Themes</a>
<ul>
<li><a href="admin/settings.php?section=themesettings"><img src="pix/item.gif" alt="">Theme settings</a></li>
<li><a href="theme/index.php"><img src="pix/item.gif" alt="">Theme Selector</a></li>
</ul>
</li>
 
<li><a href="admin/settings.php?section=calendar"><img src="pix/item.gif" alt="">Calendar</a></li>
<li><a href="#"><img src="pix/closed.gif" alt=""> HTML editor</a></li>
<li><a href="admin/settings.php?section=htmlsettings"><img src="pix/item.gif" alt="">HTML settings</a></li>
<li><a href="admin/settings.php?section=documentation"><img src="pix/item.gif" alt="">Moodle Docs</a></li>
<li><a href="admin/settings.php?section=mymoodle"><img src="pix/item.gif" alt="">My Moodle</a></li>
<li><a href="admin/settings.php?section=coursemanager"><img src="pix/item.gif" alt="">Course managers</a></li>
<li><a href="admin/settings.php?section=ajax"><img src="pix/item.gif" alt="">AJAX and Javascript</a></li>
<li><a href="tag/manage.php"><img src="pix/item.gif" alt="">Manage tags</a></li>
</ul>
</li>
 
<li><a href="#"><img src="pix/closed.gif" alt=""> Front Page</a></li>
<li><a href="#"><img src="pix/closed.gif" alt=""> Server</a></li>
<li><a href="#"><img src="pix/closed.gif" alt=""> Reports</a></li>
<li><a href="#"><img src="pix/closed.gif" alt=""> Development</a></li>
 
</ul>
 
<div class="footer">
<form class="adminsearchform" action="http://admin/search.php" method="get">
<label for="query" class="accesshide">Search in settings</label>
<input name="query" id="query" size="8" value="" type="text">
<input value="Search" type="submit">
</form>
</div>
 
</div>
 
<span id="sb-1" class="skip-block-to"></span>
</div>
</td>
 
<!-- End of original Moodle code -->
</body>
</html>

Screenshots: Semantic HTML 1.0

The block should look like this. Note: We added the red color for the list markers (by the browser) only to distinguish them from the original ones (images).

Moodle Semantic-HTML 1.0.png

And so with CSS turned off. Note that the indentation is kept.

Moodle Semantic-HTML 1.0 without CSS.png

What we did:

  • converted nested DIVs to ULs (LIs)
  • deleted unnecessary class, id, name attributes
  • null (= empty) ALT tags for meaningless images
  • deleted empty SPAN tags

What's left to do:

  • We haven't changed or added any CSS yet (the red color for the list markers is only for demonstration purposes).
  • List markers are shown twice, we have to amend that.
  • The images used as list markers are inserted inline. There are more elegant (and semantic) ways to do so.
  • The indentation is larger than in the original. That and some other values for margins, padding etc. might need some tweaking to come as close to the original layout as possible.
  • We left some DIVs which are used for styling by the current CCS.

Here's the current structure of the block:

<td style="width: 210px;" id="left-column">
<a href="#sb-1" class="skip-block">Skip Site Administration</a>
 
<div id="inst2" class="block_admin_tree sideblock">
 
<h2 class="header" >Site Administration</h2>
 
<div class="content">
 
<ul class="admintree"></ul>
 
<div class="footer">
<form class="adminsearchform"></form>
</div>
 
</div>
 
<span id="sb-1" class="skip-block-to"></span>
 
</div>
 
</td>

I noticed a slight inconsistency: Whereas the Footer DIV is nested within the Content DIV, the Header isn't. I haven't checked yet whether that was the case in the original code or introduced by me when juggling with all those DIV tags...

Stay tuned! Continued on User:Frank Ralf/Semantic HTML2.

Further resources

"The div tag is a block-level element that defines a section within a document. Divs are thus suitable for building the structure of Web pages. The div tag is also used to describe content that cannot be properly described by other more semantic tags. When developers do not understand the semantic meaning of other block-level elements, they often add more div tags than are needed."

See also