Bootstrap 4 Sass - changing theme dynamically - css

New to sass I stuck with the problem how to enable the dynamic change of a website theme - lets say a dark and a light theme - through user interaction. The template I use as a base (coreui) has a _custom.scss file in which various variables are defined
...
$navbar-bg: #fff;
...
The values of these variables would need to be set dynamically depending on the user choice of the theme and I have no clue how to get this done. Any pointer how to implement this would be highly appreciated.

SASS is a preprocessor which means essentially it gets compiled down into regular CSS and then shipped to the client. If you want to change themes you'll have to dynamically load different stylesheets using javascript.
Case 1
In the case that you want the user to pick between multiple prepackaged themes. This can easily be done with multiple "theme" style sheets which import the various parts of your style. First import the different colors, then import the main bodies of your sass. For example:
theme1.sass:
#import 'theme1';
#import 'base';
#import 'other';
theme2.sass:
#import 'theme2';
#import 'base';
#import 'other';
Then in javascript you could remove the old stylesheet and add the new one when the user does whatever is needed to change the theme. For example inside the onclick of a button you could put:
document.getElementById('cssTheme').setAttribute("href", "/path/to/theme");
It's probably best to take a bit of care and put the element in the head of the document, but this is a good starting point. That could be made to look a lot nicer with Jquery, but I didn't want to assume you'd have that.
Case 2
In the case that you want the user to dynamically change colors of individual element colors it might be worth looking into CSS Variables. Current support in IE/Edge is crumby but it is pretty interesting. Then as the user changes the fields you could just be changing the css variable in a <style> tag somewhere on the page and it should propagate through the document.
If you want more browser support then I think really the best way would be with OK sure's answer. This one gives you the benefit of just changing a variable and not having to reset each element style that uses that variable.

You have 2 options I think.
Option 1) Recompile the styles whenever a change is made by running a command serverside to generate a new CSS file for the user. This will be potentially very resource hungry and probably not recommended.
Option 2) Take the variables you want to be accessible, find where they are mentioned in the bootstrap source and either generate a file or just inline these styles after the stylesheet is included in the template.
So for your example here, depending what language you're coding in, or templating (this is a twig example) you're using, you could inline the following in the head of your template:
<style>
.navbar {
background-color: {{ user_theme.navbar-bg | default('#eeeeee') }}
}
</style>
It's tough to tell you exactly how to do this without knowing what frameworks/languages/infrastructure you're using.
If you were using Twig & PHP for example, you could send a user_theme object to the template, and have an include file which contains all the styles that need modifying with default values as above.

Related

Can CSS #import be set inside a class when using SCSS or SASS? Syncfusion example

I have the following structure but can't get it to work.
The first CSS rules get always overwritten by the second import, no matter if the body class is light or dark.
Is there a way to do it purely with SCSS?
base.scss:
body.light {
#import './light';
}
body.dark {
#import './dark';
}
_light.scss:
#import '../../node_modules/#syncfusion/ej2-base/styles/material.css';
_dark.scss:
#import '../../node_modules/#syncfusion/ej2-base/styles/material-dark.css';
Greetings from Syncfusion.
We have checked this and we would let you know that we have already logged a feature request for this support that we can track using the below feedback portal.
Feedback: https://www.syncfusion.com/feedback/8141/provide-latest-sass-version-support-with-ej2-components
We expect that it will be available with our Volume 3, 2020 release and we let you know the details for dynamically changing theme using SCSS. Until then, we request you to use the below method to change the theme dynamically.
https://www.syncfusion.com/kb/10868/dynamic-theme-change
Please get back to us if you need any further assistance on this.
Syncfusion Components are capable of dynamically generating theme file in compile time as in other third party components. But, we are not able to dynamically generate the themes in runtime as requested in the first query of this thread. We request you to use the methods
suggested in the below KB link for dynamic theme changing in the application.
https://www.syncfusion.com/kb/10868/dynamic-theme-change

Switching sass variables with angularjs

