The UF College of Education uses a header/footer template designed to be applied to any page, and we use this across several applications such as WordPress, Moodle, Elgg, and Drupal. Changes can be propagated quickly to all sites, and adding the template to new PHP apps is trivial.
If you need to create an HTML component that can be reused across a wide set of sites/apps, these guidelines might help.
Avoid HTML5 elements if you can
HTML5 elements like header
must be accompanied by JS to fix compatibility in old browsers. Sticking to HTML4 also helps with validation under HTML4/XHTML doctypes. Of course, if you’ll only be deploying to HTML5 sites that already have the IE shim, go ahead and use the best markup elements for the job.
Guard the host markup against the component CSS
Any component CSS selectors that match host markup elements can cause massive problems in the host application, and if this component is applied across an entire site, it’s very difficult to predict the impact. The key then is following a few simple rules for the component CSS:
- Each class/id name must be sufficiently unique such that there’s practically no chance of name collision. Unfortunately even selectors like
.hidden
and.clearfix
could be implemented in different ways in the host app and this could cause problems. Using a constant prefix in every name might help. - Each selector must include at least one of the component classes/ids.
- Avoid using a CSS reset/normalizer. If you must, make sure each selector follows the above rules so the effect of this is limited in scope to the component.
- Selectors must not match non-component elements. E.g. the selector
#component-root + div
should not be used because it would select a DIV element after the component. - Take care to avoid obscuring elements in the host page. E.g. negative margins could pull the component over a host element.
Guard the component markup against the host CSS
Similarly, host CSS could break the desired styling of the component markup.
- Test the component in a wide variety of pages and applications. Especially test pages that use common CSS resets and normalizers, and that have a lot of element-only selectors in the CSS.
- When interactions occur, make the affected element’s selector more specific until the component CSS “wins”. As always, test across the browsers you need to support; IE7 still has some specificity bugs for the selectors it understands, if you need to care about that.
Javascript Tips
Expose as little to the global namespace as possible
E.g., define all necessary functions and variables inside an anonymous function that is executed:
!function () { // your code here ... // explicitly expose an API this.myComponentAPI = api; }();
Document your script’s dependencies and let the implementor supply those
Automatically including JS libraries may break the host app. Consider the case of jQuery: Many plugins extend the jQuery
object, so redefining it removes those added functions (actually stores them away, but it will break the host app nonetheless). Don’t assume the user did this right. Wrap your functionality in a condition that first tests for the presence of the the library/specific features you need, and make it easy for the implementer to realize the problem if they have a console open.
Here’s an example of how to test for jQuery’s on
function:
if (this.jQuery && jQuery.fn.on) { // code } else if (this.console && console.log) { console.log('Requires jQuery.on, added in version 1.7'); }
Assume the component could be embedded after the page loads, and multiple times
Carefully consider the initialization process your component requires. In some cases it’s reasonable to leave the initialization to be triggered by the implementer. If you do automatically use DOMReady functions like jQuery’s ready()
, consider allowing the implementer to cancel this and initialize later.