Tag Archive for 'CSS'

Toppling the Stacks

Everyone agrees that CSS is an overly verbose stream of boiling pain, but not everyone agrees on how it should be solved. Sass is one such solution — a language extension that supports standard CSS code natively, but provides several tricks that make the maintenance of stylesheets easier, not least of which being the ability to nest selectors:

.profile {
  color: black;
  .name { font-weight: bold; }
}

A compiler turns the above into standard CSS:

.profile { color: black; }
.profile .name { font-weight: bold; }

Typical usage of Sass is to write the former by hand, run the compiler, and move the resulting CSS file to wherever the browser can see it.

I successfully set up Sass on my development machine and uploaded the generated CSS to source control. This worked correctly for a few weeks.

Then came the time when I had to set up Sass on the deployment server, because not everyone on the team had the time or the operating system to set up Sass on their computer. It burst into flames almost immediately with an arcane stack trace:

.../rubygems/defaults.rb:40:in `exist?': Insecure operation - exist? (SecurityError)
    from .../rubygems/defaults.rb:40:in `default_path'
    from .../rubygems.rb:752:in `path'
    from .../rubygems/source_index.rb:59:in `installed_spec_directories'
    from .../rubygems.rb:1051:in `source_index'
    from .../rubygems.rb:243:in `activate_dep'
    from .../rubygems.rb:236:in `activate'
    from .../rubygems.rb:1307:in `gem'
    from /usr/local/bin/sass:18

I posted an issue to the GitHub issues tracker for Sass. The answer was underwhelming :

This looks like a Rubygems issue, not a Sass issue.

And the issue was closed.

Let me set things straight here: when a Sass user cannot use Sass, it is a Sass issue. Yes, the underlying technical cause of the issue is probably somewhere inside that «Rubygems» thing I sincerely know nothing about, or maybe it lies in the Debian package for it, or maybe I’m just setting up my environment variables badly and just need a clean diagnosis to fix that up, but Sass is not working. Even if you have absolutely no personal responsibility for the issue, pointers such as «ask about this on channel X or mailing list Y» are most welcome.

Now, I don’t expect nex3 to provide me with free support. This is an open source project, and there’s nothing unusual or wrong with having no technical support on open source projects. In fact, given the size of the technology stack sitting under Sass, this was probably the best thing to do in terms of project strategy — only cater to users who can get the underlying stack working on their own.

This is not a matter of fairness or ethics, but one of incentives. I have no need to keep debugging Sass — the path of least resistance is precisely to replace Sass with an equivalent working tool. Rewriting a handful of Sass rules over to Less CSS is easier for me than tracking down bugs in the Debian packaging of «Rubygems». And the deployment server runs Less without a hitch.

I shudder to think what would have happened had I locked myself into more esoteric Sass language features.

Article image © yimmy149 — Flickr

Does this repository make me look fat?

The main RunOrg SVN repository contains:

  • 38490 lines of OCaml implementation code spread over 273 *.ml files.
  • 5134 lines of OCaml signature code spread over 156*.mli files.
  • 4776 lines of HTML template code spread over 271 *.htm files.
  • 1971 lines of CSS in 6 files.
  • 1898 lines of JSON configuration in 26 files.
  • 1172 lines of JavaScript in 5 files.

That’s a total 53441 lines in 837 files.

Here’s a plot of how the 38490 lines of OCaml code came into being over the last eight months.

That is all.

Brain Dump

Frameworks. Every single tech person is touting around the word Framework these days. And we all seem to have a different definition about it. Even when it obviously does not apply. Here’s what a tutorial had to say about the Blueprint CSS Framework :

Blueprint CSS isn’t really a framework in the sense that it’s not MVC (model-view-controller) like something like Ruby on Rails

Way to go kid. Don’t go around confusing Frameworks with MVC Web Server Frameworks (of which Ruby on Rails is an example). Also, do check out Blueprint CSS, it’s quite good for small-ish projects without a great web designer on hand.

