We’ve recently started a small-ish project for a mobile site demo w/.NET4; jquery-mobile has been sensibly chosen to be in charge of client-side functionality and UI interactions.
Requested branding is to differ quite significantly from anything that can be built with a ThemeRoller as it goes beyond the basic color change; this is where (I think) I’m about to hit a dead end.
It is currently my understanding that there is virtually no separation between element presentation and function on pretty much every interactive object, at least with the out-of-the-box library.
Consider the following scenario: we have rounded off-gray gradient tabs that I, with my executive decision (yeah, right), want to make into neat solid pink square (not really, but this should make my question more engaging 🙂
I’d normally add a css rule like .tab-container .tab {background-color:pink;} and be done with it; however given application of data-role attribute to the html element containing those tabs the following happens on the client at runtime (from the jquery-ui…js):
this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
this.lis.addClass( "ui-state-default ui-corner-top" );
this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
…and, when rendered, I’ll get my pink tabs but with all the styling that comes by default. Say, I really want those rounded corners gone; out of the box I have these options:
- add “ui-corner-none” class to the element – bad given that this would have to be manually done for every instance, and also for every property I want overridden making this approach unmaintainable; this would also marginally bloat css etc. etc.
- go into the jquery.ui…css and remove the “ui-corner-all” declaration – bad given that this would affect everything previously relying on the class; also the classes would continue being added at runtime although without visible effect
- go into the jquery-ui…js and remove the class reference from the section as quoted above – bad practice modifying the library itself, what if I want the corners back? likely unmaintainable too it would contribute to non-separation of concerns
- go into the main.css and add semantic classes overriding jquery styling above – solid approach except that every single property will need to be overridden quickly bloating into .tab-container .tab {background-color:pink; -moz-border-radius:0;-webkit-border-radius:0;border-radius:0;} etc.
Currently leaning towards having the majority of semantically agnostic styles removed – I’m a believer that mini-classes are bad and come with similar maintainability issues to those of inline styling.
Quite tempted to look into having brand-specific widgets introduced at least for some elements (i.e. <ul data-role=”awesomebrand-customtabs”>), but it will require a lot more effort and is outside of the scope for this question.
I’m sure something obvious is being overlooked here – please steer me right!
You’re right, in that the way jQuery Mobile uses classes feels a lot like it’s one step away from inline styling. The problem with changing jQuery Mobile’s JS is that it breaks your upgrade path.
This is kind of ugly, but what about our good friend the star selector and
!important? For example, to give the entire app a flat, square look, could be fairly straightforward:If the star selector is too heavy-handed for your uses, you could always specify everything to overwrite as comma-separated selectors (
.ui-tabs-panel, .ui-tabs-nav). No significant CSS bloat, clean upgrade path, and no manually wrangling classes.