Code Philosophy

The Art of Simple, Clear, and Elegant Code

Shadow Element

Web Code is Software

Look at a magazine: it’s text and graphics. All of the complexity that went into its layout is fixed when the ink hits the page. Users look at webpages the same way—text and graphics with maybe some interactivity thrown into the mix. But underneath, a webpage is code. The details of how the visible elements are displayed is a collaboration between the page’s code and the user’s web browser.

The code underlying a webpage is a computer software product. Like all software, it should be carefully constructed. For example, it should not contain invalid syntax. Sounds obvious doesn’t it? And yet most commercial webpages contain syntactical errors and fail to validate. You can easily check this for yourself—just enter the URL of any webpage into the W3C Validator and see what happens. CSS can also be validated by using the W3C CSS Validator.

So what if the code doesn’t validate? It still seems to work. Coding webpages poses special challenges. While most other software products are written for a particular known platform, web code is supposed to work on a large variety of web browsers running on many different operating systems. Each of those browsers can take the same page and display it differently. All browsers have error checking built into them and most will try to figure out what bad code probably means. So even broken code often looks okay on a user’s screen. The browsers don’t agree, however, on which errors to correct or how to fix them. But one set of code that browsers are supposed to agree upon,¹ at least for browsers released since about 2001, is the W3C’s standards for XHTML, CSS, and the DOM. Writing to those standards helps minimize the cross platform display issues that are the bane of every web developer.

Code can validate and be terrible. It can also function properly and still be bad.

Writing standards-compliant code is not enough. Code can validate and be terrible. It can even function properly and still be bad. While visible failures get the attention, the underlying code is like the foundation of the house—important but disregarded until something goes wrong.

Illustration - code underlies webpages.

Code Aesthetics for Non-Coders

To appreciate the aesthetics of code you have to “sense it,” not merely see it function—and non-coders usually run screaming when asked to look at code. But every coder senses these aesthetics and good ones try to make their code aesthetically pleasing. Even disregarding function, the difference between “good code” and “bad code” is enormous. Good code is lighter, easier to understand, easier to maintain, and easier to reuse.

So what makes code “good”? On the web, a big part is standards-based design—a coding model which separates the structure of content from the way it looks. HTML is used to mark up text with tags that define the structure of the document. This ‘semantic markup’ tells the reader about the structure of the document, but not about how it should be presented. For that, CSS is used to design the look of those tags in the browser.

HTML-only Example

Here’s a simple example. The following is a snippet of HTML. It displays a large red headline, shown below.

  <font size="5" color="red" 
  face="arial, sans-serif">
  <b>This is a headline</b></font>

This is a headline

HTML + CSS Example

Here’s the same headline without the information about how it should be presented mixed in:

<h1>This is a headline</h1> 

The CSS that defines how to present this headline goes elsewhere, often in a separate file for use over many pages. It would look like this:

  font-family: arial, sans-serif; 
  color: red; 
  font-size: 24px; 
  font-weight: bold; 

Together, they give the same result:

This is a headline

If you count characters, you’ll note that the HTML-only example has fewer. But imagine that you have a website full of headlines. In the HTML-only example, you need to style each of them with all of those presentation codes. Miss something in one and it’s going to look wrong. In the HTML + CSS example, you just have to mark each headline with its headline tags. And when you decide to change the way all those headlines look, in the HTML-only example you’ll need to hunt down every reference and fix it individually. In the HTML + CSS example, you just change the style properties in one place. The HTML-only example is often derisively referred to as “tag soup.” If all the headlines have all those tags around them defining how they should look, the size of the page download goes up, reducing responsiveness and increasing server bandwidth costs. Lighter, nimble code is better all around. But there’s more.

The separation between presentation and structure is critical to well-formed webpages. One benefit is accessibility. Blind users, for example, may experience a webpage through screen readers, most of which are programmed to understand and benefit from modern web standards. Page styling and untagged graphics only get in the way of these users. But text whose structure has been properly coded is much easier for blind users to navigate. For example, a screen reader might be directed to read the subheads aloud until the user finds the section of interest.

Google can be considered the web’s most voracious blind reader.

Those unmoved by social equity arguments for making sites accessible to the disabled might reason that blind users make up only a tiny fraction of the audience and can be safely ignored. But consider: when Google’s spider visits a page, it experiences it with many of the same constraints as a blind reader. In a way, Google can be considered the web’s most voracious blind reader. If the code has been written for accessibility, Google can understand the relative importance of various pieces of content and index the page accordingly. For those who care about their placement in search results, designing for accessibility is clearly in their self-interest.

In addition to accessibility and ease of maintenance, good code allows the same content to be displayed in radically different ways by changing the way the markup is styled. The best example on the web is the CSS Zen Garden. On this demonstration page, identical HTML markup is styled with a large number of different CSS choices (choose which to apply from the links under the “Select a Design” header). The content doesn’t change, just its presentation.

