Markup standardization recommendations to make theming faster and more reliable

Markup standardization recommendations to make theming faster and more reliable

by Amy Groshek -
Number of replies: 20
Hello Moodle Theme Designers,

At the Perth hackfest we discussed in detail ways in which we could improve Moodle. Some of our priorities were:
* Responsive design
* Markup standardization for more consistent theming
* Fixing some of the nagging issues which make adoption of HTML5 doctype, including header and footer elements, difficult

You can see the topics discussed here:
http://docs.moodle.org/dev/Perth_Hackfest_October_2012/Responsive_design_and_Theming

As followup to that discussion, I have set down some recommendations for improvements we could make to the markup, often to the output renderers. The idea behind this is that if the markup is more standardized across modules, and easier to test and access using tools like Totara's element library then we can all work faster and have more confidence that our changes look good across Moodle's diverse ecosystem of modules.

You can see the recommendations at the following URL:
http://docs.moodle.org/dev/Standardize_classnames_and_layout_to_facilitate_theming#Additional_classnames_to_allow_for_framework_adoption

Please contribute your critical eye to what I've put down, and let me know what I've missed. What we're trying to do is eliminate the need to check every single page view of every single module when developing a theme, so think about what particular page views are consistently irregular to you, what requires targeted CSS overrides, and why. If it's a matter of making something conform to a demonstrated convention, or it evidences a need for a convention, we should add it to the recommendations in the wiki. Give a good example, a screenshot if possible, and tell others how to replicate.

Cheers,
Amy
Average of ratings: -
In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by Danny Wahl -
Move away from use of IDs as CSS selectors
  • IDs are needed for elements which need identification for JavaScript. Elements which do not need to be accessed or manipulated by JavaScript can be identified by classnames.
  • Wherever possible, CSS selectors should use classnames over IDs.

I'm not too keen on OO-CSS because it doesn't accomplish the stated goal of "making theming faster and more reliable".  For example:

#footer {} - obviously the page footer
.footer {} - could be a forum post? blog? gotta use body > .footer or #region_main + footer or something...

This isn't to say there's not room for improvement, why are there selectors like #page-content #region-main {} when you can use #region-main {} ? or why add class .course-content when that's the only div that uses it (should be ID?) and then have a selector #region-main .course-content {}

I think we should stick with the common CSS practices and work on making it more readable.  For example:

.path-calendar .maincalendar,
.path-calendar .sidecalendar,
.path-calendar td.sidecalendar .block,
.loginbox,
.userinfobox,
.groupinfobox,
.forumpost,
.block .content,
.glossarycomment {   border-bottom-left-radius: 10px;   border-bottom-right-radius: 10px; }

Can we split that out into a couple of rules to make it a little more understandable? (or maybe a .border-round class?) Another example:

.sitetopic .section .activity .commands img,
.course-content .section .activity .commands img {}

WOW! Oh and not to mention it's different than the block selector...

.block .header .commands .icon img {}

which basically output the same thing with two separate sets of rules...

I hope I'm not sounding too complainy I'm really excited for this and would love to contribute in any way possible!

In reply to Danny Wahl

Re: Markup standardization recommendations to make theming faster and more reliable

by Mary Evans -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Hi Danny,

I am in complete agreement with you on the ID selector issue, this needs some careful thought.  The need for collaboration and dialogue is why Amy started this discussion here in the first place, so that we can all contribute and start to move forward on these issues. In fact the more input, we get here, the better.

Thanks

Mary

In reply to Danny Wahl

Re: Markup standardization recommendations to make theming faster and more reliable

by Amy Groshek -
Hi Danny,

Thank you for your contributions. This is some great input. Please keep it coming.

I like your recommendation for a .border-round class. Though I wonder whether we wouldn't want to do something more generic than that, something to which we could attach border-radius, border width and color, and dropshadow. Moodle already uses a .box class heavily but variously. Food for thought.