Drive-through open source. On the topic of having fewer tech people around you yet still managing to set up your free open source tools, Bitnami offers free installers for the main open source applications. Instead of having to hunt down appropriate versions and configuratios of Linux, Apache, MySQL and PHP to run your Drupal web site, just download and install the Drupal package stack.

Gifts and choices. In a powerful address at Princeton, Amazon.com founder Jeff Bezos explains the difference between a gift (I’m good at doing X) and a choice (I decided to do Y) and the power of X=Y. Go read it. It’s great. If you’re wondering whether you should quit your job and start a company, go read it again. It only gets better.

DNS Propagation. Need to point your domain to another server, and wondering how many DNS servers have already caught up on the modification? WhatsMyDNS.net handles this for you. It’s free and very useful (albeit in an extremely specific situation).

Browse the Brain Dump category or subscribe to my feed.

Readability Improvement

Updated the stylesheet for the blog today to increase readability:

  • Decreased the size of the header, which used valuable screen real estate, from 220 pixels to 70 pixels. In terms of screen size, it decreased from 1/3rd of the screen height down to 1/9th.
  • Increased the width from 750 to 960 pixels (all of that increase went into making the content column wider).
  • Increased the font size by a few percent, and reduced the line height a bit.
  • Restored sane colors for the links (blue by default, orange when visited).
  • Corrected some silly rules (such as strong text using a different font, code being larger than the rest of the line, and the extreme line height in pre blocks).

Hopefully, it should be easier to read.

Reusable CSS

Woe unto CSS, for it provides no refactoring-friendly tools! The CSS beast has neither functions nor variables, and its definition of inheritance is perverted beyond words. Pain and suffering await those who hope to keep their CSS from one project to the next, or even share the CSS between pages on a single website!

