Strategy for separating styling from dom manipulation - css

I'm looking for suggestions or pointers to best-practices for segregating classes used for browser styling from those used for dom manipulation.
More specifically, we're creating a single-page, backbone.js webapp that utilizes jQuery extensively for updating page elements dynamically (adding, hiding and appending new content to the page). The problem we're running into seems to originate with the overloading of the class attribute - it's used for styling presentation, AND for identifying page elements for GUI app logic via jQuery. This causes problems when it comes to modifying styles as there is no obvious way to know whether a given class (or DOM element for that matter) is required by the underlying javascript application.
In other words, if someone naively changes or removes a class on a tag, assuming they are only modifying presentation, it breaks the application. I'm looking for a way to separate these concerns - to keep the classes used for jQuery selectors separate from those used for CSS styling. I'm assuming this is a 'solved problem' as we're obviously not the first to write a javascript heavy webapp. Is there a standard way to deal with this? Am I missing something obvious?

The good way to do it probably not to use css classname for binding JavaScript logic at all. HTML5 introduces a way to add custom user-defined attributes for tags. To do it you simply add attribute to tag but start it's name with "data-" prefix. For example:
John Doe
jQuery, starting from 1.4.3, have build-in methods to work with such attributes using .data() function. You can read about it in more details here: http://api.jquery.com/data/#data-html5
If it is necessary for your app to use classnames as pointer for some reason, then you can make following convention:
Classnames starting with "js-" prefix are only used buy scripts to identify html elements, and you can't use them for styling. So this way your elements will have multiple classes on each element (some for styling, some for logic):
John Doe
This way classes without prefix can be removed without concern, and you can be pretty sure that you will broke something if you remove class with prefix.

Related

how to extract some css rule from an external stylesheet that's expecting a different layout

For an organization I work for, there is a common stylesheet that all web applications are supposed to use.
For example, they expect some elements to be in thead.table-sortable th.table-sortable-sorted-down a:after to add a sorting icon. Now, in an Angular application, I use a component library (primeng) that has a simple element that just has the class .pi-sort-up for the same thing.
How can I map / copy /use part of the organization css into my application's css, to just copy the interesting stuff without requiring the complicated nesting on component (which I have no real control on anyway)?
We could use css, sass, or even dynamically generate css rules in javascript. I'd prefer avoiding changing the DOM at runtime for all matching components, as it could be quite dynamic.
EDIT: A build-time solution (e.g. with sass) isn't the preferred way, but could be acceptable if nothing else.
If the company style sheet is readonly for you, there is not much you can do at all. You will have to load the whole document wherever you need some parts of it. A possible "workaround" to avoid that would be to write a backend program (in PHP or node.js) which opens the company style document and looks only for a specific CSS rule which it then copies and pastes to some other style document.
However, this approach would be very dynamic as well and you needed to execute the backend script with each request, for the original company style sheet could change always... If your company could agree, you should use a preprocessor like SASS or LESS and define a structure for the company style, dividing it into several documents that can be loaded on purpose.

How to manage clashing third party CSS

I'm working on a web application which is using Materialize as a front-end framework along with Kendo UI for the grid component.
I'm hitting problems in cases where both Kendo UI and Materialize have styles for the same element - for example they both override the styling on check boxes - this results in a broken layout due to the clash.
One option I realize is to pick either Materialize or Kendo UI and drop the other... however I would like to avoid this if possible as they in the most part have complemented each others weaknesses well.
If it was simply one element here or there putting specific overrides in would be an option however with the scale of the two frameworks this would be a maintenance nightmare as when one changed the overrides would possibly have to be refactored.
Are there any ways to solve this issue that I am missing?
One way to workaround such a clash is to build your MaterializeCSS to include only the parts you so need for your project.
For instance, if you do not need the buttons styling of MaterializeCSS, you could simply, via sass, compile the materialize.scss and cherry pick buttons out of the file.
If going down the path of building your custom .css of Materialize is a long short for you, you can try using materialize.khophi.co (Disclaimer: I built it).
Find more about how to customize your MaterializeCSS: http://materializecss.com/getting-started.html
I know it's usually suggested not to duplicate code, and you want to try steering away from overrides, but would it be possible to find the section of css you like (i.e. select box from materialize) and copy that in to a new custom css file, renaming the selector so you can use it seperately from Materialize/Kendo UI?
You can manually edit the stylesheet of eighter party. Take the non-minified CSS, and prepend every base path with a short prefix:
.card {
....
}
becomes
.mat.card {
....
}
That way, for every materialize style, you use .mat before anything. Or, if you mainly use materialize, do the same thing for Kendo UI.
This is a lot of pain, but would solve your issue.