I am working on theme changer with angularjs and I can't seem to find a way how to replace one sass file with another (both of them contains variables) when user changes his theme. I know that when sass is compiled to css the variables are gone. Is there a way to switch up those files and recompile whole css? I have managed to find that it should be somehow possible to do by calling server to recompile css, but I couldn't find more information. Thank you.
One way we are doing these things is having multiple files for different themes. Example content =
variables ...
primary: '#smtng'
.themeName{
.header{
background-color: primary
}
}
And in your app.html you can add class to your html tag which will represent themeName. You can hold theme name in some storage and load it from there.
Basically you are loading all themes, but only rendering css for active theme

How to develop custom theme CSS in Stencil for BigCommerce

For my latest project here at work, I was told to develop custom (Stencil) themes for BigCommerce so we can distribute them via the BigCommerce theme marketplace. I come from a Wordpress background, so making this leap is making my head spin a little bit, but I think I understand how their platform is put together for the most part. There are components which are called by Handlebars expressions, and these may be rearranged in the template files while any default styles can be applied through config.json and the client can make basic changes through the theme editor GUI.
Here's where I'm still lost, though. Some of the design requirements call for heavy CSS changes, not just a JSON variable. I have a fully developed HTML/CSS theme I would like to use by converting it into a format that BigCommerce will accept, but I can't find any documentation on how to go about doing this. I could tediously modify each of the existing SCSS files, or I could override them as if I was developing a child theme. I'm tempted to scrap the SCSS altogether and start over, but then I would need to recreate the SASS functions used to pull in the JSON where needed.
I work much better when I begin with a blank canvas (or at most a rough sketch) and build upon it, rather than morphing a complete product into what I need. Is there any way to do this with BigCommerce?
It's been a little while since I posted this question, and since then I have learned a bit more about Stencil development.
The short answer here is, add on, don't delete. BigCommerce's Cornerstone theme is not a blank theme like _underscores for wordpress. It's a fully developed, yet very basic theme. It's best to avoid editing its default files where possible, because it may be updated in the future and could potentially overwrite your changes. Instead, add folders with your custom theme's name within it. For example, you would normally see:
/scss/layouts/body/_body.scss
So you could add your own styles while leaving the above structure intact:
/scss/layouts/customtheme/body/_body.scss
We do not have to override the styles defined in the former _body.scss, because we'll also need to import your newly created styles into
/scss/layouts/_layouts.scss
In this file, you'll see this snippet at the top:
// =============================================================================
// LAYOUTS
// =============================================================================
// Global layouts
// -----------------------------------------------------------------------------
// Header
#import "header/header";
// Page
#import "body/body";
Since an underscore defines an SCSS partial, we know that just creating _body.scss doesn't do anything. We have to find the main SCSS file and add #import "body", or in this case, we must add it to another partial which gets imported into the main file. So simply delete or comment out the default
//#import "body/body";
and replace it with
#import "customtheme/body/body";
And there you go. You are not overriding or competing with any existing styles, and you've customized the look of the body. You can also add your own components, but that's another topic for another time. Suffice to say, there are more SCSS files in
/scss/components/
and they follow the same principles.
Did you try using the stencil resources provided by BigCommerce youtube channel?
Also, the forums would be a great place to start having a chat for best practice questions.

Twitter Bootstrap LESS css

I am wondering why I cant set variables within twitter bootstrap using LESS. I am using ruby on rails which has a bootstrap_and_overrides.css.less file. it has the following statement
// Your custom LESS stylesheets goes here
//
// Since bootstrap was imported above you have access to its mixins which
// you may use and inherit here
//
// If you'd like to override bootstrap's own variables, you can do so here as well
// See http://twitter.github.com/bootstrap/less.html for their names and documentation
//
// Example:
// #linkColor: #ff0000;
So my understanding is that i can set my variables within here. So i set
#black: #333;
and then tried using it in my application.css calling #black file but it does not work? i.e. doesn’t render #333.
Am i understanding this incorrectly?, do all my variables and css styling go within the bootstrap and override file?
Any advice appreciated
Follow the instructions at http://lesscss.org/#usage to make sure your updated less is used, if you are using it client side.
OR
Compile your updated less into CSS and then copy over the updated CSS.
Here's a list of tools that can do the compile. http://bootstrap.lesscss.ru/less.html#compiling
For suggestions on how to organize your bootstrap modifications see the SO question Twitter Bootstrap Customization Best Practices
As an aside, I wouldn't recommend changing #black. Changing it would alter many, many things, including some you might not expect.
If I understood you correctly, you are modifying your bootstrap_and_overrides.css.less file, but the one being used is the application.css file.
If that was the case, of course it's is just natural not to reflect the changes you've made. You must compile your .less file first to .css. to reflect that changes to your .css file.
For a try, use LESS via the client-side and setup your environment like so:
For instance, in your index.html file, put
<link rel="stylesheet/less" type="text/css" href="application.less" />
in the document head. and below it add
<script src="less.js" type="text/javascript"></script>
Download the less.js file from here. and put it inside your root directory, or you may of course customize the location and make the necessary path in the href attrib.
After doing the above, you're ready to modify your application.less file (not the application.css). You may copy you're existing custom styles from the application.css file.
application.less is where you should put your variables.
You may rename your bootstrap_and_overrides.css.less file into application.less and make sure it is the one linked to in the header tag.
For more info about LESS CSS checkout the wiki.

