no-descending-specificity error reported on two different classes - stylelint

I'm using stylelint with the standard format stylelint-config-standard and I'm encountering this error a lot with my stylesheets:
no-descending-specificity
An example of where it's happening is when I have CSS like:
.footer__social li a {}
.footer__social li a:hover {}
.footer__links li a {}
.footer__links li a:hover {}
and then I get the following error:
Expected selector ".footer__links li a" to come before selector ".footer__social li a:hover" no-descending-specificity.
A lot of the CSS will be like this because of using SASS like:
.footer__links {
a {
a:hover {}
}
}
I don't want to have disable this if I can...
But why is it complaining? as it's two separate classes: .footer__social and .footer__links.
So these two declarations for the anchors don't have any effect on each other because they have different parent classes so what's the issue? I'd understand something like:
.footer__links a:hover {}
a {}
But I don't see the issue if it's two different classes...

As Stylint is advising you .footer__social li a:hover {} has a higher specificity (0-1-2 = 3) than the rule that follows it .footer__links li a {} (0-0-2 = 2). You can use this specificity calculator to confirm this.
Source order is important in CSS, hence the warning. This rule cares about specificity, 3 is higher than 2.
From the Stylelint docs (emphasis added):
Here's how it works: This rule looks at the last compound selector in every full selector, and then compares it with other selectors in the stylesheet that end in the same way.
To satisfy the noDescendingSpecificity rule your output would need to be in the order:
.footer__social li a {}
.footer__links li a {}
.footer__social li a:hover {}
.footer__links li a:hover {}
Though personally I would also sort my rules alphabetically, as that is a) better for my OCD and b) allows for slightly better compression with gzip, e.g:
.footer__links li a {}
.footer__social li a {}
.footer__links li a:hover {}
.footer__social li a:hover {}

You can skip this rule by adding the stylelint disable commenad to the top of the file
/* stylelint-disable no-descending-specificity */
// your styles
/* stylelint-enable no-descending-specificity */

Related

Is there a way to use embedding style syntax for simplifying ( adding namespace to ) multiple class selectors in SCSS?

I have icon classes that contain the background-image and background-size properties. I want to protect the names of these classes with the prefix .icon. Then I can start writing out .icon.profile, .icon.search etc. selectors. If it were .icon .profile, .icon .search etc., then I could use embedding is SCSS to neatly protect namespace. However embedding won't work for multiple class selectors, because it selects child nodes. Once I use SCSS, it feels unintelligent to write out the prefix every time. To use embedding in DOM to support embedding in SCSS is an overkill and expensive ( adds unnecessary complexity of DOM elements ).
Is there a way to add "namespace" to classes that compile to multiple class selectors.
//////////////////////////////////////////////////////////////
// icons
.icon.search {
background-image: url(...);
background-size: cover;
}
.icon.profile {
background-image: url(...);
background-size: cover;
}
//////////////////////////////////////////////////////////////
If I understand your problem correctly, what you are looking for is the parent selector &:
.icon {
&.search {
background-image: url(...);
background-size: cover;
}
&.profile {
background-image: url(...);
background-size: cover;
}
}

Stylelint, have an empty line before non-nested rules and no empty line before nested rules?

Is there any way at all to accomplish this now?
I see rule-nested-empty-line-before has been removed for some reason, so is this config no longer possible?
I want this to throw errors...
#media (max-width: 300px) {
.foo {
display: block;
}
}
#media (max-width: 600px) {
.bar {
display: block;
}
}
There should be a space before #media since it's not nested, and no space before .foo since it's nested.
The rule-nested-empty-line-before and rule-non-nested-empty-line-before rules were combined together to form the new rule-empty-line-before rule in version 8.0.0. You can use this rule to control the empty lines before the .foo {} and .bar {} rules.
#media is an at-rule, so you should use the at-rule-empty-line-before rule to control the empty lines before it.
You can learn about how rules are named and how they work together in this section of the User Guide.
There should be a space before #media since it's not nested, and no space before .foo since it's nested.
With the above in mind, the configuration for that should be:
{
"rules": {
"at-rule-empty-line-before": ["always"],
"rule-empty-line-before": ["always", {
except: ["first-nested"]
}]
}
}
Alternatively, you can use stylelint-standard-config, which has sensible defaults for stylistic rules.

