I'm working on a product where we want to introduce customization of the back-office per user. Back-end is pretty much handled, but front-end make me wonder...
1/ Would you handle the thing in the same minified stylesheet with layout--* classes such as:
.section--dashboard {
background-image: url('not-funny.jpg');
}
.layout--2k17 .section--dashboard {
background-image: url('funny-trex.jpg');
}
2/ Or would you add additional stylesheet such as:
<link ... href="http//myapp.co/.../style-default.css" />
<link ... href="http//myapp.co/.../style-{{ user.layout }}.css" />
All code is overly simplified here.
Customizations would be minor ones: feature enabling (beta-testers or A/B testing), putting emphasis on this particular action for this user, or change an icon that one use complained about.
It's not meant to be full-fledged theming (that we have, theming system per company/brand, which is shared by all users of that company and involve complex layout changes and additional features). This is only for low complexity changes or ensure backward-compatibility at most.
For those wondering, I've created a system similar to modernizr where I can put some classes on the body and handle it via CSS and a JS object that exposes which "things" is enabled or available.
if ('2k17' === Appizr.layout) {
// Enable this new search component
} else {
// Boring search component
}
When you say "per USER" are you being literal in that sense? EVERY user can have their own? Nobody else sees it?
If so -- and I RARELY if ever would say this -- it belongs in a style="" attribute in the markup. This is NOT something I'd be making a static file for every joe-blasted user for any more than I would generate CSS from the server-side code on the fly IF that user is the only one that would ever see it.
Now, if this is per-user but multiple different users would see it, THEN I'd write it to a separate file for that user's account and load it separate. Whilst I favor monolithic stylesheets for the base template of any system so as to keep the number of handshakes low, per-account settings that OTHER users will see can save you bandiwidth from a caching standpoint. So if this was something that a user would set that OTHER users would see, THEN give it its own stylesheet.
This sounds like a perfect use-case for CSS Variables, if you can handle the browser support for them :)
In the case of your app, for each thing you wanted to possible expose as a user-settable value in your CSS, you could replace it with
var(--variableName), where--variableNameis a name you're inventing to store this information. Suppose we want to let users set a background image on the page, and an avatar image they they see. You could write some CSS like this:.avatar { background: var(--user-avatar); } main { background: var(--user-bg); }Here the
backgroundis set using CSS variables. You'll want to initialize them with a default value, this can be done by including a rule like this somewhere in your CSS::root { --user-avatar: url(path/to/default/avatar.png); --user-bg: url(path/to/default/bg.jpg); }Now we should see the default avatar and background on our site. All we have to do to override this with a user preference is include the following in CSS, HTML, or JavaScipt:
CSS
:root { --user-avatar: url(path/to/user/avatar.png); --user-bg: url(path/to/user/bg.png); }HTML
<style> :root { --user-avatar: url(path/to/user/avatar.png); --user-bg: url(path/to/user/bg.png); } </style>JS
document.documentElement.style.setProperty('--user-avatar', 'url(path/to/user/avatar.png)') document.documentElement.style.setProperty('--user-avatar', 'url(path/to/user/bg.png)')You can use whichever language is most convenient for you to output, but as long as these variables are re-declared with the user's specific values after the default values are set, the CSS above will display the correct value in the right place :D
Hopefully this helps solve your problem or at least gives you a few new ideas about how to approach it!