CSS overriding UI properties - with or without !important - javascript

I want to override default Dropdown properties that belong to react semantic UI
Here is my dropdown:
<Dropdown
placeholder="User"
selection
compact
options={userOptions}
/>
The text in my dropdown has too much padding so in my CSS I removed it like so:
.default.text {
font-size: 10px;
padding: 0;
}
I got rid of the padding from the Dropdown icon as well:
.dropdown.icon {
padding: 0 !important;
}
However, as you can see this only worked when I used !important
Related questions:
How come the icon padding only works by using !important -- the text padding did not need !important
I hear using !important is bad practice. Should I avoid using it at all costs? How else do I override these properties / What are best practices?

Use a higher css rule specificity, like:
.somegrandparent .someparent .dropdown.icon {
padding:0;
}
How come the icon padding only works by using !important -- the text
padding did not need !important
Your one rule is working without !important as it might already have a higher specificity whereas the other did not.
I hear using !important is bad practice. Should I avoid using it at
all costs? How else do I override these properties / What are best
practices?
It is "ok" to use to override external libraries sparingly. But if it is possible to override by a higher specificity that is preferred as it will be easier to debug css conflicts / bugs.

Related

How to apply styling for 3rd party css framework like bootstrap

Im working on react web app which has less file for its styling. As
shown below, EnPage is a 3rd party component, which has content within
it, Actually the main element class "page-body" has some styling
issue, so I want to overwrite it with a styling fix
<div class="Banner">
<EnPage>
<div class="page">
<main class="page-body"> ...</main>
</div>
</EnPage>
</div>
when on hovering over in chrome devtools, I can see
.page-body {
padding-right : var( --page-content-screen-lg-horizontal-padding , var(--spacing-m));
padding-left : var( --page-content-screen-lg-horizontal-padding , var(--spacing-m));
}
In dev tools, if set these both attributes to 0, then it fixes styling
issue
.page-body {
padding-right : 0;
padding-left : 0;
}
Now how to do this code , like the below?
.Banner {
--page-content-screen-lg-horizontal-padding : 0;
}
Generally third parts materials generate custom classes that style your element. Normally, their classes are inyected after yours, to be sure that their styles have precedence over inherited or previously defined styles.
Things you should try:
1 - Read the documentation of the material library.
Depending on the material library you are using, they may provide a custom way to overpass their basic styles. Some do, other don't. Please be sure to check their documentation to see if this is the case.This is always the best option as you are ensuring the material will work as designed and will not cause any bugs or conflicts.
2 - Give an id to your element and place your custom styles on the id.
This works because CSS styles are defined based on specificty precedence. As ids are more specific than classes, these styles have priority over the ones defined by classes.
Example:
html:
<main class="page-body" id="page-body"> ...</main>
css:
#page-body {
padding-right: 0;
padding-left: 0;
}
3 - If nothing else seems to work and you really need to replace the material style, you could use !important. But please note that this is a bad practice and many state that !important really shouldn't exist in the first place, as if your need to use it is because you are not understanding css precedences rules and you are just hacking the css logics.
Putting this duscission aside, you may place !important after your declaration and this is going to enforce your rule over any other that might exist.
Example:
.page-body {
padding-right: 0 !important;
padding-left: 0 !important;
}
Did I mention this is a bad idea?
If you want to read more about css precedence:
What is the order of precedence for CSS?
https://css-tricks.com/precedence-css-order-css-matters/

Is it possible to disable shadows on all components?

I was wondering if it is possible to disable shadows/elevation on all components through some configuration?
Do you mean box-shadow?
You can use * to set value of a propert for all elements.
This should work in your case:
*{
box-shadow: none !important;
}
!important will overrite all settings to a property
You may or may not need !important. Depends on your other CSS settings regarding box-shadow
This link describes how to customize any Quasar SASS/SCSS/Styl variable (Shadows are defined as variables too).
https://quasar.dev/style/sass-scss-variables
In essence, there are Quasar variables $shadow-0 through $shadow-24 and $shadow-up-0 through $shadow-up-24 that you can override individually. Else you might find it easier to override
$elevation-umbra
$elevation-penumbra
$elevation-ambient
to make them fully transparent, so that the shadows, even though present are not visible.

Disable/Remove default !important declarations in elements