Access HTML attribute value in SASS

Is it possible to access an HTML attribute value in SASS?
I have a line of code that says
<ul id="my_id" data-count="3">
where the 3 is the result of some jQuery stuff. I need the 3 to calculate some CSS. How can I save it as a SASS variable?
Alternatively, is there a way of counting the number of child elements of a certain parent element? Say I have this code:
<ul id="my_id" data-count="3">
<li>First list item</li>
<li>Second list item</li>
<li>Third list item</li>
</ul>
(As you might have guessed, the value of data-count matches the number of list items.) Can SASS count the list items and save that number as a variable?
Any ideas would be greatly appreciated.
Sass is just a CSS generator. It doesn't really interact with your HTML, so you can't use HTML attributes as Sass variables.
However, CSS can select based on attributes. So it will be more long-winded than you might like, but you can do something like
ul[data-count="3"]:after
content: "There were three items in that list!"
And I think if you're willing to limit yourself only to a subset of very recent browsers†, you can use the CSS calc() function along with attr() to use the attribute in CSS-based calculations. But that's pretty bleeding edge.
† To be perfectly honest, I have no idea which versions of which browsers have fully implemented this. I'm pretty sure Firefox has it, though I've not used it, and I have no idea about other browsers. It is certainly not well-supported, at any rate.
It seems like you are trying to get the number of items inside your unordered list in CSS (maybe to change their size according to the number of siblings?).
Indeed, you cannot use a data-attribute as a Sass variable. However there is a pure CSS way to apply conditional styles given the number of items in the parent. Plus, it is very easily written in Sass.
Let's say your maximum number of items in your list is 10 and you want to compute the size of li tags based on the number of li tags there is in your list.
#for $i from 1 through 10 {
li:first-child:nth-last-child(#{$i}),
li:first-child:nth-last-child(#{$i}) ~ li {
width: (100%/$i);
}
}
This will output the following CSS:
li:first-child:nth-last-child(1),
li:first-child:nth-last-child(1) ~ li {
width: 100%;
}
li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li {
width: 50%;
}
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
width: 33.33333%;
}
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {
width: 25%;
}
li:first-child:nth-last-child(5),
li:first-child:nth-last-child(5) ~ li {
width: 20%;
}
li:first-child:nth-last-child(6),
li:first-child:nth-last-child(6) ~ li {
width: 16.66667%;
}
li:first-child:nth-last-child(7),
li:first-child:nth-last-child(7) ~ li {
width: 14.28571%;
}
li:first-child:nth-last-child(8),
li:first-child:nth-last-child(8) ~ li {
width: 12.5%;
}
li:first-child:nth-last-child(9),
li:first-child:nth-last-child(9) ~ li {
width: 11.11111%;
}
li:first-child:nth-last-child(10),
li:first-child:nth-last-child(10) ~ li {
width: 10%;
}
Basically, this gives the li tags a width of:
100.0% when there is only one li tag
50.00% when there are 2 li tags
33.33% when there are 3 li tags
25.00% when there are 4 li tags
20.00% when there are 5 li tags
16.66% when there are 6 li tags
14.28% when there are 7 li tags
12.50% when there are 8 li tags
11.11% when there are 9 li tags
10.00% when there are 10 li tags
For a live example, please refer to this demo I did using the same trick. I hope it helps.
If you want to access an HTML attribute from CSS, you can use attr()
Check the doc

class overrule when two classes assigned to one div

