views:

214

answers:

9

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?

+1  A: 

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... :)

David Thomas
A: 

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...!

Deniz Dogan
Framework? I hand-code my pages in HTML, CSS, and JavaScript. I use PHP to output the markup, my CSS and JavaScript rarely change so they're just linked in. I use a basic syntax highlighting text editor. I'm not sure what you mean by framework...
Nicholas Flynt
By framework I mean something like Django, which is written in Python. It was a long time ago that I used PHP, so I'm not aware of the progress that's been made on that front. Of course, either way, you should use different CSS depending on the user's choice.
Deniz Dogan
+4  A: 

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.

singpolyma
So that's one vote for "restrict what the users can do", interesting and well put.
Nicholas Flynt
+5  A: 

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...
strager
<strong> means strongly emphasized, not bold<em> means emphasized, not italics<del> means deleted text, although that's usually what strikethrough is for<address> is contact info for the page owner/author, not addresses:)
singpolyma
Also, never have a style called "red". When you redesign your site and "red" becomes blue it will just make life harder for everyone.
AmbroseChapel
I disagree, Ambrose. By allowing basic color choices only, it lets me modify the actual value for the base color to be more readable with the theme. This would be especially useful for yellow if I decided to move it from a dark to a light theme.
Nicholas Flynt
@Ambros, Flynt is right. Also, it's user text, not design text, so it's "okay."
strager
@singpolyma, strong and em are generally bold and italic, respectively. This is what they are to the user, which is what I meant for the parenthetical phrases. I'll correct address.
strager
I agree with Ambrose, class names shouldn't describe style. They should describe the semantics of what you're trying to do, not how it looks. E.g. if you're displaying something in red to represent an error message, the class should be 'error' not 'red', so that if you do change the whole theme of the site, you're not left with a class that looks like: "span.red { color: #00F; }", since that's just confusing.
Alconja
@Alconja, The purpose of a class such as "red" is to allow posters to specify e.g. [color=red] and have a colour matching the theme in the output (e.g. color: #CC0000; for a light background, or #FF3333; for a dark background). Of course, red should be used as a designer's class name, but a user's one.
strager
@strager, Fair point, since its purely user-land I guess you can't know the intention of colouring something red (assuming you're allowing arbitrary colours). However, I still think the red text should _mean_ something beyond being red. I.e. is the user is trying to show emphasis, anger, an error, a highlight, etc? So if you're restricting the user to a couple of colours, why not restrict them to a couple of logical meanings instead?Unless its just to let them make the text <red>pretty</red> :)
Alconja
If the forums were to use a color sensitive theme for user text, then perhaps it would make sense to limit user color choices to "logical" styles. The flip side of allowing users to choose their own colors is that I have to make sure to keep my forum style (At least the user text area) a monochrome theme. If I limit that somewhat and allow users to suggest base colors, it allows me to easily re-theme the palette to use a darker or ligher theme without limiting the users to arbitrary (and sometimes very limiting) "logic" values.My point is, it all depends on what capabilities your users need.
Nicholas Flynt
A: 

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.

Eddie
A: 

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.

nickf
Future compatibility? Not to say browsers will forget about <font> and unended <li>'s any time soon, but I think it's best to have nice, clean code now so you won't have to fix it later if/when browsers *do* evolve.
strager
Good point, and thus why I asked really. I'm trying to avoid the use of deprecated tags (font being one of them) in my generated code though, which is the main issue.
Nicholas Flynt
well yeah, avoid the deprecated tags. Font is easily translated to <span style="..."> though
nickf
+1  A: 

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.

Josh Leitzel
A: 

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.

Pool
A: 

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?

AmbroseChapel