
Forms can be complicated. Here are a few guidelines to take the pain away.
- Use fieldsets to group sections of forms and related inputs
- Use tables to group labels, inputs, and help. Using tables to lay out forms isn’t the best, in terms of semantic markup, but we’re making a slight compromise here to ease development.
<form id="oc-join-form" name="edit_form" method="post" enctype="multipart/form-data" action="/portal_memberdata/portal_factory/OpenMember/openmember.2007-05-08.0523490218/reg_form">
<fieldset>
<legend class="headingBlock">
<h1>Join OpenPlans</h1>
<p class="oc-headingContext">Registration is free and your email will not be
shared with anyone, however, you will need to confirm your email address in order to avoid
spam bots abusing this system
</p>
</legend>
<table class="oc-form">
<tbody>
<tr class="oc-form-row">
<th scope="row" class="oc-form-label">
<label for="">Username</label>
</th>
<td class="oc-form-value">
<input type="text" name="__ac_name" id="__ac_name" />
</td>
<td class="oc-form-help">
<span class="oc-form-context">
Pick something funny
</span>
<span id="oc-username-validator" class="oc-form-validator">
Sorry, that username is taken
</span>
</td>
</tr>
<tr class="oc-form-row">
<th scope="row" class="oc-form-label">
<label for="">Full Name</label>
</th>
<td class="oc-form-value">
<input type="text" />
</td>
<td class="oc-form-help">
<span class="oc-form-context">
(optional)
</span>
<span class="oc-form-validator">
</span>
</td>
</tr>
</tbody>
</table>
</fieldset>
</form>
This markup will make the following naked html:

Add CSS, and you get the finished product:


Not your daddy’s Deliverance.
Since our markup and CSS will need to be ported into other people’s sites via Deliverance, we’ll add an oc- namespace to all our classes and IDs (in addition to following our other naming rules). This will avoid any conflicts with styles in the parent site. For example:
<div class="oc-wiki">
<div class="oc-headingBlockâ€>
<h2>Project Home</h2>
</div><!– end .oc-headingBlock –>
<ul class=â€oc-tabsâ€>
<li>
<a href=â€â€ rel=â€viewâ€>view</a>
</li>
<li class=â€oc-selectedâ€>
<a href=â€â€ rel=â€editâ€>edit</a>
</li>
<li>
<a href=â€â€ rel=â€historyâ€>history</a>
</li>
</ul><!– end .oc-tabs –>
<!–- more stuff here -–>
</div><!–- end .oc-wiki –->

Class naming conventions
Hierarchical classes:
Hierarchical elements take class names from their parents, within reason. The idea is to keep it consistent while avoiding 10-part class names. Use your best judgement here.
<div class="oc-widget oc-widget-feed">
<h2>Recently updated projects</h2>
<ul class="oc-widget-feed-list">
<li class="oc-feed-item oc-clearAfter" tal:repeat="project view/recentprojects">
<img class="oc-avatar" src="" tal:attributes="src project/image_src | nothing" />
<h3 class="oc-feed-item-title">
<a href="" tal:attributes="href project/absolute_url" tal:content="nocall: project/title">Project Title</a>
</h3>
<p class="oc-feed-item-data oc-discreetText" tal:define="nmembers python: len(project.projectMemberIds())">
<span tal:replace="nmembers">YY</span> member<span tal:condition="python: nmembers > 1" tal:replace="string:s" />, active since <span tal:replace="python: view.create_date(project)">Jan 1937</span>
</p>
<p class="oc-feed-item-description" tal:content="project/mission | string: project mission statement goes here">
This is the descriptive text for a project. Apparently it doesn’t quite work right yet. Is there even a field for users to fill out or entry to call from a database?
</p>
</li>
</ul><!– end .oc-widget-feed-list –>
</div><!– end .oc-widget-feed –>
Reusable/generic classes:
Reusable / generic classes can go anywhere, without specifying anything more. For example, an oc-headingBlock can go inside any block-level element, including “widgets”.
<div class="oc-headingBlock">
<h1>Projects on OpenPlans</h1>
<p class="oc-headingContext">Currently serving <span tal:replace="view/nprojects"/> projects</p>
</div><!-- end .oc-headingBlock -->
Two-class naming structure for generics.
First class name defines generic. Second enables customizations.
<div class="oc-widget oc-widget-feed">
<!– some stuff –>
</div><!– end .oc-widget.oc-widget-feed –>
Case studies:
A few code examples here… (simple to complex)
- Feed
- Wiki
- Forms

Simple, semantic, reusable markup, tied to organized CSS.
- Simple: Keep class names as simple as possible while using The OC and sticking with our naming conventions.
- Semantic: Use <h1>, <h2>, etc. for headings, <ul> for unordered lists, <ol> for ordered lists, etc. Use generic <div>s & <span>s as little as possible. (Almost) never use tables for layout.
- Reusable: Find patterns and use existing markup whenever possible. Keep developers out of the CSS file as much as possible.