I was creating a <div> tag in which I wanted to apply two classes for a <div> tag which would be a thumbnail gallery. One class for its position and the other class for its style. This way I could apply the style, I was having some strange results which brought me to a question.
Can two classes be assigned to a <div> tag? If so, which one overrules the other one or which one has priority?
Multiple classes can be assigned to a div. Just separate them in the class name with spaces like this:
<div class="rule1 rule2 rule3">Content</div>
This div will then match any style rules for three different class selectors: .rule1, .rule2 and .rule3.
CSS rules are applied to objects in the page that match their selectors in the order they are encountered in the style sheet and if there is a conflict between two rules (more than one rule trying to set the same attribute), then CSS specificity determines which rule takes precedence.
If the CSS specificity is the same for the conflicting rules, then the later one (the one defined later in the stylesheet or in the later stylesheet) takes precedence. The order of the class names on the object itself does not matter. It is the order of the style rules in the style sheet that matters if the CSS specificity is the same.
So, if you had styles like this:
.rule1 {
background-color: green;
}
.rule2 {
background-color: red;
}
Then, since both rules match the div and have exactly the same CSS specificity, then the second rule comes later so it would have precedence and the background would be red.
If one rule had a higher CSS specificity (div.rule1 scores higher than .rule2):
div.rule1 {
background-color: green;
}
.rule2 {
background-color: red;
}
Then, it would take precedence and the background color here would be green.
If the two rules don't conflict:
.rule1 {
background-color: green;
}
.rule2 {
margin-top: 50px;
}
Then, both rules will be applied.
Actually, the class that defined last in the css - is applied on your div.
check it out:
red last in css
.blue{ color: blue; }
.red { color: red; }
<div class="blue red">blue red</div>
<div class="red blue">red blue</div>
vs
blue last in css
.red { color: red; }
.blue{ color: blue; }
<div class="blue red">blue red</div>
<div class="red blue">red blue</div>
If you asking about they have same property then as per the CSS rule it's take the last statement.
<div class="red green"></div>
CSS
.red{
color:red;
}
.green{
color:green;
}
As per the above example it's take the last statement as per css tree which is .green.
The class that is defined last in the CSS have priority, if nothing else applies.
Read up on CSS priority to see how it works.
Many classes can be assigned to an element, you just separate them with a space
<div class="myClass aSecondClass keepOnClassing stayClassySanDiego"></div>
Because of the cascade in CSS, the overwriting rules closest the to bottom of the document will be applied to the element.
So if you have
.myClass
{
background: white;
color: blue;
}
.keepOnClassing
{
color: red;
}
The red color will be used, but not the background color as it was not overwritten.
You must also take into account CSS specificity, if you have a more specific selector, this one will be used:
.myClass
{
background: white;
color: blue;
}
div.myClass.keepOnClassing
{
background: purple;
color: red;
}
.stayClassySanDiego
{
background: black;
}
The second selector here will be used as it is more specific.
You can take a look at it all here.

Look up GWT CellTable header style/s?

How can TH style name/s of a GWT CellTable's heading be looked up programatically?
I have looked at the Client Bundle documentation but it isn't immediately obvious to me how it all fits together. Thanks.
Not sure exactly what you want to do when accessing the TH style names.
If you want to override the standard css style of a celltable header, here are some of the css styles you can override to change the Look and Feel of the component.
.cellTableFirstColumnHeader {}
.cellTableLastColumnHeader {}
.cellTableHeader {
border-bottom: 2px solid #6f7277;
padding: 3px 15px;
text-align: left;
color: #4b4a4a;
text-shadow: #ddf 1px 1px 0;
overflow: hidden;
}
.cellTableSortableHeader {
cursor: pointer;
cursor: hand;
}
.cellTableSortableHeader:hover {
color: #6c6b6b;
}
.cellTableSortedHeaderAscending {
}
.cellTableSortedHeaderDescending {
}
Here is the complete list of styles for cellTables CellTable.css
Now if you want to access you header programmatically, you can use this solution to get the TableSectionElement corresponding the the Header of your table. Then you can access the row, then the cells, and lookup for their styles I guess.
Last thing if you want to override the header style, maybe you can use the following method when adding your column to your table
public void addColumn(Column<T, ?> col, Header<?> header)
Then create your Header or use a TextHeader for example then set your style on it before adding it to the table using
public void setHeaderStyleNames(String styleNames)
Example
TextHeader textHeader = new TextHeader("headerTitle");
textHeader.setHeaderStyleNames("my-style");
myTable.addColumn(myColumn, textHeader);
Easy solution:
import com.google.gwt.user.cellview.client.CellTable.Resources;
private String getCellTableHeaderStyle() {
Resources res = GWT.create(Resources.class);
return res.cellTableStyle().cellTableHeader();
}