Are there any Chrome-specific techniques to scope/isolate CSS?

I'm writing a Chrome extension that injects HTML into a displayed page. I want the injected HTML to have it's own style, protected from the CSS that may be present in the host page.
I've tried using conventional CSS, and still suffer from style corruption from the host page.
After watching the Polymer presentation from I/O 15, I was wondering if there are any new, Chrome-specific techniques that I can use to achieve this?
What you will want to look into is shadow-dom. This will enable you to create a widget/component (which would be your injected html). This would mean that the DOM tree for the widget/component is encapsulated and no external styles from the page will affect it. There is a good article on html5rocks covering this. You may also want to look into WebComponents. Bear in mind that this functionality is only available in the latest browser versions.
Two things that I currently use at my place of work are:
css-modules
react-css-modules
I use react at work, hence react-css-modules, but css-modules should work in your case. It's not Chrome specific, but we use them within the context of each component we build. Basically, like the docs state, a class of row would become something like table__row___2w27N. The breakdown of the built name is the filename of the CSS than the class name followed by a base64 hash of 5 char. I hope this helps.
One potential downside is Webpack would be required.
Here is an example of our component folder structure:
- component
- Component.jsx/js
- component.css/scss/sass
- component.test.js

Edit CSS in browser cache

I am building an app on top of webkit, I need to modify a CSS file (edit a selector), which I can do once the page is loaded using Javascript. In my particular scenario I may load the page many times and I would like to mutate the CSS in the cache (using Javascript, as opposed to hacking webkit). Any ideas?
Without entirely understanding your use case I see at least three cheap and fast methods to override some styles:
use one of the many bookmarklets out there (e.g. this one by Paul Irish) to play around injecting styles or
use a short snippet of javascript ondomready to inject a stylesheet with selectors and styles into the head of the document (similar to the bookmarklet above) or
define a specific enough CSS selector and simply include an inline style element in your document (which I would not suggest)
All three methods are basically the same. Depending on what you have, are able to edit or want to achieve either method may be more suitable.
User stylesheets or extensions like Stylebot for Google Chrome may be another possibility to look into.
Weird stuff like loading referenced stylesheets via javascript's XHR, get the content of the file, modify or inject stuff and reapply the styles to the current document are possible as well but probably not what you're looking for.

GWT CSSResrouces - what's the advantage or the best way

