Polymer custom style sometimes cascades incorreclty - css

I've noticed that the cascade isn't always correct when using polymer custom style. From the looks of it, this could be a bug in the way the cascade is being applied to custom elements, but I'd just like to confirm that I'm not doing something silly.
Consider the following, scoped style, for my custom element:
#price ::content .price span {
display: block;
padding: 4px;
border-top: 1px solid var(--color-gray1);
}
#price ::content .price span:first-child { border-top: none; }
... but once rendered, the :first-child gets overridden by first definition, as you can see in the image below. The only way to ensure that my border: none is applied correctly, is to use !important, which I'd rather not.
I should note that I've seen this behaviour in many other places, and have opted to just use !important as a quick solution, but this starts to feel clunky.
Just adding the image of the rendered element here to show the "incorrect" top border.

From what I’ve understood, the problem comes from the CSS variables/custom properties polyfill.
It adds another class, .product-0 in this case, to scope the property where you use var(--color-gray). You probably figured this also already, but just pointing it out.
You can override that with an equally specific selector (no need to use !important), e.g. #price ::content .price.price span:first-child (notice the duplicate .price).
I don’t know if this can be fixed in the polyfill.

The first declaration is more specific than the second one. This could be the problem.

The Specification of the DOM structure is Major role to override the css.
#price ::content .price span {
display: block;
padding: 4px;
border-top: 1px solid var(--color-gray1);
}
#price ::content .price span more specific than the #price ::content .price span:first-child.

Related

How to apply only custom properties to an element?

In very simple html/css, I have my menu in a <table id="menu">. The menu has no border, however I would like all the other tables in my blog to have borders.
I made it work this way:
#menu, #menu th, #menu td {border: none; color: red}
table, th, td {border: 1px solid black;}
However this is not very robust. If I add something else to tables I might forget to 'reset' it in #menu. Is there a way to force all properties in #menu so that I don't have to override one by one anything I would add to table, th, td {...}?
I tried the :not() selector but it doesn't feel robust either, I would rather specify what I want for menu on the #menu {...} line, not elsewhere. Let me know if that makes sense or I can reformulate
I think that I understand now. I was searching for a way to unset all values for a css class and came across this page: Reset/remove CSS styles for element only
It tells us that we can do something like this to achieve what you want:
#menu, #menu th, #menu td {
all: unset;
color: red;
}
table, th, td {
border: 1px solid black;
}
Notice how I added the all: unset; and removed the border: none;
This should reset all the styles for elements with that id, but make sure to put your other styles AFTER the all: unset, or else it will unset the styles you just wrote. Hope this helps!
Maybe using classes instead of id's.
If you use a class you can apply a css rule to all elements that have It
So for example to your table you can use
.custum-table
The prevoius class Will apply css styles to all elements
And finally if you wanna apply another css rule you can add another class to your element in this way
Another html file
.custom-table__no--effect
Previous class with BEM Will apply css styles to only one element for example table element

Why does a descendant selector override a class selector?

I have classes like this:
.tableGeneric tr td
{
text-align: center;
vertical-align: middle;
border: 1px solid black;
}
.tdValignTop
{
vertical-align: top;
}
When I apply these classes, I expect that a td with class .tdValignTop would be vertically-aligned to the top, even when .tableGeneric tries to align it to the middle. However, it would seem that I am wrong: the table cell would use .tableGeneric's styles instead of .tdValignTop's styles.
Here's a fiddle to demonstrate.
So... why? Isn't a specific class style/selector supposed to override base/parent styles? Is there some kind of logic or reasoning behind this behavior? I assume the behavior is intentional, but I cannot find any documentation on it.
What you think of as “specific” is not more specific in the CSS sense, and it is CSS specificity that matters when applying CSS. The CSS specificity rules define specificity on terms of the syntactic structure of a selector. In this case, the first selector has one class name and two element names, so it is more specific than the other, which only contains a class name.
This is because the first style rule you defined is more specific than the second, thus it will override.
If you do this it will work as you expect:
.tableGeneric tr td
{
text-align: center;
vertical-align: middle;
border: 1px solid black;
}
.tableGeneric tr td.tdValignTop
{
vertical-align: top;
}
Working example here.

Force to use style for a selector, no matter where it is in the dom

Say I would like to define a numbered circle, that looks like this:
http://jsfiddle.net/edi9999/6QJyX/
.number
{
border-radius: 50%;
width: 32px;
height: 24px;
text-align: center;
padding-top:8px;
font-size: 14px;
display:inline-block;
line-height: 16px;
margin-left:8px;
color:white;
background-color:black;
border-color:white;
}
I would like to add importance to the selector, so that no matter in what context the element is, an element with class number looks the same.
Here's an example of the code breaking: http://jsfiddle.net/edi9999/6QJyX/2/
A way to do this would be to add !important to all properties of the CSS, but I wonder if they could be other solutions, because it is a bit crappy.
I have added the private tag as that seems a bit like code-encapsulation.
Your best option is to increase the specificity of the selector. Other than that there is not much you can do.
#id .number
The ID selector will increase specificity so that only another ID in a selector will be able to override it.
http://jsfiddle.net/6QJyX/3/
Increasing the specificity of selectors will only lead to specificity wars (which leads to anger, which leads to hate, which leads to suffering). I would suggest decreasing the specificity of the selector that's causing the problem.
Pseudo code below:
.number {...}
.card span {...} // this selector is questionable
<div.number> this is styled correctly </div>
<div.card>
<span.number> this is styled incorrectly </span>
</div>
Why do all .card spans need to be styled a particular way? It seems as if the second selector is more like a grenade and less like a sniper—that is, it targets a blanket set of elements rather than just the ones you need.