Consider two simple pages: the home page has a small navigation bar (selected by #navig) at the top of the screen, while the catalog page as a larger navigation (still selected by #navig). Each page includes a different layout.css stylesheet, so everything’s fine. Except that now, anything defined in a layout has to be copied over by hand to the other layouts if you want to reuse them. Ouch.

Does that example sound extreme? It certainly is! But the danger of page-specific stylesheets remains: if you won’t be stepping on your own toes with something as trivial as #navig, perhaps .book will mean two different things on two different pages?

Rule Zero : Keep all your CSS Together

This might seem a bit harsh, especially if you have truckloads of CSS floating around and don’t want to slow down the initial loading time of your page, or the time spent resolving collisions. However,

  • This rule will make it easier to factor out common bits of CSS, leading to an overall smaller set of stylesheets.
  • The number of HTTP requests matters as much as the bandwidth, so delivering all your CSS as a single, minified, gzipped blob is often a good performance idea.
  • The entire point is to make it harder to create page-specific rules, so that you don’t make a rule page-specific by mistake, and strive to make most of your rules page-independent.

I usually place all of my CSS in correctly named files in a directory on my server, then have the server generate a single, all.css master file that @imports the other stylesheets by path. This means Firebug’s CSS browser will correctly identify the source file for any given rule. When the code moves to a production server, the auto-generated master file becomes a pre-generated/minified/gzipped resource, and can even be moved to a CDN for improved performance.

On the other hand, keeping all your code in one place will only help you see collisions, it will not actually help you solve them.

Fortunately, we can look to other languages for tips and trick on how to make code easier to reuse. The fundamental observation is that you cannot use something if you don’t give it a name. One would expect CSS identifiers and classes to serve the same function, and indeed it does work in simple cases:

a.important { font-weight: bold }

Now, you have the important «function», that you «call» on an anchor element to make it appear important. Bam! Instant reusability. Using an identifier instead of a class still allows reuse on distinct pages, but restricts reuse within a single page.

Rule One : Document your «Functions»

You cannot reuse code if you cannot find it, and even if you don’t forget about it someone else on the team might be completely unaware that it even exists. So you should somehow document that the important class exists. My personal, PHP-friendly preference, is to have a “Css” class with all those nice classes available:

class Css
{
  /* a.important : make a link important */
  const IMPORTANT = "important";
}

Then, you can reuse them when you see fit to do so:

Click <a href="<?=$url?>" class="<?=Css::IMPORTANT?>">here</a>

That’s just personal preference—any way of documenting your CSS classes is fine as long as it’s somewhere everyone can see it. In fact, I have a nice set of PHP helpers lying around to bind jQuery UI CSS effects to my code, thereby documenting what jQuery UI can do without having to dive into the stylesheets every single time.

The real problem appears when you have more than one «argument». A typical example is the list of links with a “selected” link: the graphical effect applies to the list, to the elements of that list, and to the content of those elements, which leads to several rules selecting different elements.

ul#navig { margin: 0 ; padding: 0}
ul#navig li { list-style-type: none }
ul#navig li.selected a { font-weight: bold ; color: black }

This kind of structure cannot be documented simply by stating that the ul#navig element is going to become a pretty list, because without the li.selected in there there will be no «pretty» worth mentioning.

I document this as follows:

/*
  <ul id="navig">
    <li><a>Item</a><li>
    <li class="selected"><a>Item</a><li>
    <li><a>Item</a><li>
  </ul>
*/
ul#navig { margin: 0 ; padding: 0}
ul#navig li { list-style-type: none }
ul#navig li.selected a { font-weight: bold ; color: black }

Why not document it in the PHP code, then? IMO, a CSS designer to write a quick const FOO = "bar"; line in PHP, but not an HTML helper that turns an array of links into pretty list HTML. CSS designers write the CSS (with documented HTML) and PHP developers turn that into HTML helpers.

</acronym soup>

Another important element of code reuse is the notion of encapsulation, and in particular the existence of “private data” that is part of the program, but can only be accessed by some parts.

There is no such thing with CSS. There are two reasons for this. The main reason is that being sloppy with selectors is commonplace:

/*
  <div id="userList">
    <ul class="users">
      ...
    </ul>
    <a>New</a> |
    <a>Edit</a> |
    <a>Delete</a>
  </div>
*/
#userList a { color: #FF9900 ; text-decoration: none }
#userList a:hover { text-decoration: underline }

The three links in the user list component («new», «edit» and «delete») will appear in orange without underlining, as expected and documented. The unexpected and non-documented consequence of this code is that all links within the list of users will be orange without underlining as well.

Rule Two : Only Select what you Need to Select

The typical consequence of sloppy selectors is that «insert component A into component B» operations utterly destroy the formatting of component A. The typical designer reaction to such graphicalypse is «Darn, component B destroyed some property of component A, so let’s add some rules to component A to reverse the damage!»

Bad idea. It makes the code longer, and only hides the actual problem (along with any symptoms that only appear in specific cases). The real solution is to make sure selectors only select what they need to select.

One way of doing so is to use the «>» selector, as it restricts the selection to only children of the initially selected element. This would work:

#userList > a { color: #FF9900 ; text-decoration: none }
#userList > a:hover { text-decoration: underline }

Of course, it wouldn’t work in IE6, but who cares about IE6 anymore?

The general approach is to use specific classes for those elements that must be affected:

/*
  <div id="userList">
    <ul>
      ...
    </ul>
    <a class="userList-link">New</a> |
    <a class="userList-link">Edit</a> |
    <a class="userList-link>Delete</a>
  </div>
*/
a.userList-link { color: #FF9900 ; text-decoration: none }
a.userList-link:hover { text-decoration: underline }

If anyone uses that userList-link class in their code (and your naming conventions were clean enough), they had it coming.

Rule Three : Choose Proper Naming Conventions

It is quite important to remain consistent in your naming practices, especially since you now need to identify, for any given identifier and/or class:

  • If it represents a «function» (#userList), or if it helps select a specific «argument» (.userList-link).
  • In the latter situation, what function the argument corresponds to (so that you can look for its definition).

My preference is to use camelCase names (classes or identifiers) for functions, and camelCase-camelCase names for arguments, where the first half is the name of the function. The CSS would then be gathered in a camelCase.css stylesheet named after the function, with a documentation of the expected HTML at the top, hence making it much easier to find and reuse.

Now that you have access to functions, you will probably want to use them to implement reusable «components» — standalone pieces of HTML and CSS that represent atoms of information.

At some point, you will have to make components interact (if only to respect each other on the page layout). All of this will be hell if component A uses normal block layout rules, component B is floating to the left and component C is positioned absolutely.

Rule Four : a Component Should only Care about its Inner Layout

As soon as a component starts to care about outer layout concepts such as margin, position, floating or clearing, you will be in a world of pain. This is because such concepts depend on where the component appears, and as such are not easy to reuse.

I split my CSS code into components and bones:

  • Components. These are reusable atoms. They do not care about their outer layout at all, so they never specify anything like margin, position, floating, clearing, display mode or anything that might cause them to interact differently with their surroundings on the page.

    They may specify a width and height if they wish, but it is discouraged (a component that can adapt to any geometry is easier to use). They can specify anything they want in terms of border, padding, font, color, background, font, and any inner properties they need.

  • Bones. These are elements found inside the components that handle the layout of the component contents themselves. They can and should make appropriate assumptions about what bones can be found within a component and how they should interact to result in the layout you need to see.

A nice finishing touch is to make the component overflow : hidden, because the last thing you need is a component’s skeleton sticking out from its skin and interacting with other elements.

I repeat: never allow the contents of a component to stick out of that component!

In particular, if you have a component with floating elements inside, make sure you add a clearer element at the bottom of the component to have it resize with its contents.

In practice, I assume every function argument to be a bone, and every function to be a component. The situations where a function acts as a bone are so rare, and the results so difficult to reuse (so you’ve added a float:left to an element, where are you going to put it?), that I don’t really take them into account. The Component-Bone approach tends to solve almost everything elegantly, as long as you’re clever about where a component begins and a bone ends.

For instance, if you’re laying out a list of comments for a blog, you are probably going to have a «comment list» component with «comment» bones that are laid out on top of one another with appropriate margins, borders and paddings. The contents of every «comment» bone will be a «comment» component, with bones representing the picture, name, date and comment body, laid out cleanly without that component.

Whether the .commentList-comment is placed on the same element as .comment is something you can decide for yourself. What is essential is that, in order for the comment style to be reusable independently of the comment list style, all outer layout information should be in .commentList-comment, not in .comment.

Good.

Now, before I finish, do you remember when I said earlier that component B could be mangled by component A for two different reasons? The second reason happens to be inheritance. Everyone knows inheritance is bad for reuse. Right?

What happens is that, if you define a font size, color or family in a given element, then all descendants of that element will get the same font size, color and family (unless some CSS rule changes them). That’s inheritance: the value of the property in the child element is inherited from the parent element.

Rule Five: Only Change Inheritable Properties on your own Content

It’s impossible to define the entire list of inheritable properties at the root of every single component in your web side, however convenient it may be. Keeping everything in sync is very difficult, if not impossible. It is far easier, by comparison, to restrict such changes to only those areas of a component where the content is closely controlled and guaranteed not to contain any other components.

I believe there are basically three kinds of areas in any given page that are actually worth being paid attention to. These are:

  • Layout areas. These are those component-in-component-in-component places where touching an inheritable property can get you killed annoyed.
  • Text areas. Those contain no components, but they might still contain paragraphs, links, headings, images in a typical «rich text editor» fashion. If you change one property (such as the color of text), be ready to change all the related properties (the color of links) to keep a consistent appearance.
  • Line areas. These contain a short bit of text without any other tags. You don’t have to worry about changing properties here.

Every component should document, for every piece of content that should be filled from outside the component, whether it is a layout, text or line area. For instance:

/*
  <div class="comment">
    <span class="comment-author">...</span>
    <div class="comment-contents"><p>...</p></div>
    <div class="comment-reply">
      ...
    </div>
  </div>
*/

Here, a span (can only contain inline elements or text) represents a line area, a div-with-paragraph represents a text area (may contain several paragraphs, of course) and a normal div represents a layout area. This tells me, for instance, «don’t even think about putting a component in the comment contents, or I’ll clobber their stylesheet beyond recognition.»

Depending on the kind of web site you are building, other kinds of areas may be useful to you, such as forms.

CSS Indentation Trick

While reading a WordPress stylesheet recently, I stumbled upon an interesting way to nest CSS selectors and their associated rules. To illustrate, here’s a listamatic example of list stylesheet:

ul#navlist
{
margin: 0 0 0 30px;
padding: 0;
width: 12.5%;
}

#navlist li
{
list-style-type: none;
background-color: #191970;
color: #daa520;
border: .2em solid #daa520;
font-weight: 600;
text-align: center;
padding: .3em;
margin-bottom: .1em;
}

#navlist li a
{
color: #daa520;
text-decoration: none;
display: block;
}

#navlist li a:hover
{
background-color: #faebd7;
color: #191970;
}

And here’s the reindented version:

ul#navlist {
  margin: 0 0 0 30px;
  padding: 0;
  width: 12.5%;
}
  #navlist li {
    list-style-type: none;
    background-color: #191970;
    color: #daa520;
    border: .2em solid #daa520;
    font-weight: 600;
    text-align: center;
    padding: .3em;
    margin-bottom: .1em;
  }
    #navlist li a {
      color: #daa520;
      text-decoration: none;
      display: block;
    }
    #navlist li a:hover {
      background-color: #faebd7;
      color: #191970;
    }