Hey, I'm developing a GWT app and now facing the CSS part. I read a lot about this topic at the official site but still have a few questions and hope someone can give me a hint.
When I'm using CSSResource the css styles will be compiled into the code - right? So it's not possible to change it without recompile the app. But what I wanna do is to have the styles be editable from "outside".
So what is this CSSResource for, since you can't just change a color or an image without compiling the app again?
Whats the best way to use CSS since there are a few ways (.css file, CSSResource, styles in ui.xml) to do this?
My thoughts are now, that I'm using only the normal CSS file to handle all my "changeable" stuff and add this file to the head, since I can't see the advantage of this CSSResource thing. Hopefully someone can help me with that. Thanks.
It all depends on the way you work with CSSes - if you need to apply some small changes, first test them "live", in Firebug/similar tool. During the designing phase (when you don't have a finalized view of how you want to style your application yet), you might want to work with normal CSS files, but as soon as the general style clarifies, you should switch to ClientBundle/CssResource.
Why? Let me answer, by writing up some thought about the goals listed on CssResource's documentation page:
Primary
Compatibility with non-GWT-aware CSS parsers (i.e. any extensions should be valid CSS syntax)
This does not imply that the stylesheet would necessarily make sense if you just displayed it in a browser - meaning, we want to only use valid CSS syntax, not some syntactic sugar that's gibberish to other parsers - might not be that important from your point of view (although, as a result, you don't need to change the syntax of your existing styles)
Syntax validation - very important point, IMHO. You get stuff like checking for missing (possibly misspelled) CSS classes, syntax errors, etc. - something that had to be (usually, painfully) tracked down via some browser specific developer tool (Firebug). Here, you get those errors early, during compile time (or even faster, with the help of the Google Eclipse Plugin).
Minification - this is not your run-of-the-mill minification, you get also selector and property merging. See the next point too.
Leverage GWT compiler - if a CSS class is not used (the GWT Compiler can make such a distinction, since it has the overview of the whole application), it is pruned and not included in the compiled code. How many times have you found CSS classes that were left there after some design changes? This takes care of that (see also the CSS modularization point)
Different CSS for different browsers, automatically - since the CSS generated this way is included with your JS code, it can (and is) optimized for the target browser - no need to include lengthy IE hacks in every permutation!
Static evaluation of content - already mentioned it before
Secondary
Basic CSS Modularization
Via dependency-injection API style - you can inject CssResources as needed (for example, to facilitate custom themes in your application)
Widgets can inject their own CSS only when it's needed - this is one of my favorite points, although at first I didn't see its significance - you divide your (usually) huge, monolithic CSS file into small modules, one for each Widget that uses UiBinder (which in turn uses CssResource internally) plus probably one global CssResource for application-wide styles. This results in a much cleaner, easier to maintain CSS styles (at least, in my experience). This also means, that if your code doesn't use that particular Widget (maybe because you've used ocde splitting and it hasn't been loaded yet), you won't download those styles.
BiDi (Janus-style?) - bidirectional text support, haven't used it but the docs look promising :)
CSS image strips - automagical image sprites generation - what more can I say? ;)
"Improve CSS"
Constants - I've always missed this feature in the CSS specification - when you change your primary colour, you have to find & replace it in the whole file (possibly leading to some errors, where you want to use the old colour in some places) - this makes it more intuitive, IMHO, by introducing constants (via valid CSS syntax and without any runtime penalty)
Simple expressions - you should skim through the docs to see the possibilities there, really cool stuff
Tertiary
Runtime manipulation (StyleElement.setEnabled() handles many cases) - on stylesheet injection (during runtime), some values are evaluated - this allows for skinning, etc.
Compile-time class-name checking (Java/CSS) - already mentioned the (obvious) benefits of this
Obfuscation - this one is really cool too, the GWT Compiler can safely obfuscate all the styles in CssResources, because it has the overview of the whole application - thus, name clashes are impossible. This means that you can use long (but not too long ;)), meaningful class names, without worrying how that will impact the size of the application - it will all get obfuscated to nifty, short (even 1-2 character long), random strings. This also enables you to define a .warning style in two Widgets and the compiler will understand that these two styles are in different namespaces (different Widgets) and thus should be treated differently (that is, obfuscated to different names).
About style injection
The class StyleInjector allows injecting styles at runtime. Additionally, the CssResource allows (at least according to the docs, I haven't tried it yet) for runtime substitution. For example, when you inject a CssResource containing the following:
#eval userBackground com.module.UserPreferences.getUserBackground();
div {
background: userBackground;
}
The userBackground will get evaluated and injected (as opposed to constants, which are resolved at runtime).

Resources