top of page
  • Writer's pictureselinov

Using Structural Selectors to avoid Class-itus in HTML5 and CSS3

I’ve been spending some time cleaning up my HTML and CSS in the Flojuggler iOS app. Trying to stay within semantic standards is becoming my latest obsession. I call it an obsession because, like all rules, there’s a time and a place for everything. While it would be great if everything could be super clean all the time, sometimes breaking the rules gets the project to where it needs to be. That said, this example is within the rules. 😉

Here’s a snippet that includes a simple form with an ID of #edit-form. I’m using JQuery Mobile on this project because I like the built in transitions and widgets for HTML5 field types like “number” and “date”.

<form id="edit-form" data-ajax="false">
	<div data-role="fieldcontain">
		<input id="name" type="text" maxlength="25" name="name" placeholder="enter name" value="Unnamed" />
	 </div>
	<div data-role="fieldcontain">
		<label for="cycle-field">How many days between flos?</label>
		<input id="cycle" type="range" max="40" min="1" name="cycle" readonly="readonly" value="30" />
	 </div>
	<div data-role="fieldcontain">
		<label for="long">How many days does the flo last?</label>
		 <input id="long" type="range" max="12" min="1" name="long" readonly="readonly" value="7" />
	 </div>
	<div data-role="fieldcontain">
		<label for="startDate">What is the start date her last flo?</label>
		<input id="startDate" type="date" name="startDate" value="" />
	 </div>
	<input id="thumbnail" type="hidden" name="thumbnail" value="images/thumbnail.svg" />
</form>

Typically I would have placed classes on the first and last field items. This would allow me to target them directly and remove the borders as needed. The thing about that approach is that it requires me place those class assignments into the HTML which just adds to the clutter. Instead I decided to use CSS3 structural selectors instead. This allows me to target the same DOM nodes without adding class assignments to the markup.

#edit-form .ui-field-contain:last-of-type {
    border: none;
}

#edit-form .ui-field-contain:last-of-type .ui-input-text input {
    min-height: 1em !important;
}

#edit-form .ui-field-contain:first-child .ui-input-text {
    width: 12em;
    float: left;
    margin: 0 0 0 10px;
    line-height: 1em;
    padding-top: .4em;
}

Oh… how I wish I had SASS installed. Then I could get rid of those redundant #edit-form tags which are there “just in case”. I’m not sure what the future holds as far as mark up so I want to make sure that these styles are scoped only to this form with the ID of #edit-form. If I had SASS I could do the same by nesting the sub-styles within the #edit-form definition like so…

.ui-field-contain {
    &:last-of-type {
        border: none;
    }
    
    &:last-of-type .ui-input-text input {
        min-height: 1em !important;
    }
    
    &:first-child .ui-input-text {
        width: 12em;
        float: left;
        margin: 0 0 0 10px;
        line-height: 1em;
        padding-top: .8em;
    }
}
bottom of page