How to make custom CSS the dominant CSS in Shiny? - css

I have a custom CSS file for my shiny app. I know it is being read, because some of the elements come through. However, some of the elements are overridden. If I add !important, it fixes them, but there are a lot and this is not good practice. Can I specify my custom CSS always takes priority?
I have tried both methods of hooking in the css and they both do the same job.
ui <- fluidPage(
tags$head(includeCSS("www/my_theme.css")
#tags$link(rel = "stylesheet", type = "text/css", href = "my_theme.css")
),

What you are looking for is named specifity of the css selectors. On the first look it seems to be a complex theme ... but it is not as complicated.
It has do do how many tags/ids/classes had been used to specify a styling.
id are more important than classes
classes are more important than tag (element name like div)
And a higher number off used id/classes/tags in general is more important than stylings which uses less classes (= .a.b.c {...} is more important than .a.b {...}).
Styles noted direct in html (inline-styles) are more important than styles in loaded files.
And some other rules ...
Bringing this alltogether CSS calculates the specifity for a selector.
Here are two links
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
https://specifishity.com/
Practical
// most often it is enough to add one more tag/class/id
// to the rule --> BUT YOU HAVE TO TEST IT ON THE ACTUAL RULE
// before
.classA { ...}
// now to overwrite:
div.classA {...}
// or much higher specifity
body .classOffContainer div.classA {...}
NOTE: but keep it simple for possible debugging!!!
Most often really ONE more 'actor' in the selctor is enough!
SORRY!! -- UPDATE
Here are so many beginners that I did get your question maybe false ...
No. There is no way to rank one css file above another one. Included files are allways get the same specifity value, independend in what order they are loaded.
I am not sure about the following:
Maybe you try to move your css from the css file to the script block in the head off the html file ... but I am not very otimistic that this will get a higher specifity.
UPDATE 2
Just as rough and dirty fast working idea to the problem:
Copy your code in a SASS file.
Wrap the whole code in a html and/or body tag.
That adds a htmland/or body before all of selectors/clases off your css.
Not elegant but fast, generate higher specifity and easy to debug, - and at the end (nearly) nobody cares about a clean CSS.
Add the new generated css file to the project.
// example off SASS file
// to expalyin what I mean:
html [optional: body] {
... your whole css ...
}

Related

Using existing CSS selectors to apply styles across the Shadow DOM to custom elements

This question likely has no single direct answer, but hopefully will lead to some best practices or common patterns to use when adapting an existing styles framework to new web component development.
For my case, I have a component <custom-avatar>, and it's all set up properly with self-contained styles and functionality, everything is just peachy.
In certain use cases, the application display needs to stack avatars, just one slightly overtop one other at a diagonal, and the pattern I'm following is using a simple component <custom-composite-avatar>. All this does is wrap the slotted content in a <div> with the correct styling class, but key aspect is retaining the composability for flexible re-use, like so:
<custom-composite-avatar>
<custom-avatar title="first"></custom-avatar>
<custom-avatar title="second"></custom-avatar>
</custom-composite-avatar>
The tricky bit lies in the styles, which are imported from a monorepo that provides the same BEM-ish CSS and component CSS modules to other flavors of the component library like React, Vue, etc. I have the avatar and composite-avatar styles imported just fine, but forcing the intended overlap display is defined with the hierarchical selector .my-composite-avatar.my-composite-avatar--medium .my-avatar {}
So with .my-composite-avatar class applied to the div wrapper within <custom-composite-avatar> and the .my-avatar class applied to the wrapper within the <custom-avatar> and it's own Shadow DOM, that parent/child CSS selector is no good.
I doubt there is a silver bullet for this, but this seems like it will be a rather common scenario as more people migrate to Web Components while using existing styling systems. What approach makes the most sense to ensure that the composite component remains composable, and adaptation of existing selectors pain-free (or at least easy to communicate to other devs)? can this be solved with ::host or ::slotted, or will these cases require significant re-work?
Thanks for reading, your ideas are appreciated!
I would advice to become good friends with CSS properties
because they trickle down into shadowDOMs following CSS selectors.
CSS Custom Properties(variables)
and getPropertyValue
and setProperty if you want to be brutal and make Custom Elements change the outside world.
example
I have an <SVG-ICON> element taking configuration from attributes OR CSS properties
with my favorite lines of code:
let val = this.getAttribute(attr)
||
getComputedStyle(this)
.getPropertyValue("--svg-icon-" + attr)
.replace(/"/g, "")
.trim();
Allows for your standard attribute configuration:
<svg-icon name="configuration" fill="grey"></svg-icon>
But more powerful (simplified example):
<style>
body {
--svg-icon-fill: "grey";
}
svg-icon[selected] {
--svg-icon-fill: "green";
}
</style>
<svg-icon name="messages" selected></svg-icon>
<svg-icon name="configuration"></svg-icon>
CSS = Custom String Scripting
It doesn't often happen, but sometimes the simplest code makes me very happy.
There is no Styling restriction!
These 2 lines allow any String you want in CSS properties:
.replace(/"/g, "")
.trim();
Example
<style>
[name*="globe"] {
--svg-icon-tile: "rect:0,0,24,24,0,fill='blue'";
--svg-icon-stroke: white;
}
</style>
<svg-icon name="feather-icons-globe"></svg-icon>
The --svg-icon-tile has nothing to do with CSS, it is read (and parsed) by the <SVG-ICON> connectedCallback() code to generate a SVG background/tile for all icons named globe.
The double-quotes aren't required, but without them your IDE will complain about invalid CSS.
Have fun coding... you will pull some hairs when you start with calc() in your CSS properties...
But you can take 'CSS' to another level.
PS.
And monitor the future of ConstructAble StyleSheets aka ConstructIble StyleSheets aka Constructed Sheets aka AdoptedStyleSheets:
https://developers.google.com/web/updates/2019/02/constructable-stylesheets
https://chromestatus.com/feature/5394843094220800
iconmeister

Is there anyway I can prefix over 1000 lines of CSS at once?

I have some h1, h2, h3 and a lot of bootstrap snippets that I want to apply only to a specific part of my site, I added a unique class, say .unique but it would take hours to prefix over 1000 of CSS lines
I use sublime text
Thanks in advance
You could use a CSS-preprocessor like LESS or SASS (there are more). Both can do what you want, by just doing this:
.unique {
// Old CSS goes here
}
The have many other advantages over normal CSS.
common I would like to give you some ideas, cause i think your question has something to do with control css overriding.
the Jost's LESS or SASS solution is very good actually to prefix cause can use nested css features, but it requires a compile process, their eventually compiled files are still css. cause the .less or .sass files can not be recognized for html to render styling.
Another thinking To avoid css conflicts and wrong overriding,
Instead of including global styling, see if you can embed them in part of the specific section/page where they can get higher priorities than the rest global styles.
even the same css, generally, !important > inline css > internal css > external css
or javascript can trigger css override after previous css finished rendering on the page.
Instead of using css priorities or script running priorities to override styles, making two external mobile.css, destop.css for example, then using javascript to reload page to include different stylesheet when device width are detected to have been changed in browser resizing behavior.(This is one pop way used in responsive view)
using IDE to locate css patterns and replace them with your prefix if it's simple to match all the patterns.

Can you change css class precedence at loadtime?

I'm working with jQuery datatables and oTableTools aButtons. I'm doing this:
oTableTools: {
aButtons: [
{
sExtends: 'text',
sButtonText: 'Add +',
fnClick: function ( nButton, oConfig, oFlash ) {/*stuff*/},
sButtonClass: 'btn-success'
}
]
},
My problem is that the a.DTTT_button class on dataTable.tableTools.css:38 is overriding the .btn-success class on bootstrap-combined.min.css:9, so my button is grey instead of green. They are both being loaded from external sources, so I can't edit them, and changing the order in which they are loaded did not affect anything, presumably because the defintion in dataTable.tableTools.css is more specific, what with being specifically for anchors.
Is there a way to force sButtonClass to take precedence over a.DTTT_button at loadtime, or am I going to have to create a new class in my local css file to duplicate the style I want and call it instead? That feels less clean to me, so I'd rather not do it if I don't absolutely have to.
I think the cleanest way given the parameters in this case is actually to create a a.sButtonClass selector in your "local css file" that loads after the a.DTTT_button class. Specificity will match, but the cascade will win for a.sButtonClass. I know you said this "feels less clean," but your contraints of not being able to manipulate the two css files make it one of the cleanest solutions. Also, if you are using a preprocessor (like LESS that boostrap is based off of), then you can have your local enhancement automatically match the bootstrap class by using that class as a mixin for your more specific selector.
However, an alternative is to not apply those styles by a class at all, and write the sButtonClass styles directly to the style attribute of the anchor element, as that will override anything that a.DTTT_button is doing (assuming a.DTTT_button does not have !important tags on its properties).
You can't change precidence unless you want to remove and re-insert the sytesheets into the DOM using JavaScript in the order you want. That's a little ugly, but it can be done.
The proper way is to use CSS specificity, but since you can't edit the external files, manipulating the DOM may be the only way to go.
This may help:
Add: Add stylesheet to Head using javascript in body
Remove: How to dynamically remove a stylesheet from the current page

gwt how to use setStyleName(String style, boolean add) - for a gwt standard widget

I want to style/mark a MenuItem in GWT MenuBar. So i have some logic that adds a style name to a menu item (the logic is working properly).
mItem.setStyleName("menuItemMarked", true);
with this set getStyleName yields "gwt-MenuItem menuItemMarked" as expected.
But how to use/apply this style in css (at the moment i put css in uibinder.xml)? (as you may see i am not a css expert)
update: what i tried is that.
.menuItemMarked{background-color: yellow}
this is not working. if i call "inspect element"(chrome) i can see "class="gwt-MenuItem menuItemMarked" but i can not find the style "menuItemMarked" in the list of applied styles?!
Where are you specifying your CSS?
If your code is located within your code packages, it is likely being obfuscated by the GWT compiler. This applies to <ui:style> blocks in .ui.xml files, and .css files included in ClientBundles.
In this case, you will want to check out Programmatic Access to Inline Styles from the GWT docs. This will allow you to change your code to:
mItem.setStyleName(style.menuItemMarked(), true);
Alternatively, you can tell GWT to not obfuscate certain CSS classes. Here is a detailed answer to a similar question
Finally, if GWT does not touch your CSS file (it is being served from your server like other files), then you will need to make sure that your file is being included in your page properly. Your browser's dev tools should be able to help with that.
Make sure you specify correct selector name in your css. In this case you need to have following:
.gwt-MenuItem.menuItemMarked {
background-color: yellow;
}
Since gwt-MenuItem remains the first class name in the list it takes precedence over any styles (incl. background-color) defined in the subsequent classes. The only way to overrule this is to define styles with more specific selector like above. Check this link out for more detailed explanation.

CSS no-conflict styles

What's a good way to create a no-conflict version of a CSS stylesheet? Let's say you have a bunch of code with classes that overlap with Bootstrap's classes.
Is this valid: adding a class="bootstrap" to the ancestor element under which bootstrap styles should be applied, and then changing bootstrap.css to prefix every rule {} with .bootstrap rule {}?
I've also needed to do this recently with the bootstrap form styles to avoid clashes, and I've found that you can surround all the #imports in the bootstrap.less (or your own custom version) with: .bootstrap { ... } and rebuild bootstrap. Now every CSS selector will be prefixed with .bootstrap.
I don't see any reason that would not work, but there are probably some performance implications to doing that - I'm not sure if they would even be significant enough to consider. It would probably be a better idea to rename the conflicting classes.
Here are a couple of resources to check out:
http://www.vanseodesign.com/css/css-selector-performance/
https://developer.mozilla.org/en/Writing_Efficient_CSS
And this is from Mozilla's CSS efficiency guidelines (2nd link): "This is the key to dramatically increasing performance. The fewer rules required to check for a given element, the faster style resolution will be."
Yes. That is an ugly approach and you will get into DOM Bashing (slower performance). Is there any reason why you couldn't just refactor your code and seperate the bootstrap styles entirely?

Resources