Ionic 5 Dynamically change primary color - css

I am trying to make my Ionic Angular app's color scheme change based on events that happen while using the app. The app is quite large with many components that all need to be aware of the color change when it happens. Ideally I would like to know of a way to have my elements reference a color(s) (let's say --primary) and to be able to change that color in one place and have all the elements respond to the change.
I have not found anything in the Ionic docs that references being able to change the CSS variable definitions at runtime so I have looked at instead swapping which variable I use at runtime.
I have considered listing many different colors in the variables.scss and then using ngClass to apply a globally defined class name that can respond to the change. The downside of this is I would have to anticipate and individually declare each possible attribute that needs the color. For example, I could use [ngClass]="primary-1" to apply a class defined like this:
.primary-1 {
background: var(--ion-color-primary-1);
}
but if I wanted to use an element that needed the background-color attribute I would also need a different class for that attribute:
.primary-1-other {
background-color: var(--ion-color-primary-1)
}
My problem is that I do not want the global class definitions to be aware of the specific element attributes unless there is a concise and comprehensive way to do that.
I have also looked into using setProperty but as far as I can tell that only changes styles in the specific context rather than the app as a whole.
Any solutions/ideas are appreciated.

This worked for me:
const htmlEl = document.querySelector('html');
htmlEl.style.setProperty('--ion-color-primary', '#0000ff');
Thanks #XML for the hint.

I think what you want is to modify Ionic's Global CSS Variables. They are a bunch of runtime modifiable variables. You're in luck, because in the old days, you could only modify those variables at compile time. Now, there are methods to modify at runtime.
This guide explains how: https://ionicframework.com/docs/theming/css-variables

Related

NativeScript Is there a way to include a css file with a view model instead of by a views

Is there a way to include a css file with a view model and not a view?
I've tried looking at the nativescript documentation and have not been able to find the answer
This view model is used/presented in a number of different views so adding the css classes to each view folders css file works but makes it harder to maintain as I now have duplicate css classes floating about in different folders.
Alternatively i could put it in the global css file however this can quickly become too large of a file if i need to do this for multiple view models/ styles.
Use case:
A list of items that get validated in an async manner which will change css class based on status (simple use case example background-color changes to: white/red/yellow/green).
please note that I am coding a non-angular app.

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.

Strategy for separating styling from dom manipulation

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.

Flex change values of custom Skin at run time

I have built a basic theme for my Flex app. I would like to add support for additional predefined themes. By default, app has a theme and I would like it to change when user selects a theme from dropdown list. This can be done by loading a swf file using styleManager. However, all the skins have colors hard-coded in them. So, in order to achieve this I would have to duplicate skins and change value of the colors.
Is there a better way of doing this? Can I just have a skin that will change color values dynamically based on user selection?
The best way is to move all hard coded colors from skin to the css.
You will have to update your custom skins to take advantage of that.
so if you have a <SolidStoke color="0xff0000" />
you need to replace it by <SolidStroke color="{getStyle('yourCssPropertyName')} />
Another way to do it is to write your skins so they have references to their host components (see [1]). Then you extend the current host components so that they have properties for each color you want to specify (e.g. instead of using , you'd use with borderColor and fillColor as new properties).
Honestly, though, Florian's answer is probably the better way to go.
[1] - http://www.adobe.com/devnet/flex/quickstarts/skinning_components.html#host

check if css class exists in the stylesheet file in code behind

I control styles for a set of pages in a common utility method. What i would like to do is check the .css file to see if a css class exists; if it does then pick it, else pick the default.
say PageA.aspx and PageB.aspx both use styles.css that contains .default{...}
if i wanted PageA.aspx to be styled differently, i would just add another entry in styles.css .PageA{....} etc. At runtime, it will search for a css class named PageB, since it does not find it, it will default to the default class.
Question is how do i check the .css file to find out if a particular css class exists in the code-behind.
Thanks
The simple way would be to apply the default style, and then the pageA style. The browser should ignore the pageA declaration if it doesn't exist.
However I think the Right Thing™ would be to handle this in ASP or use separate files as Seb suggests.
Many questions in SO ask for a particular solution but don't state the real problem behind, so it's difficult to answer properly.
But I suspect what you're asking could be achieved far easier by splitting styles in 3 different files and including just what you need:
styles.css: common styles for PageA and PageB
styleA.css: rules applying only for PageA
styleB.css: rules applying only for PabeB, but with the same name used in styleA.css
Then, you include styleA.css or styleB.css depending on which page you're showing and that's it.
If this doesn't answer your question, then you might post what's your real problem instead of the solution you're trying to code - which might not be the best solution.
BTW: I don't think there's a way to know which CSS classes are defined; you just set and unset them.
You could load the css file using a StreamReader (since it is a text file) and search it line-by-line using the String.IndexOf() method, but that wouldn't be very efficient for every page load.
Your question doesn't make a lot of sense, but since CSS is not a programming language, if you want to know what's in another file, you're going to have to do it somewhere else.

Resources