React changes the sequence of CSS rules applied after the deployment to remote - css

I created a page with a resizable panel on the bottom using react-resize-panel lib.
I had to change the alignment of the elements inside the divs generated by the <ResizePanel> component provided by the lib.
<ResizePanel> creates three levels of elements:
I needed to override the margin-bottom property of the child with the class name ResizePanel-module_ResizeBarVertical__2LUZV. Likely, the suffix is generated dynamically, so I had to use the CSS selector to override it:
[class^='ResizePanel-module_ResizeBarVertical'] {
margin-bottom: 0;
}
Tested it locally and it worked as expected. But when I deployed to remote the sequence of the CSS rules applied changed and my custom style was overridden:
I would like to get a better understanding of how CSS is loaded locally and remotely. In particular, is there any rule of thumb for local testing when it comes to React styles and conflicting CSS rules
UPDATE with solution
There are two solutions suitable:
narrow down the selector to div only (selected this one based on best practices)
div[class^='ResizePanel-module_ResizeBarVertical'] {
margin-bottom: 0;
}
use !important in the style
[class^='ResizePanel-module_ResizeBarVertical'] {
margin-bottom: 0 !important;
}

CSS Precedence could be tricky sometimes, there should be 3 "levels", sorted by highest priority:
!important (you can force override; should solve your problem, but probably doesn't fully answer your question)
specification of selector (how much specified the selector is; seems like what you are struggling with – your custom selector is less specified, so it has lower weight)
order; what was declarated first (there could also be problem with cache; but that's probably not your case)
More info about the selector specificity weight in the Mozilla docs:
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

Related

CSS precendence in shadow DOM <style>

What do the CSS precendence rules say about the <style> tag in shadow DOM?
I have an element <component class="component">, a CSS file included in <head> with:
component {
display: inline-block;
}
and a <style> tag inside some shadow DOM with:
::slotted(.component) {
display: block;
}
If I understand it correctly, the first rule should have a specificity of 0.0.1 as it has one element and the second one specificity of 0.1.1 as it has one pseudo-element and one class. Therefore, the second one is more specific and should override the first one. This doesn't happen though. In the developer's console (Chrome) I see both the rules and neither of them crossed out and in the "computed styles" panel I see 'display: inline-block'.
A more detailed example as requested in the comments:
<head>
<style>
/* "other-component" related styles: */
other-component {
display: inline-block;
}
</style>
</head>
<body>
<some-component>
#shadow-root:
<style>
slot[name=some-slot]::slotted(*) {
display: block; /* Only works with !important. */
}
</style>
<slot name="some-slot"></slot>
<!-- The actual ("light-dom") content: -->
<other-component slot="some-slot"></other-component>
</some-component>
</body>
This behaviour is defined in the CSS Scoping Module Level 1 Draft §3.3:
When comparing two declarations that have different tree contexts, then for normal rules the declaration earlier in the shadow-including tree order [the first, global rule] wins, and for important rules the declaration coming later in the shadow-including tree [the second, ::slotted(*) rule] order wins.
Note: This is the opposite of how scoped styles work.
In other worlds:
Styles that applied before distribution continue to apply after distribution.
We might have the most in-depth explanation of the design at https://github.com/w3c/csswg-drafts/issues/2290#issuecomment-382465643
A few reasons went into the current design:
We purposely didn't involve specificity at all. Doing so would expose implementation details of the component, which makes code fragile - if the component is updated and changes the exact selector it uses, it might start overriding outside rules that previously won, or vice versa, and there's no good way for the component's user to understand or manipulate this.
So we have to decide in some other way. Document order (the final cascade step) doesn't really work here - it adds an unexpected dependency on exactly how you load the custom element, and might have interesting race
So we're left with Cascade Origin, or something close to it, that just unreservedly makes one or the other win. Actually injecting a new origin into the list didn't seem like a great idea; it's unclear how user vs author stylesheets should interact with this. So instead we add another cascade step for this.
And finally, we have to make a decision about which wins. We already know that whatever order we choose, !important should have the reverse order; this is how the cascade origins already work. So we have to decide whether the outer page wins by default, but the component wins in !important, or the reverse. We decided that the former made more sense; this means that the component author's normal styles are "defaults", the component user's styles (!important or not) can override that, and the component author's !important styles can be used to "lock down" styles that need to stay how they are. Going the other way around didn't seem to satisfy use-cases as well: it would mean that component users can't override styles by default; they'd have to use !important to do so, possibly interfering with their other styles; and then component authors would have no way of "locking down" styles.

CSS Priority and Hierarchy

This will probably be an extremely easy question to answer, but I am trying to create a one-stop-shop for setting up property values from SQL and would like to know an answer to the issue that just came up in brainstorming:
If you set a parent (let's say a form) to be Read-Only but set an object (lets say a button) in that parent to NOT be Read-Only, will the button be read-only? Also, what If the parent or child had !Important included?
I am trying to set up a priority system so users can set up these kind of property values without running into issues where unexpected things do not happen.
readonly is not a css property, thus no style. It goes directly into the html tag.
The key buzzwords for you to search are css inheritance and css specifity.
For a quick overview: Yes, there are fixed rules. Not every property is inherited. You can look them up e.g. in the MDN CSS Reference.
Which css rule kicks in depends on where you place the style rules and how specific your selector is.
Cascading order (source):
Inline style (inside an HTML element)
External and internal style sheets (in the head section)
Browser default
Specifity is like a score system. The rule with the highest score (=highest specifity) applies.
ID, e.g. #paragraph {...} (100 points)
Class, e.g. .redparagraphs {...} (10 points)
Tag, e.g. p {...} (1 point)
So the rule div p span {...} would have a score of 3 points, because of three tag selectors.
#wrapper .centered #main .fancynews .withoutborder p {...} would have 231 points and so on.
If two rules have the same score (specifity), then the last one processed counts (stylesheets are processed from top to bottom).
The "quick and dirty" trick for applying a style is to add an !important to the rule like
.alwaysredtext { color:#F00 !important; }
This will override whatever color rule you made and whereever (as long as they do not also have an !important). This is not recommended due to later maintainability problems.
p.s.: Don't miss the Specifity Calculator where you can enter and compare several selector rules and see which one "wins".
Only <input> and <textarea> elements support the readonly attribute, so not, what you are describing is not possible.

Remove all the styling from elements which have inline styling using CSS

Suppose I have some html like this -:
<div style="blah...blah">Hey Nice</div>
<a style="blah...blah">Great</a>
How do I remove all the inline styling applied to the above elements in my stylesheet considering I don't know what all inline styling exists.
Currently I am trying this, but in vain -:
div[style], a[style]{ !important }
You must reset all css properties for elements that have style attribute:
[style] {
position: static !important;
float: none !important;
border: 0 none !important;
margin: 0 !important;
padding: 0 !important;
outline: 0 none !important;
// and so on
}
There are several determining factors determining which CSS property prevails in any situation. In order, these are:
Whether the property value has the !important flag or not.
If the style declaration is applied inline via the style attribute.
The strength of the CSS rule selector
If the rule has any ID clauses, and if so how many
If the rule has class, attribute or pseudo-class clauses, and if so how many
If the rule has any tagname clauses, and if so how many
If the property is parsed later in the source than another property with a rule of the same strength
So the only way to override the properties is to make sure that all the properties applied via style are applied elsewhere in your stylesheet, and have the !important declaration. The most rational way to do this is still very awkward — it would involve applying a very specific reset stylesheet, and including !important on every property on every rule.
But even if this is done, you still couldn't override inline style declarations that have !important themselves.
You've told Mojtaba that there should be a better solution, but that better solution would involve designing CSS to break its own rules. Imagine if there was a simpler solution for overriding inline styles from stylesheets designed into the language of CSS — should there also be another solution for simply overriding the override from inline styles? Where does the cycle end? All in all, I'd recommend using Javascript or giving up. Or describing your specific problem in more detail — there may be another solution!
If you're not happy with using !important overwrites in the CSS (as suggested by others on here), the only way would be to use JavaScript to remove the styles.
This is really easy in jQuery (better if you're able to assign a class name to the elements to select it with):
$('.selector').attr('style', '');
This will simply replace the element's 'style' attribute with nothing, thus removing the inline styles.
This isn't ideal though since it will rely on the visitor having JavaScript enabled, and may well result in the visitor seeing a style 'flash' as the page loads: the styles assigned in-line to the element before the JS kicks in and removes it.

Can a CSS selector reference another selectors property?

I've just noticed that Webkit now has some support regarding the CSS Values and Units Module Level spec. And I was wondering if anyone knows if there is a way to reference another CSS selectors (or DOM style) property from a CSS selector?
I'm expecting something like this to be the answer here. Which I know is most likely the case for current browser implementations; but please keep reading...
For instance, in the case where an animation might resize an element (NOTE the ${.element2.width} is fictitious syntax):
<style type="text/css">
.element1 {
.width: /*-webkit-,-o-,-moz-*/calc(80% - ${.element2.width});
}
.element2 {
.width: 100px;
}
.element2:hover {
width: 200px;
transition: all 0.4s ease-in-out;
}
</style>
In this case I would expect the .element1's width to be re-evaluated based off the transition triggered from the hover events on .element2.
I realize that the aforementioned spec. is only a working draft but perhaps the syntax for referring to such a 'referential selector property' is defined within another spec. which I'm yet to discover? Or simply just not a case for concern (thanks to an overlooked work around)?
I added an answer to the question you linked: https://stackoverflow.com/a/11071806/137626
You can use the same declaration block with as many selectors as you want by grouping them (selectors are separated by commas)
You can't reuse the same declaration block later with a different CSS selector without rewriting the whole declaration block preceded by this selector or using a preprocessor/macro that'll do that for you. Or add it to the existing declaration block as above
Now with your example of an element resized by CSS itself: you could use CSS3 Media Queries and its #media rules containing as many declaration blocks as you want. These media queries would adapt to the width of viewport here.
Mixing expanding elements via animation and media queries that would've the reverse effect will be very soon very complicated (and I'll wonder what content you're playing with); if you want to Keep It Simple, then JS is the way to go. There are variables, loops, events ;) and you can start a CSS3 animation by adding or removing a single class from an element (or whatever CSS selector).
CSS3 won't replace JS (and you shouldn't use JS to style HTML as JS isn't activated or existing everywhere and there's already a nice fallback named CSS).
Other than using a pre-compiler such as sass/scss or less, I believe all you can do is wait or hard-code it.

Best-practice approach to reset CSS styles on a specific element?

I'm building an html5/js/css application that will exist inside of a div on my client's existing html. I want to be sure that none of the client's CSS styles are inherited by my app.
Is there a best practice to reset this div and its descendant elements?
I'm thinking I'll use something like:
#my-id * { //styles }
I'm wondering if there is a better/best-practice approach? Thanks.
That will be very difficult/likely impossible to ensure. The type of solutions that Starx is referring to assume no preset styles other than the browser defaults, and "reset" in that context refers to harmonizing the inconsistencies across various browser defaults.
But in your case, your client CSS may already contain highly specific selectors such as
#someDiv .aClass a{float:left;}
... and applying those "CSS reset" solutions simply will not override this.
You can see that Truth's selectors also have lower specificity than this, and therefore will fail to ovetride the client's styles in such cases.
Your question is very similar: How to remove all inherited and computed styles from an element?
So the short answer is: there is no way to ensure this because you cannot "remove all inherited and computed styles from an element" ... update: ...unless you can anticipate and override every preexisting style declaration with new declarations having appropriate specificity.
If you want to only recent this specific div, than what you have is fine. You forgot to reset the div itself though:
#my-id, #my-id * { /* styles */ }
You are probably looking for Eric's CSS Reset as it one of robust resets out there.
But the reset rule is applied to the whole page, instead of the just the box. SO, modify the rules, by keeping #my-id infront.

Resources