Split out base stylesheet between public pages and admin dashboard - css

I have updated a rails app and now want to use different base styles and variables between the public pages and the admin dashboard.
What is the cleanest way to do this?
I am using SASS and have a base.scss which contains mostly typography changes and I want to use different sheets whether in public pages or admin pages.
I have a class of admin on the html tag, but using this (html.admin h1 for example) overrides custom styles on the page.
Is there a way to do this based on the controller possibly?

Thanks to Fabrizio's comment, I've managed to resolve this.
Because two different layouts are used, I was able to create a separate application.scss sheet, import the original application.scss first and then any overrides come after. Then include the new stylesheet in the <%= stylesheet_link_tag %> instead of the original one.
I did need to add this to the assets.rb precompile, but other than that, it works like a charm!

Related

react pages css is getting mixed up even though in seperate folder for both pages

I have 2 different pages sign-in and signup both are in separate folders with their own index.css(1 index.css for 1 page) but they are somehow using each other's CSS. if I make changes in one CSS file it also reflects on another page. I have imported them into their respective pages. I am kinda new to development.. please help.
you should add a specific classname for each tag in your project same classes take same styles
add class names in different files, not make them unique the best practice right now is to use CSS Modules. Check here for more info :
CSS Modules React document
with them, you can have the same name in different files, which react make them unique automatically

Using two style.css for the same react app

I am trying to use two snippets as components from bootsnipp, and each snippet has its own css. i tried to put them both in the style.css, but it ended up damaging one component for the other to look fine.
I'm thinking about how to use both these styles.css, since in the index.js i can only import style.css.
can i use router to use multiple pages, and import style.css in the second page? but wouldn't that mean i'll have to use the second page as app.js, which is called only once in react? this is kind of confusing me.
EDIT: can I put the css of one component in another css file, and then import it INSIDE that component instead of index.js?
it doesn't bother me by the way whether i put that component inside index.js or not; in fact, I'm not going to use it there.
I would say you need to deal with the global namespace issue. You could create two components with its own css file.
Then add a unique className to stop collisions.
The benefit here is that you could also enable code spitting, so you would only load html/css/js when you need it (see React.lazy).
—-
By trying to load two styles in different times or manners you will still have the same issue of conflicting styles.

Bootstrap 4 Sass - changing theme dynamically

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.

How to apply separate SCSS files to separate views in Rails

I'm currently working on landing and login/signup pages, and am trying to apply different stylesheets to each layout. I've tried making a separate layout page for my home controller and calling it in my home controller with layout "home". My app/views/layouts/home.html.erb file is pretty much the same as application.html.erb, except that I changed the stylesheet_link_tag from <%= stylesheet_link_tag "application" %> to <%= stylesheet_link_tag "home" %>. Though the styling from my login/signup pages is no longer applying to my landing page, my landing page now no longer has any of the styling given to it in my app/assets/stylsheets/home.scss file. Is there more I'm supposed to change in my layouts file than just the stylesheet_link_tag, or am I setting up separate stylesheets for each view improperly? If so, what's the proper way to do it?
i wouldn't recommend changing this<%= stylesheet_link_tag "application" %>, instead, in my opinion, best way is to create a folder in assets/stylesheets for each controller you have. for example: i have home_page_controller.rb i would create a folder in assets/stylesheets as home_page then i would make a scss file e.g show. this allows me to navigate to my files easily. of course you can have your different approach but thats my take on it.
I figured it out and got it to work by putting <body class="controller-<%= controller_name %>"> in my application.html.erb file, and placing whatever styling I wanted for my "home" views under .controller-home
Since rails generate scaffold generates CSS and JS files with the same names as the controller you generate it might be intuitive to think that these files will only be loaded by that controller. That's not the case. They're loaded globally by default, and that's sort of the point.
Like Marv-C said, I wouldn't recommend changing <%= stylesheet_link_tag "application" %>. In production mode, Rails optimizes your CSS by loading all of it into a single file.
This also means you can structure your CSS documents any way you want. You can eliminate overlap between CSS documents by using sensible class and id-selectors (which you should).
If you take advantage of SASS nesting, it should be no problem at all.
http://sass-lang.com/guide

Can I use CSS assets and the public folder in the same app?

I have a legacy application that I'd like to migrate to use the Rails 3 asset pipeline. I have upwards of 100 stylesheets which are imported on a template by template basis using a
content_for :stylesheets
block.
Compiling them all into a single stylesheet is not currently a goer as the code was written to expect only certain stylesheets on certain pages, so for example the login page imports a stylesheet which redefines article form. It would not be good to redefine this on all pages.
Is there a way to migrate slowly to the assets pipeline having the app look first for a compiled asset, and then having it failover to the public/stylesheets directory?
If you want to do this "right", one thing that would not take a huge amount of effort would be to put a class name on your <html> or <body> tag and wrap the contents of your CSS files with a selector. For example, I use something similar to the following in my ApplicationController.
before_filter :body_class
def body_class
controller_name = self.class.name.gsub(/Controller$/, '')
if !controller_name.index('::').nil?
namespace, controller_name = controller_name.split('::')
end
#body_classes = ["#{controller_name.underscore}_#{action_name} ".downcase.strip]
#body_classes = ["#{namespace.underscore}_#{#default_body_classes.join}".strip] if !namespace.nil?
end
Then, in my layout I have something similar to this
<body class="<%= #default_body_classes.join(' ') %>">
Next, you could change the extension for all of your stylesheets to .css.scss. Put them all in the new app/assets/stylesheets directory. To include them quickly (though possibly out of order), add
/*
* =require_tree .
*/
to the top of a new app/assets/application.css.scss file. Just include this one application.css file in your layouts.
<%= stylesheet_link_tag "application", :media => 'screen' %>
Finally, spend some time going through your stylesheets wrapping the entirety of each document with the appropriate body class. For example, if you have a stylesheet specific to some User::Admin controller's signup action, you would wrap the entirety of that stylesheet with
.user_admin.signup {
/* Your stylesheet's content here */
}
Sass will prefix all nested content properly with the .user_admin.signup class that will be appended to your <body> tag when that action's being rendered.
I realize this isn't really an intermediate fix as you're looking for, but following steps similar to this you should be able to get 95% of the way there with not much effort, and it will be done "right".

Resources