Group discussion > XHTML guideline discussion: Part 1

XHTML guideline discussion: Part 1

Cash
219 days ago

As has been discussed on the community site, Elgg's XHTML, CSS, and UI could definitely be improved. As a starting place, I'd like to start a discussion on a guideline for XHTML. This guideline would be followed by core developers and serve as a good standard for plugin developers. The goal is better markup which makes it easier to do UI/UX work with Elgg.

What rules or recommendations would you like to see in an Elgg XHTML guideline? (Please note, this is for XHTML - not CSS. We'll get to CSS soon enough - edit - probably no way to keep them separate!).

XHTML

  1. Valid XHTML.
  2. Keep the DOM simple. Don't use several divs when one or two can do. If you do find yourself using a lot of markup, you are probably trying to solve a presentation issue with XHTML markup rather than using CSS.
  3. Use the correct markup for the content. Tables should be used for tabular data not for layouts. Lists for lists (rather than paragraphs). And so on.
  4. Markup should be content driven rather than presentation driven. IDs and Class names should not describe presentation: Bad Example: two_column_left_sidebar.
  5. Avoid inline javascript
  6. Accessible markup
  7. Reusable markup.
    • Prefer classes to ids
    • Use general classes for shared presentation and specific classes/ids for unique presentation. See discussion on the .messages markup below
    • Do not design your markup so that all CSS needs to be on terminal elements - use CSS inheritence

The CSS discussion is here.

Cash
219 days ago

The markup should be valid as defined by the w3 validator http://validator.w3.org/ .

Valid markup makes it easier to debug XHTML problems. It can make the rendering more consistent in browsers. It makes a project/site look more mature and professional. It's just a good idea.

smeranda
219 days ago

Cash, I second your requirement for valid markup. To further your arguments, validity allows for enhanced JS/CSS functionality.

In addition, other recommendations regarding XHTML:

  1. Table-based layouts should be removed. In looking at the profile page, the layout could be easily done with XHTML/CSS. This allows for further separation of presentation from markup.
  2. Use the correct markup for the content. To continue dissecting the profile page as an example, the links underneath the avatar are wrapped in individual <p> tags. These should be list items. The markup descibes the content. It will also make it easier for plugins to integrate (I just need to add an <li> instead of <p class="X">).
  3. To further the markup describing the content, the naming conventions of IDs and Classes should be better used. For instance, the names should not descirbe presentation. As an ID example:
    two_column_left_sidebar_maincontent_boxes

    What if I want to use the content on the right side of my page? Furthermore on this page, the following ID is also found on this page:

    two_column_left_sidebar_boxes

    Ideally, the IDs should be "elgg_maincontent" and "elgg_sidebar", respectivly and a class of "elgg_two_col" should be applied to both in order to provide the column structure in the CSS. Through this, we can also achieve reusable styles - which will be easier to maintain/update and will provide a smaller footprint.

  4. Reusable Markup - As I just eluded, resuble markup will save a lot of time/troubleshooting. Check out the feedback messages: normal and error. Both appear as the same structure/intent yet they used different class names (.messages & .messages_error). Examining the CSS shows that most of the presentation is duplicated (border size, radius, position, margin, etc.). This should be setup to allow for .message to setup the presentation, and a new class of .error that can be applied to .message to provide the error-specific presentation (color changes).

These are a few of my quick thoughts. As Elgg gets more powerful, becomes more widely-adopted and grows larger in codebase, I'd like to see markup changes begin soon - it will make it much easier to scale and adapt.

Brett
219 days ago

+1 on valid XHTML.

I would love to see a more simplified DOM.  I know the DOM is on the Javascript side of things, but a simpler DOM also means faster rendering for page paints.  Elgg's defaults pages have a pretty complicated DOM and I'm not sure it's needed.

Sort of related to smeranda's comment #3, I'd like to have more semantic-based ids and classes.  Creating pages with such structures will greatly simplify theming and jQuery calls.  I know object oriented CSS is a fad at the moment, and I'm always wary of fads, but there is something attractive about it. Semantic structures generally make more sense, and sense is always good...

Cash
219 days ago

What I'll do is pull rules out and add them to the top post - people can lobby/complain as needed on what I select.

On smeranda #1 - I do have a layout for the profile page that is div based rather than table based. It is a lot cleaner and has fewer rendering problems than the table layout. I believe it should work with IE6 but I have never gotten around to testing that.

A different but related comment than #3: if there is a chance that an element may be used more than once on a page, it should be a class rather than an id. The current markup is too liberal in its use of ids.

Brett
219 days ago

What do you think about dropping support for IE6?  It's 9 years old and 2 major versions behind...And I really dislike it.

Cash
219 days ago

Last time I checked it still had 25% of the browser market due to corporate controls. There are plenty of sites that support IE6 with nice div layouts. There is no reason Elgg cannot.

Alternatively, you could drop support with the default theme but provide an IE6 friendly theme for those who want to run Elgg in an environment where IE6 is the mandated browser.

Brett
219 days ago

http://www.w3schools.com/browsers/browsers_stats.asp shows it down to around 11% as of the end of last year.

Regardless, you're probably right that between corporate control and school systems, IE6 should be supported at some capacity.  If it can be done and isn't a huge drain on resources, it sounds good to me.

smeranda
218 days ago

Given the latest security exploits for the MS browsers, and the downward trend of IE6, delivering a stripped down experience in order to take advantage of new, advanced features like CSS3 is worth it. YouTube, Facebook, and many of the big sites have either already done so or have announced they intention to do so. As Cash mentioned, delivering an IE6 theme that renders with less sparkle could be appropriate.

A small suggestion based on the rule in the top thread:

Example: .messages & .messages_error have the same basic presentation logic and could be replaced with a single generic class and two smaller specific ids.

I'd propose this example to simply use two separate classes. By using a 2 class model, we allow for greater reusability. To demonstrate:

<div id="elgg_message" class="message">The message</div>
<div id="elgg_message_error" class="message">The error message</div>

While this will allow more flexibility in CSS, it still doesn't quite work correctly. For instance, what if I needed more than one error div on a page? Valid XHTML won't allow for duplicated IDs. An even more flexible markup would be:

<div class="message">The message</div>
<div class="message error">The error message</div>

In terms of the CSS, the IDs are not required (perhaps they are needed for JS targetting, but even this could be done simpler). All the presentation is handled by targetting the class (in this case 'message') and extended by doing simple color overrides with an additional class ('error'). This cleans up the markup by removing, and allows for more streamlined controls.

So, to continue on the resuable markup recommendation: utilize more class attributes and less id attributes.

morgar
218 days ago

Glad to see great activity in this topic. It was started sometimes in the past, but they didn't do too much progress. I agree it's the time for a move in that direction.

As Brett pointed, a DOM simplification is mandatory, the current html code is so unnecessary crowded.

We implemented XHTML/CSS in our Elgg site. I started trying to adapt the existing code but I finish rewriting most of it from scratch. It might have some glitches because it was my first big project in XHTML :)