ASP.NET Themes - Should They Be Used?

I'd been reading up on themes in my ASP.NET book and thought that it could be a very handy solution, then I met some problems.
The theme picks up every single CSS file in the folder
If you want to use reset styles (where ordering is important) the order of imported stylesheets is not guaranteed
Your master page would not explicitly indicate what style is being used, only the rendered page can tell you that unless you dig into your web.config
Styling web controls using the theme file is... well... stupid? You can simply do this in your stylesheet. Granular control should be at the HTML level, should it not?
How do you specify print stylesheets without having all styles in a single stylesheet?
I'm wondering as to whether they're actually worth using at all. Is there any benefit? Are there any major sites using them?
EDIT
Just to clarify slolife's last point. If I had two stylesheets, one called print.css and one called main.css and I used ASP.NET themes, how would it know that print.css was a print stylesheet? In regular HTML you use the media type in the tag itself (i.e. <link rel= ...>) but the themes wouldn't know this, so it would just get included as a regular stylesheet.
I like using themes, but as Raj pointed out in his answer, URL rewriting can cause problems. My search for some solutions to that is what led me to your question. But I'll add my opinions in anyway.
I'll address some of your bullets from above as to why I think themes are good:
- The theme picks up every single CSS file in the folder
I guess you are looking to apply only certain stylesheet files to certain pages. Yes, themes takes the shotgun approach here, so that's a problem. But you don't have to put all stylesheets in the the theme folder. Put your specialized ones outside of it and they won't be included automatically. But I think it is nice feature to have the common/site wide ones included automagically.
- If you want to use reset styles (where ordering is important) the order of imported stylesheets is not guaranteed
I think you can guarantee the order by the way you name the files, so they are numerically and alphabetically ordered. Maybe not an elegant solution, but not horrible.
Personally, I have a build step that combines and compresses all of the *.css files in my theme folder into one single style.css file, and since I control that build step and the order that the files are combined, that doesn't affect me.
- Your master page would not explicitly indicate what style is being used, only the rendered page can tell you that unless you dig into your web.config
You can change the theme via code and in the <%#Page directive
- Styling web controls using the theme file is... well... stupid? You can simply do this in your stylesheet. Granular control should be at the HTML level, should it not?
I agree that applying style attributes to controls via the theme doesn't seem to be a best practice. But I love the fact that I can define image skins in the theme's skin files and don't have to cut and paste Width,Height,AlternativeText,Align attributes for common images that I use lots of places throughout the site. And if I ever change one of those images, I can fix the attributes in one place, rather than all over. I also can created skinned controls with a certain list of css classes applied, which seems handy to me.
- How do you specify print stylesheets without having all styles in a single stylesheet?
I have a Print.css file that starts with #media print and that defines print styles for my site. Why do you need to put them in one stylesheet?
IMHO, asp.net themes are absolutely USELESS
try implementing url rewriting with an app which uses themes and see them break straight away
basically, you can achieve the same thing writing few lines of code in asp.net and multiple css folders. i am yet to come across any developer / company who has been using themes
when asp.net 2.0 was launched, there was a big hype around themes but my personal opinion is its simply not worth it :-)
Use themes to change control attributes ONLY.
They were bad designed for working with css.

Resources