The idea is to combine the common prefixes in selectors as branches of a tree, and then indent each node of the tree by its depth in the tree (and place it right below its parent node or elder sibling). From what I gather, the position of the braces varies depending on personal styles, but the basic indentation rules apply as such.

Empty Lists

We have all written this code before :

<ul>
  <?php foreach ($list as $element):?>
    <li><?=htmlspecialchars($element)?></li>
  <?php endforeach; ?>
</ul>

What happens when the list is empty? What is generated is an empty UL element :

<ul></ul>

This would be perfectly fine, if it wasn’t completely wrong. Quoth the XHTML DTDs (any of them) :

<!ELEMENT ul (li)+>

There must always be at least one list item in a list (what kind of insanity would have led to preventing empty lists from existing is beyond me, although I’m certain they must have had a good reason), which means a document will not validate if it contains the aforementioned empty UL element. This is also the case for HTML 4, though HTML 5 does currently allow empty lists.

So, to circumvent the empty list case, the code becomes:

<?php if (count($list) > 0): ?>
  <ul>
    <?php foreach ($list as $element): ?>
      <li><?=htmlspecialchars($element)?></li>
    <?php endforeach; ?>
  </ul>
<?php endif; ?>

While it might be possible to abstract these details away behind a function that prints a list of elements, the ultimate point of such an abstraction would be to free the developer’s mind of the issue of empty lists not being allowed in XHTML. And such a thing would be ill advised : since the correct behavior is to remove the empty list from the document, the developer should be aware that no UL element will be generated for an empty list, especially since this has implications on the CSS side (which has to accomodate the absence of the list) and the Javascript side (which has to create the element if it doesn’t exist before adding elements to it).