Content can be adjusted so that it is well-adapted to the display media. Desktop computers aren't the only game in town. Modern websites need to support devices with a variety of different widths. Phones, tablets, and laptops are all part of the mix. Some computers with high resolution “retina” screens need higher resolution images inappropriate for mobile devices. And webpages aren’t always displayed on screens; sometimes they need to be printed on paper. CSS makes it possible to provide a very different experience of the same page to each of these different devices and media. It's called “responsive design,” and it’s a game changer.

The web is full of mash-ups, content aggregators, PDAs, interactive television systems, voice response systems, and even some domestic appliances, all of which may need to access content.

Finally, designing for accessibility also allows for device independence. Web content is not just for display by browsers anymore. The web is full of mash-ups, content aggregators, PDAs, interactive television systems, voice response systems, and even some domestic appliances, all of which may need to access content. Accessibility of content through proper design is the key to being able to participate in much of this activity and satisfy these different uses. “Web on Everything” has become the environment for which we need to build websites.

Other Code Aesthetics

In addition to creating code that’s simple and clear, code should be written in such a way that it degrades gracefully as the technology that it depends upon becomes unavailable. For example, a very high percentage of users have JavaScript turned on. So it’s reasonable to use JavaScript to add special features to a website. However, a web developer must be mindful of the users who don’t. Features that are added should offer enhanced functionality not otherwise available but not replace the basic functionality which can achieved without JavaScript. So, for a simple example, JavaScript might be used to hide some content beneath a button labeled “more” and only show that content when the user clicked on the button. But if the user doesn’t have JavaScript turned on, then the content should display by default and the button should disappear. Code should be written so that JavaScript is unobtrusive, enhancing the experience of those users that have it but staying out of the way of those that don’t.

Old World Craftsmanship

We doubt much of what we’ve said so far on this Code Philosophy page will be controversial to web coders. But this will be: good code is written by hand. The code that is generated from the WYSIWYG editors, such as Dreamweaver, is just not as good as well-written code created by hand. The programs have gotten better over the years and they may even produce code which validates but it’s just not as good—and frequently it’s bad. It tends to be more laborious—heavier, harder to read, less generalized. Handwritten code exhibits that old world craftsmanship. (We bet you couldn’t guess that we write our code by hand!) Beyond function, the goal of writing good code is to keep it simple and clear. To do that you need to be passionate about it—constantly trying to find ways to make it better. It’s called refactoring and it is important to any software system. Even after the code works, you continue to comb through it, simplifying and rewriting to streamline the code and make it more elegant.

Also, we’re usually not fond of the code generated by Content Management Systems (“CMS”). There are two general categories of such systems—those that take pre-coded chunks and disperse them on a page as appropriate and those that actually generate code from content submitted in a non-code form. The first can be fine. We’ve written systems that work this way. But the second is more problematic. Often—may we say usually?—the code that’s generated is of poor quality. There’s a sliding scale—the more complex the code that a CMS tries to write, the worse it is. Many can encode straight text reasonably well, but additional markup is more difficult and automatically writing styles for the markup is disastrous. Basically, the less code that the CMS tries to write, the better.

Dynamic vs. Static Web Pages

Whether to use a CMS leads to another interesting topic—the choice between running dynamic or static websites. The value-laden words themselves make it seem like a no-brainer: who wouldn’t like a “dynamic” site? Who’d want a “static” one? But the reality is somewhat different. A dynamic webpage means one that’s served programmatically, usually out of a database. A static webpage is one that exists on the server already, ready to be called. That’s it. It doesn’t matter if the static webpage was pre-generated by a database or another program—or if it contains client-side scripts that makes it jump through hoops on the users’ browsers—if it’s there waiting to be called, it’s considered static.

A good web developer should help guide the decision process between static and dynamic pages because, like everything, there’s a cost/benefit analysis that needs to be made driving this choice. Dynamic webpages are sometimes completely appropriate. If the content is generated by the users—i.e. message boards, tagging, comments on a blog—then a dynamic site is probably the right answer. If the web content is changing extremely rapidly from external sources—a news wire type service for example—then a dynamic site is also the way to go.² But, unless there’s a compelling reason to do so, static pages often make more sense. They are not as technically complicated, so there’s less to go wrong. They are easier to maintain, easier for search engines to spider, easier to bookmark, faster for users to load, much more secure, easier to differentiate for different types of content, and generally cheaper to create.

It all sounds good until you see the mistakes that are made and the quality of the code that’s produced.

There are some structural reasons for an organization to prefer static to dynamic pages. Let’s say that an organization has many non-technical people generating content for a site. Most web developers would probably counsel the use of a CMS. Users can enter their content into a word processor of sorts, the content can be approved by a manager, and the system can then generate the code for the website. It all sounds good until you see the mistakes that are made and the quality of the code that’s produced.