I guess the right move should be start it from scratch.

I fully agree about the 'progressive' classes like in messages/errors. Some primitives will be also necessary, like profile and group widgets for example, that currently implement their own classes, resulting in a big mess.

Another decision is about using XHTML strict or transactional. I vote for this last one.

My 5c.

danielwells
218 days ago

According to the Microsoft End of Life page for IE (http://support.microsoft.com/gp/lifesupsps/#Internet_Explorer), it looks as though they will no longer support it after April of this year.  Maybe that will provide enough incentive for people (i.e., corporations) to get off of it.

I have decided not to support it on my site (encourage users to upgrade or switch).  I waste enough time troubleshooting rendering issues with IE7 and don't want to hassle with IE6 as well.

Cash
218 days ago

Could we get some examples of simplfying the Elgg DOM? I know pulling out tables makes it cleaner but I'm looking for other examples.

morgar
218 days ago

A specific case that I remember is the river. Every item has a lot of unnecesary nested divs (in 1.5, I didn't use the following versions yet, maybe they were fixed). I remove most of them and they kept working fine.

And if I remember right, there are also a lot of unnecesary <p> enclosing some elements like inputs in forms and items in menus.

I will take a look for recovering more cases.

 

Federico Bond
218 days ago

Now this is awesome. Standards compliance will make the platform much more atractive to designers & developers. I will try to help as much as I can!

@Cash Savvy use of CSS can help remove most of the excess divs wrapping the content, thus simplifying the DOM a lot.

@Morgar I really don't see the point in using XHTML Transitional. It's not very difficult to make things validate against the strict dtd, and it helps A LOT with misbehaving browsers (IE 7-)

morgar
218 days ago

@Federico: Yes, I agree strict is really not a big deal, I already used it in a couple of sites.

Mark Bridges
217 days ago

@All, fantastic to see this going on... not sure I understand all of it, but it will I think help make elgg the market leader it could be, and resolve my frustrations with it's clunkyness and complexity in theming and performance fears.  Please keep it up!

Cash
217 days ago

I added a "Keep the DOM simple" item. The river is a good example of excessive markup - 6 divs and 1 paragraph tag for a single river entry.

alfalive
217 days ago

Cool xhtml means that we get width and height for images code in future...   :)

 

<img src="http://community.elgg.org/mod/profile/icondirect.php?lastcache=1251220846&username=brett.profitt&size=small">http://community.elgg.org/mod/profile/icondirect.php?lastcache=1251220846&username=brett.profitt&size=small" border="0"  title="Brett"  /></a>

smeranda
217 days ago

This is my vanilla install of Elgg 1.7, with the river overwriting the dashboard. This chunk is from the main content:

<div id="two_column_left_sidebar_maincontent_boxes"> 
 
<div id="content_area_user_title">
<h2>Welcome John Doe</h2>
</div>
<div id="river_container">
<div class="contentWrapper">
    <div id="elgg_horizontal_tabbed_nav">
        <ul>
            <li class="selected" ><a onclick="javascript:$('#river_container').load('http://localhost/workspace/Elgg/mod/riverdashboard/?type=&content=&callback=true'); return false;" href="?type=&content=">All</a></li>
            <li  ><a onclick="javascript:$('#river_container').load('http://localhost/workspace/Elgg/mod/riverdashboard/?type=&display=friends&content=&callback=true'); return false;" href="?type=&display=friends&content=">Friends</a></li>
            <li  ><a onclick="javascript:$('#river_container').load('http://localhost/workspace/Elgg/mod/riverdashboard/?type=&display=mine&content=&callback=true'); return false;" href="?type=&display=mine&content=">Mine</a></li>
        </ul>
    </div>
   
    <div class="riverdashboard_filtermenu">
        <select name="content" id="content" onchange="javascript:$('#river_container').load('http://localhost/workspace/Elgg/mod/riverdashboard/?callback=true&display='+$('input#display').val() + '&content=' + $('select#content').val());">
            <option value="all" selected="selected">All</option><option value="object,thewire" >The wire</option>        </select>
        <input type="hidden" name="display" id="display" value="" />
        <!-- <input type="submit" value="Filter" /> -->
    </div>
<!-- </div> --><div class="river_item_list">
    <div class="river_item">
        <span class="river_item_useravatar">
            <div class="usericon">
<div class="avatar_menu_button"><img src="http://localhost/workspace/Elgg/_graphics/spacer.gif" border="0" width="15px" height="15px" /></div>
 
    <div class="sub_menu">
        <a href="http://localhost/workspace/Elgg/pg/profile/jdoe"><h3>John Doe</h3></a>
                    <p class="user_menu_profile">
            <a href="http://localhost/workspace/Elgg/pg/profile/jdoe/editicon/">Edit profile icon</a>
        </p>
        <p class="user_menu_friends">
        <a href="http://localhost/workspace/Elgg/pg/friends/jdoe/">Friends</a>   
    </p>
    <p class="user_menu_friends_of">
        <a href="http://localhost/workspace/Elgg/pg/friendsof/jdoe/">Friends of</a>   
    </p>
        </div>   
    <a href="http://localhost/workspace/Elgg/pg/profile/jdoe" class="icon" ><img src="http://localhost/workspace/Elgg/mod/profile/graphics/defaulttiny.gif" border="0"  title="John Doe"  /></a>
</div>
 
        </span>
        <p class="river_item_body">
           
<a href="http://localhost/workspace/Elgg/pg/profile/jdoe">John Doe</a> posted a message to the wire<div class="river_content_display">Hello World!</div>            <span class="river_item_time">
                (yesterday)
            </span>
        </p>
        <div class="clearfloat"></div>
    </div>
    </div></div></div>
</div>

Based on what should be presented, here is my simplification of the DOM (I also have striped much of the JS, as these could more easily be targetted with jQuery selectors, but that's for another discussion.)

<div class="three_col"> <!-- Can we split into 4, standard reusable columns? -->
<h2>Welcome John Doe</h2>
<div class="contentWrapper">
    <ul id="elgg_tabs">
        <li class="selected"><a href="?type=&content=">All</a></li>
        <li><a href="?type=&display=friends&content=">Friends</a></li>
        <li><a href="?type=&display=mine&content=">Mine</a></li>
    </ul>
    <form id="filter_menu">
        <select name="content" id="content">
            <option value="all" selected="selected">All</option>
            <option value="object,thewire" >The wire</option>
        </select>
        <input type="hidden" name="display" id="display" value="" />
        <input type="submit" value="Filter" /> <!-- uncommentted out for accessibility reasons, could be hidden with JS if not desired -->
    </form>
    <ul class="item_list river">
        <li>
            <a href="http://localhost/workspace/Elgg/pg/profile/jdoe" class="icon" ><img src="http://localhost/workspace/Elgg/mod/profile/graphics/defaulttiny.gif" title="John Doe" alt="John Doe Profile Icon"  /></a>
                <div class="sub_menu">
                  <h3><a href="http://localhost/workspace/Elgg/pg/profile/jdoe">John Doe</a></h3>
                    <ul>
                        <li><a href="http://localhost/workspace/Elgg/pg/profile/jdoe/editicon/">Edit profile icon</a></li>
                        <li><a href="http://localhost/workspace/Elgg/pg/friends/jdoe/">Friends</a></li>
                        <li><a href="http://localhost/workspace/Elgg/pg/friendsof/jdoe/">Friends of</a></li>
                    </ul>
                </div>
        <p class="item_body"><a href="http://localhost/workspace/Elgg/pg/profile/jdoe">John Doe</a> posted a message to the wire</p>
        <blockquote>Hello World!</blockquote>           
        <p class="item_time">(yesterday)</p>
    </li>
    </ul>
</div>
</div>

alfalive
216 days ago

@morgar

This code in header produce many errors

	<script type="text/javascript" src="http://community.elgg.org/_css/js.php?lastcache=1264780321&js=initialise_elgg&viewtype=default">http://community.elgg.org/_css/js.php?lastcache=1264780321&js=initialise_elgg&viewtype=default"></script>

How are you got this working?
Some things can be escaped but I don`t know if this working.

I see also you use
/1264553048?
instead
?lastcache=1264780321&

is it the equivalent?

morgar
216 days ago

@alfalive not sure what are you talking about. Do you mean that code produces errors running the w3 validator? For passing it, all '&' in urls must be changed to '&amp;'. Validator generates many errors for every '&' ocurrence.

About the lines you mention, no, they are not equivalent, but I guess I didn't change the original one (in 1.5 version). I don't remember, I will check.

morgar
216 days ago

Hmmm, nope, the original lines are different, I have no idea where I got the modified version, but it works :)

alfalive
216 days ago

Ok many thanks for your reply. :)

Mike (vazco)
215 days ago

I would love to see some template system for Elgg at some point - maybe Smarty templates. This could be hard to implement with the current view system, though maybe thanks to caching it would lower the loading time of views. It would also greatly simplify work on the HTML for people who don't know PHP.

I'm already experimenting with Smarty in plugins. If I manage to find a solution that would allow to use it without too much extra work, I will post it to the community.

 

This is another level of complexity though. Asking plugin developers to know SMARTY markup and to use it may be too much...

Carlos
215 days ago

@Vazco.. 

You're right.. I think Elgg devs would find it a little complex to work with Smarty with Elgg's views build. And as you say, SMARTY has its own markup and that's another pain in head. I worked with SMARTY when I did a couple of site with 'Handshakes' from DZoic.. Not fun!!!

Tom
215 days ago

@cash: We already cleaned and are going to valid XHTM; for example have stripped all tables our of out templates we use. All fine with IE6

@brett: IE6 is still used by 50% of our clients: yes all terrible-way-too-big-multinationals, but they pay our bills.

@smeranda: Naming: #elgg_sidebar is still no good; we have this sidebar at the top;) #elgg_page_menu is already better maybe

danielwells
212 days ago

Google not supporting IE6 anymore (in case you missed it).

http://googleenterprise.blogspot.com/2010/01/modern-browsers-for-modern-applications.html

Cash
212 days ago

I agree with what Brett said about IE6:

... IE6 should be supported at some capacity.  If it can be done and isn't a huge drain on resources, it sounds good to me.

@Tom - there is always a limit to how generic you make your markup. For example, 'footer' definitely has information about presentation but since it works for 99.9% of the sites out there and is expected by front-end developers, it makes to use it.

I plan to pull out what rules smeranda used to go from his first markup example to the second. I think that is a useful exercise and helps to validate what we've come up with so far.

Cash
212 days ago

An overview of @smeranda's modifications on post 19 (Elgg needs unique links for each comment!):

  • Don't use a div if you don't need to - avoid divitis!
  • inline javascript was pulled out
  • form was used for the filter to make it more accessible
  • The markup is more generic and uses multiple-inheritence (item_list river rather than river_item_list)
  • lists are used rather than div elements when marking up lists

Did I miss anything?

So far we have not said anything about accessibility or using inline javascript. Do people have any comments on these?

douglerner
212 days ago

Will Elgg stick with XHTML rather than move to HTML5?

Thanks,

doug

 

Cash
212 days ago

Doug - you may find this link useful in understanding how HTML5 relates to XHTML: http://dev.w3.org/html5/spec/Overview.html#html-vs-xhtml

Of course, this link is a lot more fun: http://www.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip/

douglerner
212 days ago

Thanks, Cash. I will look that all over!

doug

p.s. Posts here still seem to be slow, don't they?

morgar
212 days ago

There is at least one case where I'm not sure what is the right decision about inline javascript. The case is when you have an element list, like this thread for example, and you need a delete link for every one of them. As you can't use numeric only IDs or any other attribute for identifying the elements, using a jquery single call you must do some kind of ID parsing for knowing what was the clicked link.

What do you think?

douglerner
212 days ago

Cash, reading over the cartoon version :) it seems that XHTML1 transitional (which is the doctype for the page) can be simply interpreted as HTML 5 by changing the the doctype definition.

But XHTML2 is dead, right?

Thanks,

doug

smeranda
211 days ago

@morgar regarding the inline JS, in this case would there not already be a unique attribute in the markup for each element? Like a href? For accessibity issues, whenever feasable, a JS disabled deprecation should be available, therefore the href for the delete link should go to a page where the unique ID is passed. With JS, we could simply sniff out that unique ID from the href, and use it run the AJAX delete function.

Based on abilities such as this, I am in favor of stripping all inline JS. The result will be cleaner markup, central JS code and simplier debugging.

@Tom I understand the sidebar can be defined in a presentation connontation, however I was going for a content connontation (items placed adjacent to the main content). Nonetheless, your suggestion for #elgg_page_menu is valid. However, as Cash pointed out, there is a threshold between generic and indistinct markup. This is a balance we're going to need to explore as the markup gets cleaned up.

Cash
211 days ago

@doug - XHTML2 is dead. I think of HTML as defining the tags and XHTML as defining a set of rules for using the tags (lowercase, must be closed, etc.).

morgar
211 days ago

@smeranda I'm not talking about the case of a direct link like <a href="delete.php?id=22"> but when you need to ask a confirmation, or maybe doing an ajax call for deleting the object. Do you mean using the id attribute like <a id="del22" href="#"> and parsing the id in the jquery code?

Brett
211 days ago

@morgar - jQuery allows you to use CSS selectors to bind multiple elements at once.  Ex:

<a class="deleteLink onclickConfirm" href="http://delete_link?guid=1234">Delete message</>

<a class="deleteLink onclickConfirm" href="http://delete_link?guid=3254">Delete user</>

<a class="deleteLink onclickConfirm" href="http://delete_link?guid=6453">Delete file</>

A confirmation prompt can be put on all of these links with one jQuery call:

$('.onclickConfirm').click(function() {

    return confirm("Do you want to delete this?");

});

@smeranda - Accessibility!  I'm glad you're the one who brought this up ;)  Since Elgg is used in government and education facility, it's very important to consider unobtrusive javascript and accessibility.  I know at least the US and the UK have pretty strict laws about accessibility when evaluating if a software can be used, especially in state-funded educational institutions.

The easiest way to ensure accessibility is to write everything WITHOUT ajax at the start and add ajax in later.  This makes sure that links actually work.  When you start putting ajax in, you'll bind to the ajax links, extract the href, and send it to the (currently non-existent) ajax handler.

I hadn't wanted to pollute this thread with my javascript goals or accessibility plans, but it's so hard to talk about just one aspect of this without including everything...

smeranda
211 days ago

@Brett - For us (University of Nebraska-Lincoln), accessibility isn't just a nice feature, it is a requirement by law (at least the federally-funded institutions). We follow the same process: design for a fallback that won't require Javascript and then put in the JS functionality to improve the UX. At the minimum, a user should be able to do all tasks without JS enabled. Advanced features/presentation/effects can be hanlded with JS.

morgar
211 days ago

@Brett, yes, you are right, I know that way. I didn't choose the right example for my point, my fault. The specific case is when you need to do an ajax call and pass the id in the call. But yes, maybe this is not the right topic for discussing this in detail.

smeranda
211 days ago

@morgar I'm inclined to believe all JS functionality can be done without auto-incrementing IDs or inline JS provided the markup and accessibility is carefully thought-out and created. For your example of deleting an item, you could use jQuery to target these links without modifying the markup (not even adding a class):

Markup: <a href="delete.php?ID=22">Delete this item</a>.

$('a[href^=delete.php?ID=]').click(function() {
//We now have all the links to the delete page, let's catch the click and do JS instead.
var IDtoDelete = $(this).attr('href').split('ID=');
//Now we have the ID (22) which can be used in the AJAX call
var confirmDelete = confirm("Are you sure you want to delete?");
if (confirmDelete) {
$.get('delete.php', {ID: IDtoDelete[1]}, function(data) {
alert ("Item deleted: "+data);
//or whatever else we want to do
})
}
return false;
});

*note: untested JS

This is an over-simplified version for illustration purposes. In this case, we wouldn't need to parse out the unique ID (we could just simply use the href value as the .get() page), but I did it this way to show that we can use generic markup to grab an ID and then use that in any function we need.

morgar
211 days ago

@smeranda Thanks for the example. Yes, I guessed the only way for doing this without inline js was doing some kind of parsing inside the function.

Brett
211 days ago

@smerand - What if we offload the id sniffing to PHP since it has handy functions for this already?  If our ajax handler accepts a full URL, it will be dead simple to extract the query params from that...

smeranda
211 days ago

@Brett - Sure, I don't see why that wouldn't work.

morgar
211 days ago

Well, in that case, couldn't ajax call the same href by appending another parameter like $(this).attr('href') + '&ajax=1' directly in the url (it works).

So, no href parsing is necessary in javascript nor php. The same page does the action, returning the result to the ajax call or following the navigation flow is javascript is disabled.

PS: I guess we need a branch thread for this offtopic divagation :)

Brett
210 days ago

@Morgar - That's definitely another possibility.

Cash
196 days ago

I think we're almost done with this thread. What's left?

How about style guidelines? lower camel case or underscores for classes and ids? I think Elgg mostly uses underscores (ex: page_container) with a few lower camel case mixed in (ex: contentWrapper).

smeranda
195 days ago

I don't have a strong preference, as long as they are consistent.

How about using a psuedo-namespace and preferencing all elgg classes with 'elgg_' or 'elggXXX'?

Brett
195 days ago

Having a chat with Pete about this, we're leaning toward using underscores for consistency with the views names.  Consistency is nice :)

Cash
192 days ago

CSS discussion here: http://community.elgg.org/mod/groups/topicposts.php?topic=424690&group_guid=212846