I have a CSS conflict going on with a major plugin in my wordpress site. The plugin maker found it handy to add !important declarations throughout all their styling sheets. From a developer's perspective; this is a disaster. In their defense they want to cover all themes that are using !important declarations, so it looks consistent. I do not agree, so I need a solution.
What happens is that my premium theme, who's not using those declarations, cannot override the styling. I have some solutions to remove certain classes by jQuery.
But there is a problem which cannot be resolved by removing classes. For example, the anchor:hover is default as border: none !important by the plugin. But I would like to see is that the anchor:hover border option is actually applied via the theme settings. The applied CSS is this (be aware that the .plugin class is not applied in the anchor, just from a CSS file):
.plugin a { border: none !important; }
Is there any way I can disable certain class combinations from the DOM? I'm happy to have this done with php or jQuery. Something like: .plugin is not applied to anchor I have no idea how to resolve this.
Surely this is just a case of overwriting the css with a better specified css line.
For example if the code is:
.plugin a::hover { border: none !important; }
You can overwrite this by doing:
body .plugin a::hover { border: 1px solid grey !important; }
Because you have added the element body to your css line it adds extra specificity meaning it overwrites the plugins css. You unfortunately have to use !important, as !important throws regular specificity ruling out the window (bad plugin creator).
More on css specificity here
Do you need any of the styles provided by the plugin? If not then it might be worth looking at dequeueing the plugin styles altogether and just adding your own styles where the theme doesn't cover it.
If you find out the registered name of the stylesheet (should be in the style tag) you can dequeue it with something like:
function remove_push_plugin_styles() {
wp_dequeue_style( 'plugin-stylesheet' );
}
add_action( 'wp_print_styles', 'remove_pushy_plugin_styles', 1000 );
You aren't able to edit an iframe's content, true. But the iframe's itself still belongs to your page, and you can edit the attributes. I just tested and was able to do something similar to:
var i = $('div.item iframe');
// Did the selector work?
console.log(i.length);
i.removeAttr('width');
i.removeAttr('height');
That being said, using !important in this situation is not bad. If you're worried about CSS maintenance, leave a comment that the !important is overriding the element's attributes. !important is often demonized, but in this case it is a valid use to increase the specificity of your CSS.
The advantage of doing it in CSS is that it will apply before your JavaScript is loaded, so you won't get a split second of those attributes and styles applying before the JavaScript removes the styles.

CSS specificity beat inline with !important

Here is my site: http://stage.samkeddy.com/
It's responsive using a couple media queries and a mobile menu button powered by javascript.
Here is the javascript for the menu button:
function toggleMenu () {
if (menuIsVisible == false) {
collapsibleMenu.style.height = 'auto';
content.style.paddingTop = '290px';
menuIsVisible = true;
}
else {
collapsibleMenu.style.height = '0';
content.style.paddingTop = '80px';
menuIsVisible = false;
}
}
so you can see that I need to adjust the padding at the top of the content div, in order to offset the menu
But if resize to the mobile size, open the menu, and then resize back to the desktop size, the padding isn't fixed by the media query, because there's still an inline style from the javascript. I tried making the padding on the desktop version !important, but it the padding still doesn't change when resized, even though according to this !important beats inline.
You can test for yourself by opening the size (how it should look), resizing to a mobile width(the nav will disappear, and you will see the menu button), clicking the menu button (leave the menu open), then resize the site back to a desktop width. You will see the padding is still there. If you inspect it, you can see the original padding is crossed out in favor of the inline style.
I know this would be possible by monitoring the width with javascript and setting the padding then, but I really don't want to do that, and don't think I should have to.
EDIT: solved
First, I should have been adding classes, rather than adding CSS with my javascript.
Then I assumed that putting !important outside of a media query would make it only show up on desktop, but it took over all media queries. So placing just this in a query made it work. Note that if I was using 2 separate menus (mobile/desktop), I wouldn't need this, but since it was fixed and the #content needed padding, it had to be done. But using this technique you can also use only a single menu, but doing the height for the menu this way. I've demonstrated the technique in a codepen: http://codepen.io/anon/pen/JFvay
Adding this code to your stylesheet should solve the problem, I just tried this on your website using the Developer Tools and it's working:
#media only screen and (min-width: 643.2px) {
#content {
padding-top: 80px !important;
}
}
Although I'd strongly recommend you to create a separate navigation menu for mobile devices and resort to using #media-queries to display it.
Your problem at heart is that you're mixing CSS and in-line styles. As a general rule, avoid placing specific CSS properties directly on elements, whether in HTML, by using element.style.<property> =, or via jQuery's .css() feature. Instead, you should define the properties you want as CSS rules, using classes:
#collapsible-menu { height: auto; }
#content { padding-top: 290px; }
#someelt.menu-visible #collapsible-menu { height: 0; }
#someelt.menu-visible #content { padding-top: 80px; }
where someelt is some higher-level ancestor element. Then, your JS becomes simply
function toggleMenu() {
document.getElementById('someelt').classList.toggle('menu-visible');
}
If you are targeting browsers which do not support classList (see CanIUse), jQuery provides its own version of class toggling.
CSS is not an imperative language, but if you want, you can think of the #someelt.menu-visible part of the last two rules above as a kind of if statement: "If menus are visible, then shrink collapsible-menu to zero height", etc. In this metaphor of CSS as a kind of programming language (which it is), the presence of the menu-visible class of #someelt could be thought of as a kind of boolean "variable", I suppose. Most likely, you will no longer need a corresponding variable in your JS.
Anyway, the advantage of this is that people looking at your code can see all your CSS-related logic just by looking at the CSS file, instead of having to look at both CSS and JS, and you can change CSS-related things in just one place.

