Question

For so long, I've read and understood the following truths concerning web development:

  1. HTML is for content
  2. CSS is for presentation
  3. JavaScript is for behavior.

This is normally all fine and good, and I find that when I strictly follow these guidelines and use external .css and .js files, it makes my entire site much much more manageable. However, I think I found a situation that breaks this line of thought.

I have a custom forums system that I've built for one of my sites. In addition to the usual formatting for such a system (links, images, bold italics and underline, etc) I've allowed my users to set the formatting of their text, including color, font family, and size. All of this is saved in by database of forum messages as formatting code, and then translated to the corresponding HTML when the page is viewed. (A bit inefficient, technically I should translate before saving, but this way I can work on the system live.)

Due to the nature of this and other similar systems, I end up with a lot of tags floating around the resulting HTML code, which I believe are unofficially deprecated since I'm supposed to be using CSS for formatting. This breaks rules one and two, which state that HTML should not contain formatting information, preferring that information to be located in the CSS document instead.

Is there a way to achieve dynamic formatting in CSS without including that information in the markup? Is it worth the trouble? Or, considering the implied limitations of proper code, an I to limit what my users can do in order to follow the "correct" way to format my code?

Was it helpful?

Solution

It's okay to use the style attribute for elements:

This is <span style="color: red;">red text</span>.

If users are limited to only some options, you can use classes:

This is <span class="red">red text</span>.

Be sure to use semantic HTML elements:

This is <strong>strong and <em class="blue">emphasized</em></strong>
text with a <a href="http://www.google.com" rel="external">link</a>.

Common semantic elements and their user-space terms:

  • <p> (paragraphs)
  • <strong> (bold)
  • <em> (italic)
  • <blockquote> (quotes)
  • <ul> and <ol> with <li> (lists)
  • More...?

Likely less common in forum posts, but still usable semantic elements:

  • <h1>, <h2>, etc. (headings; be sure to start at a value so your page makes sense)
  • <del>, and, to a lesser extent, <ins> (strikeout)
  • <sup> and <sub> (superscript and subscript, respectively)
  • <dl> with <dt> and <dd> (list of pairs)
  • <address> (contact information)
  • More...

OTHER TIPS

This is a bit tricky. I would think about what you really want to allow visitors to do. Arbitrary colours and fonts? That seems rather useless. Emphasis, headings, links, and images? Well that you can handle easily enough by restricting to those tags / using a wikitext/forumtext markup that only provides these features.

You could dynamically build an inline style sheet in the head of the html page fed to the users. Put in the head of the page and allow it to target those elements configurable by the user.

Alternatively, there's the notion of using external stylesheets that feature the most common adjustments, but there'd be hundreds of them to account for every possible alternative. If you use this you'd need an external style sheet for a specific font size, colour and so on, and dynamically link to those in the header. As with any external stylesheet. Though this is almost unbearably complex to enable.

Option one would work okay though.

As an example:

<STYLE>
    h1,h2,h3,h4 {font-family: Helvetica, Calibri;}
    p    {font-size: 1.2em;    // Populate all this with values from the Db.
         font-weight: bold;
         }
    a    {text-decoration: underline;
         color: #f00;
         }
</STYLE>

Also, it just occurred to me that you could probably create a per-user stylesheet to apply the configurable aspects. Use

<link href="/css/defaultstylesheet.css" type="text/css" rel="stylesheet" media="all" />
<link href="/css/user1245configured.css" type="text/css" rel="stylesheet" media="all" />
<!-- clearly the second is a stylesheet created for 'user 1245'. -->

The bonus of this approach is that it allows caching of the stylesheet by the browser. Though it might likely clutter up the css folder, unless you have specific user-paths to the user sheet? Wow, this could get complex... :)

This is an interesting situation because you can have an infinite number of different styles, depending on your users' tastes and their own personal styles.

There are a couple of things you can be doing to manage this situation efficiently. Probably the easiest would be to just use style overrides:

<p style="color: blue; font-size: 10pt;">Lorem Ipsum</p>

This is quick and easy. And remember, this is what style overrides are there for. But as you've said, this does not fit well with this content-presentation separation paradigm. To separate them a little more, you could build some CSS information on page load and then insert it into the <head> tag of your HTML. This still keeps the HTML and the CSS somewhat distinct, even though you're not technically sepating them.

Your other option would be to build the CSS and then output that to a file. This, however, would not be efficient (in my opinion). If you were to, on every page load, build a new CSS file that accounts for your users' unique preferences, this would sort of defeat the purpose. It's the same thing as the second option, using the <head> tag, you're just making it look separated. Even if you used techniques such as caching to try to limit how often you have to build a CSS file, will the ends really justify the means?

This is a completely subjective topic and you should, in the end, choose what you're most comfortable with.

I don't know which framework or even language you are using but e.g. Django uses a certain template language to sort of represent the HTML being output. I think a nice solution would be to simply use a different "template" depending on what the user has chosen. This way you wouldn't have to care about breaking the "rules" or having a bunch of basically unused tags floating around in the DOM.

Unless I completely misunderstood...!

The easiest way to manage this is probably to emit dynamic CSS when the pages are generated, based on the user's settings. Then everything is doing the job it is supposed to be doing and the server is doing the work of converting the user's settings into the appropriate CSS.

With the CSS doing this work, you can use appropriate attributes in the HTML (id and name and class and so on) and emit CSS that will cleanly format everything the way you want.

Consider the benefits versus the costs before you do anything. What is actually wrong with your code right now? Tag soup and combined content/presentation is to be avoided not because it makes a bad website, but because it is hard to maintain. If your HTML/CSS is being generated, who cares what the output is? If what you've got now works, then stick to it.

I assume you are allowing only a limited white list of safe options, and therefore parsing the the user's HTML already.

When rendering the HTML you could convert each style declaration to a class:

<span style="font-family: SansSerif; font-size: 18px;">Hello</span>

To:

<span class="SansSerif"><span class="size_18px">Hello</span></span>

Laborious to generate (and maintain) the list. However you needn't worry about a class for each combination, which is of course your main problem.

It also has the benefit of extra security as user's CSS is less likely to slip through your filter as it's all replaced, and this should also ensure all the CSS is valid.

I've allowed my users to set the formatting of their text, including color, font family, and size. All of this is saved in by database of forum messages as formatting code, and then translated to the corresponding HTML when the page is viewed.

So, you've done formatting through HTML, and you know that formatting is supposed to be done through CSS, and you realise this is a problem, and you got as far as asking a 300-word SO question about it ... ?

You don't see the solution, even though you can formulate the question ... ?

Here, I'll give you a hint:

All of this is saved in by database of forum messages as formatting code, and then translated to the corresponding HTML CSS when the page is viewed.

Does that help?

Is this question a joke?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top