Different themes are accessing the same IDs and classnames to different effects, so the CSS varies, even across the core themes, somewhat. Where selectors are varied and difficult to read in base or canvas or standard, that is definitely something to refine. Where did you get your examples?

Regarding OO-CSS, I'm not sure #footer is a good example. The reason I say so is that we're already adopting the HTML5 doctype and will probably adopt the HTML5 header and footer tags at some point in the near future. (There are a few JS bugs to work out before that can happen.) Can you reframe your argument against OO-CSS using some other example?

Regards,
Amy



In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

A .border-round class sounds like the wrong approach. It seems to be saying how something should look. The class name should say what a thing is, then the theme should have complete freedom for how that looks.

In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by Danny Wahl -

2nd reply, about renderers.  If renderers need to be updated and possibly rewritten (for revisioning support...) can we please make sure that they conform to the coding style - or modify the coding style to unify the writing methods?  I can't speak for other theme developers but I'm not much of an actual programmer so when I see these different methods to accomplish the same thing it really throws me for a loop (no pun intended) to figure it out:

concatenation
$output = html_writer::start_tag('div', array('class'=>'generalbox'));
$output .= html_writer::tag('a', get_string('purgecaches', 'admin'), array('href'=>$CFG->wwwroot.'/'.$CFG->admin.'/purgecaches.php));
$output .= html_writer::end_tag('div');
return $output;

"stuffing" (probably a real name for this...)
$output = html_writer::tag('a', get_string('purgecaches', 'admin'), array('href'=>$CFG->wwwroot.'/'.$CFG->admin.'/purgecaches.php));
$output = html_writer::tag('div', $output, array('class'=>'generalbox'));
return $output;

nesting
$output = html_writer::tag('div',
 html_writer::tag('a', get_string('purgecaches', 'admin'), array('href'=>$CFG->wwwroot.'/'.$CFG->admin.'/purgecaches.php)), array('class'=>'generalbox);
return $output;

mixing (can be any of the 3 above w/ raw HTML)
$output = html_writer::start_tag('div', array('class'=>'generalbox'));
$output .= '<a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/purgecaches.php' . '">' . get_string('purgecaches', admin') . '</a>';
$output .= html_writer::end_tag('div');

there's more variation out there, and I realize that in certain situations some are better than others (like building a list vs a div w/ a link) but it largely seems to be guided by personal preference.

In reply to Danny Wahl

Re: Markup standardization recommendations to make theming faster and more reliable

by David Scotson -

Since the topic is standardization I'd suggest the easiest and best way to achieve that aim is to have to have the code put into re-usable functions e.g. assuming that your code example is going to be used in more than one place then first decide what standard "semantic" function it provides, let's say it's a footer link :

function footer_link($href, $text)

It's a lot easier to get consistency this way and has the added benefit that those re-usable units can be "themed" independently. This is currently hit-or-miss with some core functions "renderized" and others not, and sometimes there's not enough semantic info provided to decide how to render them (e.g. if I'd used generalbox_link here, then you'd not know much about what the link was for, just that someone had decided that visually it should go in a box, similar to Tim's point about ,border-round).

In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by David Scotson -
A few quick notes,

I asked about the span.maincontent before, I believe it's used for a skiplink, but I think it could be replaced with a link to the maincontent area. See this bug for more:

http://tracker.moodle.org/browse/MDL-34723

Regarding the idea of using Bootstrap classes and Moodl classnames at the same time. It's a good idea, but note that there are some classnames which are used in both for different purposes. I've been documenting them here:

https://github.com/ds125v/moodle-theme_bootstrap_renderers/blob/master/style/undo.css

Often the Moodle usage is inconsistent so I'd vote for solving the clashes by changing the Moodle classnames.

For tables I like the bootstrap idea of .table for tables that are used as tables (i.e. containing tabular data and that you can style with a standard stripey look) since both Moodle and content seem to use table (tag, I put it in pointy brackets and the rest of my comment got eaten) and even .generaltable for things that aren't tabular data.
Average of ratings: Useful (1)
In reply to David Scotson

Re: Markup standardization recommendations to make theming faster and more reliable

by Amy Groshek -
David,

Thanks for pointing me to that tracker bug. I see it was closed. Has anyone looked into whether sending the user to #region-main would not work? Or assigning the #maincontent ID to what's presently #region-main .region-content? Might be worth looking into. My reasoning, as stated in the wiki, is that an otherwise unused span#maincontent is not really semantic. That span is not the main content.

Good to know that yet another theme designer has done some experimenting with a framework. I'll take a look at what you've set down. I think the question of incorporating framework classes is not just a matter of details, at this point, but also a question of overall obstacles, future technical debt, etc. I would really like to hear some opinions about the big-picture aspect of this kind of adoption, both advantages and disadvantages.



In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by Mary Evans -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Hi Amy,

I think you will find, if you delve back far enough, that the reason behind the main content span was a hack, but I may be wrong and getting this muddled with MAIN_CONTENT_TOKEN. smile

Cheers

Mary

In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Since I added that span, let me try to justify it:

There are two separate purposes here:

  1. A container around the main body content of the page for layout / styling purposes.
  2. The optimal destination for a screen-reader (or other) user when they click the "Skip to main content" link at the start of the HTML.

These may, or may not, come at the same point in the HTML. My preference is to keep them separate.

It occurs to me now that <a name="maincontent-skipto"></a> might have been more semantic than <span id="maincontent"></span>.

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: Markup standardization recommendations to make theming faster and more reliable

by Amy Groshek -
Hi Tim,
I agree it's very important that it's there. I also agree that perhaps a modification to the ID would help. a#maincontent-target might be even better. Also, perhaps some text to let folks know they're arrived:
<a id="maincontent-target">Start of main content</a>

Also, if we made that change, it'd be nice for it to have a height of 0px instead of 1px. (I'm looking at the standard theme; no idea if that's in base.)
I went to test it in with VoiceOver on in OS X and was able to jump to the target but focus did not come with me. So I arrived at the target but as soon as I hit tab I was sent to the login info. Looks like it's a thing; you need a JavaScript fix in OS X to make focus travel with the tab. Though I'm not sure how many users actually in need of accessibility features would be using Webkit browsers + VoiceOver.
http://www.refinedpractice.com/2009/06/skip-links-chrome-safari-and-added-wai-aria/
http://whatisdamon.com/blog/2012/01/why-your-skip-to-content-link-might-not-work/
In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

I like maincontent-target. height: 1px styling just seems like a bug to me.

I am pretty sure "Start of main content" is just irrelevant noise. In most situations, I expect the main content will start with a semantic and meaningful header anyway.

Mac OS X has a settings for wether tab just visits form controls, or all focussable things. I think most screen-reader users would switch that settings to tab to all links. (I did not bother to read the links you gave, I mught be wrong about what is going on here.)

In reply to Tim Hunt

Re: Markup standardization recommendations to make theming faster and more reliable

by Mary Evans -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

What about...

<a id="maincontent-target" name="maincontent-target"></a>

This would act like a bookmark woudn't it? Which in turn would be W3C Standards Compatible and also valid in older versions of IE.

Average of ratings: Useful (1)
In reply to Mary Evans

Re: Markup standardization recommendations to make theming faster and more reliable

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Why do we need the id as well as the name? I may be missing something, but it just seems redundant.

In reply to Tim Hunt

Re: Markup standardization recommendations to make theming faster and more reliable

by Mary Evans -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Because IE needs NAME whereas W3C only requires ID, hence my comment about it being W3C compliant and also work in IE,

Pleople need to know that IE does have some oddities and this is one of them.

In reply to Mary Evans

Re: Markup standardization recommendations to make theming faster and more reliable

by Colin Fraser -
Picture of Documentation writers Picture of Testers

Interesting discussion.. but there are a number of consideratoins outside coding and W3C Standards that I suggest need be considered.

Here is a discussion that started out simply, and grew into something that you may want to look at - https://moodle.org/mod/forum/discuss.php?d=216687. It is long and somewhat interminable, but it relates very much to something that Moodle has, I suspect, been avoiding and perhaps not aware of that fact. A large part of the issue, (OK, my issue, but it is going to spread) is around the interaction between Users and the UI, something in which themes are right in the middle of. 

In reply to Tim Hunt

Re: Markup standardization recommendations to make theming faster and more reliable

by Amy Groshek -
Thanks, Tim. I changed the tab settings for Safari and experience a marked difference.
In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by Danny Wahl -
you shouldn't need to use a#maincontent-target over simply #maincontent-target because IDs are unique to a page. It's not like there's also going to be div#maincontent-target (or if there is it's invalid)
In reply to Amy Groshek

Re: Markup standardization recommendations to make theming faster and more reliable

by David Scotson -

So I went back and checked my CSS for places where I'd had to "harmonise" a bunch of different classes, the big ones seem to be marking text as error/warning/success (i.e. red/yellow/green), various types of alert boxes, form layouts and tables.

Note this isn't CSS, it's LESS, basically saying apply the Bootstrap CSS inside the { } to all the classes named before it.

You can see the full file here: https://github.com/ds125v/gumoodle/blob/master/theme/bootstrap/less/moodle/patch.less

Currently I'm trying to fix the problem at the root by rewriting renderers so this HTML doesn't get written out in the first place, but particularly in forms that's not possible so once I've convinced myself I can't fix it in a renderer I'm patching it in a similar manner here:

https://github.com/ds125v/moodle-theme_bootstrap_renderers/tree/master/style/moodle


div.felement.error span.error,
span.error,
span.patherror,
tr.rolecap td.risk.xss a,
div.form-warning {
  .label-important
}
span.warn,
p.warn,
span.editinstructions,
#page-admin-report-security-index span.statuswarning,
span.statuswarning,
tr.rolecap td.risk.spam a,
.form-overridden {
  .label-warning
}
span.ok,
span.pathok,
span.statusok,
font[color="green"],
tr.rolecap td.risk.config a {
  .label-success
}

#page-admin-roles-assign h2 + .box.generalbox,
div.notifysuccess,
div.notifyproblem,
body.admin div.info,
div.box.copyright,
body.pagelayout-report div.info,
div.redirectmessage,
div.adminwarning,
div.forumnodiscuss,
div#notice p,
div.performanceinfo.pageinfo,
div.noticebox,
div#helppopupbox,
div.releasenoteslink,
.errorbox {
  .alert
}
a#closehelpbox {
  .alert .close
}

div.notifysuccess {
  .alert-success
}

#page-admin-roles-assign h2 + .box.generalbox,
div.notifyproblem,
.errorbox {
  .alert-error
}

body.admin div.info,
div.box.copyright,
div#helppopupbox,
div.redirectmessage,
body.pagelayout-report div.info,
div.releasenoteslink,
div.performanceinfo.pageinfo {
  .alert-info
}

/* just one example for forms */
#fgroup_id_buttonar,
#fitem_id_submitbutton,
table#form td.submit,
.form-buttons {
  .form-actions
}

table#explaincaps,
table#defineroletable,
table.grading-report,
table#listdirectories,
table.rolecaps,
table.userenrolment,
table#form,
form#movecourses table,
form#movecourses table,
#page-report-log-user .generaltable,
#page-admin-course-index .editcourse,
.forumheaderlist,
.userprofilebox table.list,
.generaltable {
    .table
}

Average of ratings: Useful (1)
In reply to David Scotson

Re: Markup standardization recommendations to make theming faster and more reliable

by Amy Groshek -
Thank you, David. This is useful for more than a discussion about bootstrap. It exposes the places where we have similar or the same concepts being expressed with different markup.