An important quality of any developer is their ability to identify and handle any corner cases of their domain. An important quality of any domain is to have as few corner cases as possible.

Bored CSS

I had some free time on my lunch hour today, so I decided to answer a plea for help on the GameDev.net forums.

I am absolutely horrible with CSS. I need something to launch my site with (server is not available ATM)

If you can make this page look presentable i’ll be very happy. Please build on each other work so instead of msging me paste a link in the thread so everyone can see what you done and hopefully make it better.

It took me a few minutes to review the page structure, think of a classic left-right page structure, and write the corresponding CSS. I didn’t have a lot of time, so I couldn’t make the stylesheet fully portable (for instance, the rounded corners only work in Firefox, and some CSS selectors seem to confuse Internet Explorer) thus illustrating the classic conundrum that designing the stylesheet is 99% of the work, and making the stylesheet work across all browsers is the remaining 99% of the work.

And then there’s the 99% of adding jQuery to the page ;)

You can check out the re-designed page, or look at this screenshot to see what it looks like in my FireFox:

You cannot hide

You shouldn’t hide parts of your web pages by using display:none. At least, that’s what Roger Johansson says:

In most cases, using display:none to hide an element is a bad choice that reduces accessibility.

I can’t really agree with that. After all, the display:none CSS property exists for a reason, and that reason is precisely to let designers hide parts of the design that shouldn’t be shown in a particular display mode. For instance, there is no point in displaying a navigation bar in a “print” stylesheet, so the navigation bar will get a display:none property and disappear.