CSS style for parent instead of child?

I am using jquery to insert html I get from the server into a div. Based on the div contents i'd like to adjust the syle of the container. I wrote up a simple html test. How do I tell css to apply this site when it has X child? After googling I tried :has and :contains with neither working. I don't want to keep my styles in JS as css makes more sense.
Demo: http://jsfiddle.net/wd9fk/
html
<div id="a"><div id="b">B</div></div>
<div id="a"><div id="c">C</div></div>
css
#a { height: 400px; border: 1px solid red; }
#b { height: 200px; }
#a :has #b { height: 300px; border: 1px solid blue; }
You simply cannot traverse up the DOM in CSS. You will need to use JavaScript.
Here is an article explaining why: http://snook.ca/archives/html_and_css/css-parent-selectors
Long story short, it's due to the way CSS is read by the browser, and by introducing it, it would increase the performance hit by a factor of ten (at least!), because it would need to read every single node multiple times to see whether or not it fits the profile.
It's a nice thought, but it's simply not viable.
There is no parent selector for CSS yet, there are plans and it is being discussed though. In CSS Selectors level 4, a subject selector has been proposed, which would let you refer to elements this way:
ol! > li:only-child
Which then reads: “an ol element that contains a single li element” (this syntax is a proposal though), and would let you style the parent ol element.
If this proposal succeeds, subject selectors would be available in the next version of CSS selectors.
For now, Javascript is the way to go, until the subject selector becomes a standard.
You cannot traverse up the DOM to get the parent selector of current matching elements.
But you can do it with jQuery quite easy like this:
$('#Default a span.active').closest('.vehicle_details').css('background-color','#444');
Fiddle Demo
#a > #b { height: 300px; border: 1px solid blue; }
Not sure if this is what you wanted, but give it a try.
Regards.

Why are my CSS properties being overridden/ignored?

I'm having some issues with the CSS "hierarchy" (not sure if it's proper to call it a hierarchy). I'm trying to style the below bit of HTML.
<body>
<section id="content">
<article>
<ul class="posts-list">
<li class="post-item">
<h2>[post title]</h2>
<p class="item-description">...</p>
<p class="item-meta">...</p>
</li>
...
</ul>
</article>
</section>
</body>
Since section#content changes on every page I have, I wanted to maintain consistent styles across all of them, so I wrote some "global" CSS rules.
#content {
color: #000;
margin-left: 300px;
max-width: 620px;
padding: 0px 10px;
position: relative;
}
#content p,
#content li {
color: #111;
font: 16px / 24px serif;
}
I wanted to style HTML within a ul.posts-list differently, so I wrote these rules.
li.post-item > * {
margin: 0px;
}
.item-description {
color: #FFF;
}
.item-meta {
color: #666;
}
However, I ran into some issues. Here is how Chrome is rendering the CSS:
For some reason, the rules #content p, #content li are overriding my rules for .item-description and .item-meta. My impression was that class/id names are considered specific and thus higher priority. However, it seems that I have a misunderstanding of how CSS works. What am I doing wrong here?
Edit: Also, where can I read up more about how this hierarchy works?
Elements id have the priority in CSS since they are the most specific.
You just have to use the id:
#content li.post-item > * {
margin: 0px;
}
#content .item-description {
color: #FFF;
}
#content .item-meta {
color: #666;
}
Basically id have the priority on class which the priority on tags(p,li,ul, h1...). To override the rule, just make sure you have the priority ;)
The "hierarchy" in which CSS rules are measured is called specificity. Each part of a CSS rule has an actual numerical base-10 value. IDs are worth 100 while classes are only 10.
For more information see http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
Targeting ID's is more specific than targeting classes. More specific styling will overwrite less specific styling. It should be noted that in-line styling in HTML is more specific and will therefore overwrite ID-targeted styling. In other words:
<p style="color:white" id="itemDescId" class="item-description">...</p>
With the CSS:
p{color:blue;}
#itemDescId{color:red;}
.item-description{color:green}
The text will appear white - not because it's closest to the html code, but because it's higher in the specificity hierarchy. If you remove the inline styling (and you normally should for cleaner more manageable code), then the text would become red. Remove the ID and it will be green. And finally it will be blue once the class is removed.
This is one of the more complex topics to understand in CSS, and I'm only scratching the surface, but the easiest description I've found on how CSS specificity works is over at CSS tricks:
http://css-tricks.com/specifics-on-css-specificity/
My response should have been a "comment" on the answer, but I have the correct fix although #tibo answered correctly:
li.post-item > * {
margin: 0px !important;
}
.item-description {
color: #FFF !important;
}
.item-meta {
color: #666 !important;
}
The !important rule will override the order of evaluation between id and class.
Here is a link to an article, When Using !important is The Right Choice, that will help you to understand... it made my life easier :)
Better to follow the CSS standards.
choose css selector and makeit under its parent then u may not to get conflicts when loading css fles (like .css files)

Resources