remove / reset inherited css from an element [duplicate]

This question already has answers here:
How to reset/remove CSS styles for a specific element or selector only
(17 answers)
Closed last month.
I know this question was asked before, but before marking it as a duplicate, I want to tell you that my situation is a little different from what I found on the internet.
I'm building and embedded script that people can put it on their sites. This script creates a div with a certain width/height and some information in it.
My problem is that some websites declare styles for div that are inherited by my div as well.
for example:
div{
background-color:red;
}
so if I don't set any background color to my div, it will show red even if I don't want that.
The only solutions I come along is to overwrite as many css proprieties, this way my div will show exactly as I want.
The problem with this solution is that there are too many css proprieties to overwrite and I want my script to be as light as it can be.
So my question is if you know another solution to my problem.
It can be in css/javascript /jQuery.
Thanks
"Resetting" styles for a specific element isn't possible, you'll have to overwrite all styles you don't want/need. If you do this with CSS directly or using JQuery to apply the styles (depends on what's easier for you, but I wouldn't recommend using JavaScript/JQuery for this, as it's completely unnecessary).
If your div is some kind of "widget" that can be included into other sites, you could try to wrap it into an iframe. This will "reset" the styles, because its content is another document, but maybe this affects how your widget works (or maybe breaks it completely) so this might not be possible in your case.
Only set the relevant / important CSS properties.
Example (only change the attributes which may cause your div to look completely different):
background: #FFF;
border: none;
color: #000;
display: block;
font: initial;
height: auto;
letter-spacing: normal;
line-height: normal;
margin: 0;
padding: 0;
text-transform: none;
visibility: visible;
width: auto;
word-spacing: normal;
z-index: auto;
Choose a very specific selector, such as div#donttouchme, <div id="donttouchme"></div>. Additionally, you can add `!important before every semicolon in the declaration. Your customers are deliberately trying to mess up your lay-out when this option fails.
You could try overwriting the CSS and use auto
I don't think this will work with color specifically, but I ran into an issue where i had a parent property such as
.parent {
left: 0px;
}
and then I was able to just define my child with something like
.child {
left: auto;
}
and it effectively "reset" the property.
Technically what you are looking for is the unset value in combination with the shorthand property all:
The unset CSS keyword resets a property to its inherited value if it inherits from its parent, and to its initial value if not. In other words, it behaves like the inherit keyword in the first case, and like the initial keyword in the second case. It can be applied to any CSS property, including the CSS shorthand all.
.customClass {
/* specific attribute */
color: unset;
}
.otherClass{
/* unset all attributes */
all: unset;
/* then set own attributes */
color: red;
}
You can use the initial value as well, this will default to the initial browser value.
.otherClass{
/* unset all attributes */
all: initial;
/* then set own attributes */
color: red;
}
As an alternative:
If possible it is probably good practice to encapsulate the class or id in a kind of namespace:
.namespace .customClass{
color: red;
}
<div class="namespace">
<div class="customClass"></div>
</div>
because of the specificity of the selector this will only influence your own classes
It is easier to accomplish this in "preprocessor scripting languages" like SASS with nesting capabilities:
.namespace{
.customClass{
color: red
}
}
Try this: Create a plain div without any style or content outside of the red div. Now you can use a loop over all styles of the plain div and assign then to your inner div to reset all styles.
Of course this doesn't work if someone assigns styles to all divs (i.e. without using a class. CSS would be div { ... }).
The usual solution for problems like this is to give your div a distinct class. That way, web designers of the sites can adjust the styling of your div to fit into the rest of the design.
As long as they are attributes like classes and ids you can remove them by javascript/jQuery class modifiers.
document.getElementById("MyElement").className = "";
There is no way to remove specific tag CSS other than overriding them (or using another element).
you may use this below option.
<style>
div:not(.no_common_style){
background-color:red;
}
</style>
now , if their any place where you do not want to apply default style you can use 'no_common_style' class as class.
ex:
<div class="no_common_style">
It will not display in red
</div>
From what I understand you want to use a div that inherits from no class but yours. As mentioned in the previous reply you cannot completely reset a div inheritance. However, what worked for me with that issue was to use another element - one that is not frequent and certainly not used in the current html page. A good example, is to use instead of then customize it to look just like your ideal would.
area { background-color : red; }
One simple approach would be to use the !important modifier in css, but this can be overridden in the same way from users.
Maybe a solution can be achieved with jquery by traversing the entire DOM to find your (re)defined classes and removing / forcing css styles.

Categories