Some systems require the code be authored by the non-technical content creators—sometimes they provide tools for “markup lite.” We think it’s analogous to car drivers being expected to know how to repair their own vehicle. While it may sound good to say that the CMS will assist the user in the process, it’s like having an automated mechanic. Perhaps it can do some things, but if you had a choice, you’d probably want to have your car maintained by a skilled human mechanic. We much prefer a system where there’s a coder, familiar with the website and its code base as a whole, who receives the content from the creators and uses it to update content. It’s separating the content from its technical delivery. Generally we do this for our clients. It’s almost as fast as a CMS system from submission to publication, and the quality of what’s pushed to the live site is much better—fewer mistakes, better integration with the rest of the site, much more secure, better designed and more effective content, easier maintenance in the future, and faster page loads. CMS systems just can’t write code as well as coders can.

Code aesthetics can even have a marketing purpose. If users have a poor impression of the technical aspects of a company’s website, they’re liable to form a judgment of the competence of the company as a whole. It’s analogous to typos and spelling errors — it may be unfair, but users often judge a company’s lack of attention to such details as a general lack of capability.

Software Quality is Both External and Internal

The quality of any program can be assessed both by external and internal features.

External quality features are those that are visible to the client and to the users. They include: functionality, usability, reactivity, security, availability, and reliability. If a program satisfies those features, most clients are satisfied and accept the program.

But internal quality is just as important even if it is invisible to clients and users. What is it? It sounds arcane, but internal quality is the key difference between a good program and a bad one. Internal quality is about “clean code.” It means that the code is readable by other skilled developers, provides good internal documentation, has filenames and variables that can be understood, is internally consistent, utilizes best practices in architecture and organization, has been optimized for the task, has a clean separation between the different functions of the program, is testable at least in substantial part. Ideally, each piece of code should have a clear responsibility. It should have no significant duplication. If it has dependencies, they should be explicit. It should be well encapsulated so that one object performs its methods internally and allows other objects to interact with it through clearly defined external interfaces.

Paying attention to internal quality is an investment in the future of a piece of software. Skimping on internal quality might save time and money in the short run, but causes the program to suffer from what has been aptly called a “technical debt.” It takes longer to fix even trivial bugs. Any changes or extensions to the software require a larger effort. Maintaining the software becomes more expensive. The software is not flexible and can’t grow with the needs of the client. If the original developer becomes unavailable, it can take a larger effort for another developer to understand how the program works. Sometimes, if changes are needed in a program which suffers from particularly poor internal quality issues, the economically sound decision can be to start over again from scratch.

A good program has already identified those areas likely to change and made it easy to implement changes in those areas. A good program is flexible and maintainable. A good program doesn’t intermingle logic and presentation. If a bug is identified, a good program makes it easier to fix that bug without breaking the rest of the program. Importantly, in a project built upon open source foundations, a good program allows the key underlying technologies to be upgraded without requiring a massive effort.

It always takes more time up front to polish code for internal quality. After one has written a piece of code which meets the external feature specifications, one must go back and refactor that code to clean it. But for code designed to be used for any length of time, that initial investment is well worth it in the reduced costs of support, maintenance, and upgrades.

Good Code Wrap-up

There are numerous browsers to view websites: Chrome, Explorer, Edge, Firefox, Safari, Opera, and more. And each of these browsers have different versions and upgrades, all of which are still in use by someone somewhere. Each browser can take the same webpage and display it differently based on its idiosyncratic rendering of the code.

The best approach we’ve found through this thicket is to create valid standards-compliant code that’s as clean as we can make it. Then if a particular supported browser displays a specific rendering error, we write special code for that browser and isolate it to target only that browser. These are called browser hacks. Isolating them keeps the main code clean and understandable.

Then there are many different devices — phones, tablets, desktop computers — each with different screen sizes. You can’t shrink a desktop webpage down to a phone-sized screen and provide a good experience to your user.

Rather than build separate websites for mobile and desktop, we’ve embraced responsive design which adapts a page’s layout based on the screen size of the device which is viewing it.

Most of our clients aren’t coders themselves and don’t know what we’ve done in the code underlying their site. The site just works. If they do open the source code and look at it, we hope they’ll think it looks simple and clear. The extra effort to streamline code is worth it in a reduction of errors, maintainability, flexibility, and future compatibility.

  1. In the old days, they didn’t actually agree as well as they might, but modern browsers are very good at rendering standards-compliant HTML and CSS.
  2. As an aside, for these kind of projects we always used to recommend a LAMP architecture—Linux, Apache, MySQL, PHP, although we’ve been using the MERN stack recently with great results. MERN stands for MongoDB, Express, React, and Node. And Vue can be substituted for React, giving you a MEVN stack.