Aside from that, I also use display:none to hide things from users that don’t have JavaScript enabled. I see no reason to display AJAX-specific constructs (such as ‘loading’ sprites or containers used to display the result of asynchronous operations) to these users—instead, non-AJAX constructs should be displayed by default and replaced by their AJAX counterparts though JavaScript executed upon page load.

I believe the core of the disagreement here is what hide means. When I hide something, I want it to be completely gone for the user.

  • The user should not be able to see the element.
  • The user should not be able to hear the text on the element.
  • The user should not be able to select the text of the element by using the browser’s Find method.

It’s already bad enough that some web browsers include hidden text when highlighting and copy-pasting text around it (try copy-pasting the hidden text in this sentence), why go for an inferior solution that doesn’t really hide the element?

In the end, the real question is not how to hide elements—use display:none and that’s it—but rather when to hide elements. And hiding an element that you want some users to see (or hear, or interact with in any other way) is just silly.

CSS Strategery

How do you prevent CSS from becoming a mess? Here are some tasty bits from my own design strategy.

Nature

CSS is based on rules, used to select only certain elements in the document and apply effects to these elements. While the rules themselves have some small level of semantics applied to them, most of the time the actual meaning is provided by the author, which makes it essential to decide exactly how the semantics should be described.

Most rules deal with an object with a certain nature. At this most basic level, the nature is merely the element the rule is applied to. For instance, for div.header a:link {} the nature is “link”, and for p img {} the nature is “image”. Some rules have no nature: p * {} does apply to anything, and div {} doesn’t really specify what the semantic nature of the div is. Nature can be further described using a class or identifier: img#logo {} applies to the logo, p span.mailaddr {} applies to spans that contain mail addresses.

One way of doing bad CSS is relying too much on nature. It consists in giving almost every element in the tree a specific nature by means of classes or identifiers, and then individually applying a rule to every nature. The problem is that quite often the intended meaning is to have the same nature, but to exist in different context.

Context

For instance, is a link in a menu different from a link in the actual page contents? Both are links, the difference between them is not one of nature, but one of context. In a way, while the nature is everything tied to the last element in the rule, the context is everything else in that rule.

.header a:link {}
.contents a:link {}

Orange is context, blue is nature. Splitting selector parts between context and nature does not change the overall size of the rule selector: a.header:link is ultimately the same length as .header a:link. However, relying on context means the XHTML is simpler: instead of having to decorate every link with a class, you merely have to decorate those elements that contain only header links (which, quite surprisingly, is usually the “header” block itself).

By consequent, it is essential to move as much information as possible to the context, within reasonable limits. The real question is what these limits really are.

Defaults

To put it bluntly, there’s no reason to tag a paragraph in the news section as having class “news” if all paragraphs in the news section have class “news”. In general, if the majority of elements with a default XHTML semantic have the same semantic in your document in a certain context, then that should be made the default semantic for those elements within that context. So you can avoid writing horrible things like:

div.contents p.content_text em.content_text_emphasis {}

And instead use the more reasonable:

div.contents p em {}

The main benefit is not that your CSS is shorter, although that does happen as well, but that your XHTML document is shorter, since you don’t have to add classes to every element.



1170 feed subscribers
(readers who polled a feed this week)