Markup standardization recommendations to make theming faster and more reliable
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
Re: Markup standardization recommendations to make theming faster and more reliable
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!
Re: Markup standardization recommendations to make theming faster and more reliable
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
Re: Markup standardization recommendations to make theming faster and more reliable
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
Re: Markup standardization recommendations to make theming faster and more reliable
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.
Re: Markup standardization recommendations to make theming faster and more reliable
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.
Re: Markup standardization recommendations to make theming faster and more reliable
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).
Re: Markup standardization recommendations to make theming faster and more reliable
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.
Re: Markup standardization recommendations to make theming faster and more reliable
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.
Re: Markup standardization recommendations to make theming faster and more reliable
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.
Cheers
Mary
Re: Markup standardization recommendations to make theming faster and more reliable
Since I added that span, let me try to justify it:
There are two separate purposes here:
- A container around the main body content of the page for layout / styling purposes.
- 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>.
Re: Markup standardization recommendations to make theming faster and more reliable
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/
Re: Markup standardization recommendations to make theming faster and more reliable
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.)
Re: Markup standardization recommendations to make theming faster and more reliable
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.
Re: Markup standardization recommendations to make theming faster and more reliable
Why do we need the id as well as the name? I may be missing something, but it just seems redundant.
Re: Markup standardization recommendations to make theming faster and more reliable
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.
Re: Markup standardization recommendations to make theming faster and more reliable
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.
Re: Markup standardization recommendations to make theming faster and more reliable
Re: Markup standardization recommendations to make theming faster and more reliable
Re: Markup standardization recommendations to make theming faster and more reliable
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
}