CSS - Match a whole attribute value - css

HTML
<div data-whatever='something cols-16 else'>
</div>
This works:
Will work - CSS
[data-whatever*='cols-1'] {
background: red;
}
It will find the div and make it red.
Will not work - CSS
[data-whatever='cols-16'] {
background: red;
}
It will not find the div because there are other stuff in there as well.
Problem
The problem with the working CSS, is that it matches both cols-16, cols-1 and any other that starts with cols-1.
Question
Is it possible to find an attribute value, exact match?

In order to target the class cols-16 (even when it appears with other classes)
and not target the cols-1 class use this:
[data-whatever~='cols-16'] {
background: green;
}
You can see this working in this fiddle.
For more info see this post (Goto #16. - X[foo~="bar"]
The tilda (~) symbol allows us to target an attribute which has a
spaced-separated list of values.

try this:
[data-whatever~='cols-1'] {
background: red;
}
It worked for me if I didn't missunderstand your question
Edit: I just remembered the ~= randomly, tried it, and pasted it.
But I just googled a bit (I had curiosity and found This, it's quite interesting)

To ensure that it only matches cols-1 and not cols-16 without relying on the cols-16 style overriding the cols-1 style (below), you could:
[data-whatever='cols-1'],
[data-whatever^='cols-1 '],
[data-whatever*='cols-1 '],
[data-whatever$='cols-1'] {
background: red;
}
This matches data-whatever="cols-1", data-whatever="... cols-1", data-whatever="cols-1 ..." or data-whatever="... cols-1 ...".
JSFiddle example.
Thanks to aleation's answer: data-whatever~="cols-1" achieves the same as the above in just one selector.
--
At any rate your cols-16 styling could overwrite your cols-1 styling anyway, depending on the order it was presented:
[data-whatever*='cols-1'] {
background: red;
}
[data-whatever*='cols-16'] {
background: blue;
}
/* cols-1 will be red. cols-16 will be blue */
JSFiddle example.

Related

Use the "Starts with" selector in less

Lets say i have a div like
<div class="col-d-1 col-m-5">some content</div>
I want to select the div. Normaly no problem... My problem is, there is more css that acts on this div. So I dont want to use !important. I try to use more than one selector to keep this one "important". Now i know there will be a col-m- but i dont know the value.... even if its 1, 2, 3 or what ever...
Actually in CSS i would use
.col-d-1 [class^='col-m-'] {
background: red;
}
something like this to select my col-d-1 having some col-m-
But how to convert this to less ?
I thought
.col-d-1 {
&.col-m-* {
background: red;
}
}
But nothing i tried works ^^
Any suggestions ?
Or is this less allready ?
This should work for you:
.col-d-1 {
&[class*='col-m-'] {
background: red;
}
}
codepen example
Well, LESS does recognise CSS, so keep it unchanged should work.
The other option is just combine it using the raw selector:
.col-d-1 {
&[class*='col-m-'] {
background: red;
}
}
Because you are pattern-matching on the class attribute, not checking if a class within it starts with col-m-, you need to use the contains selector *=, no the starts-with selector.

LESS mixins vs classes

I'm looking into LESS because I definitely see some of their benefits. For instance colour declaration.
One thing I don't understand tho, and maybe I'm not getting the flow right is - why use the following LESS snippet
.radius {
-webkit-border-radius:5px;
-moz-border-radius:5px;
border-radius:5px;
}
.btn-red{
background-color:red;
.radius;
}
.btn-green{
background-color:green;
.radius;
}
...
When we can use the .radius class in the html file right away. I'm left with the impression that LESS will add a ton of duplicate code once it gets compiled.
I'm using the following, which makes more sense. Same with font-size, margins, etc... Aren't classes used in such cases?
<div class="btn-red radius">Cancel</div>
<div class="btn-green radius">Go</div>
The snippet above does not benefit from SASS/LESS capabilities that much. Lets have a closer look and check this SCSS snippet.
// Abstract placeholder.
%radius {
border-radius: 5px;
}
// Put your global styling here.
// I'm assuming that you can alter the markup and have button.btn.btn-green
.btn {
// Color modifier.
&-red {
#extend %radius;
background-color: red;
}
&-green {
#extend %radius;
background-color: green;
}
}
The CSS output will be:
.btn-red, .btn-green {
border-radius: 5px;
}
.btn-red {
background-color: red;
}
.btn-green {
background-color: green;
}
And then you have to pick up Autoprefixer and vendor-prefixes issue is solved once and for all.
Because now, you can just specify the class btn_red or btn_green and all the buttons will automatically have a radius.
Your HTML should contain only the semantics, and styling or classes referring to styling should not be part of it.
That applies to the other classes as well. If for instance, you would rename btn_red to btn_cancel, you have a meaningful classname that you can apply to any kind of cancel button. And in the CSS you can specify that a cancel button is red and a 'Go' button is green, and both have a radius, without needing to modify the HTML at all.
So, the ultimate goal is to have the HTML describe the structure and the CSS describe how that structure should look. And a CSS preprocessor is only their to make a bulky spaghetti-like CSS file more structured.
There are several benefits.
You can use more semantic class names. Rather than encoding style information directly in your class names, (btn-red, radius) you could use a single class that conveys the usage of the style, rather than its contents.
You can avoid repeating yourself.
#radius-size: 5px;
-webkit-border-radius:#radius-size;
-moz-border-radius:#radius-size;
border-radius:#radius-size;
You can parameterize it so that you'd be able to use different radiuses (radii?) in different contexts.
.radius(#radius-size) { ... }
Because there are cases that developer has-no-access or don't-want to change the markup. and the only solution is to include all props from a predefined class.
for example:
you have bootstrap loaded (then you already have .has-success and .has-error classes) and if you want to use HTML5's native form validation using input's :valid and :invalid states, you have to use JavaScript to add/remove success/error classes based on input's states. but with this feature of LESS you can include all props of success/error class inside input's states. the code for this example could be something like this:
#myinput {
&:valid { .has-success; }
&:invalid { .has-error; }
}

Priority of one css attribute value over another

For a button I have 3 possible classes: "state-normal", "state-focus" and "state-hover".
All have the same attributes (background, border, ...), but different values for the
attributes.
If a button gets "state-focus", I do not want to remove the class "state-normal".
If a button is "state-focus" and gets "state-hover", I do not want to remove the class
"state-focus".
In the browser language specification you can give a "quality"/priority to a language:
"Accept-Language: da, en-gb;q=0.8, en;q=0.7"
It would be great to do the same also in css:
.state-normal { background-color: #aaaaaa;q=0.5 }
.state-focus { background-color: #bbbbbb;q=0.7 }
.state-hover { background-color: #eeeeee;q=0.9 }
I know that there is nothing in CSS.
But, I know in jQuery UI they have kind of this, because they don't remove "ui-state-default" when they assign "ui-state-focus" to an element. How do they do it?
Is there another way to implement this with a trick (WITHOUT !IMPORTANT).
Thanks alot in advance
You can do this using CSS.
.state-normal { background-color: #aaaaaa;q=0.5 }
.state-normal.state-focus { background-color: #bbbbbb;q=0.7 }
.state-focus.state-hover { background-color: #eeeeee;q=0.9 }
But this implies that all classes mentioned in the rule will be present, i.e. an element will have both classes present. So an element with class state-focus will not have the background-color set as per the rule.
If you want to avoid that, then you can do this instead:
.state-normal { background-color: #aaaaaa;q=0.5 }
.state-focus, .state-normal.state-focus { background-color: #bbbbbb;q=0.7 }
.state-hover, .state-focus.state-hover { background-color: #eeeeee;q=0.9 }
EDIT: As per OP's request
CSS Specificity
CSS Selectors - MDN
Similar answer

CSS "properties of .x" syntax

Is it possible to add additional rules to a css block when using a "{ (properties of x) }" selector?
I looked at references but I can't find anything related to "properties of x". A link would be wonderful. I tried the following two combinations, but neither worked:
.dock li { (properties of grid_2; display:inline; background-color:#666; ) }
.dock li { display:inline; background-color:#666; (properties of grid_2) }
Many thanks!
EDIT
Apparently I misread an article and thought that such a syntax existed. I thought one could create a class and let it inherit the properties of another using such syntax, which is evidently not the case.
CSS does not have such a feature.
What you are describing is not possible. I think there are two other possibilities you could maybe use. The first is, that you need to know that several styles can be applied to an element at the same time. I'll give you an example:
li { font-size: 10pt; }
.dock li { color: #ff0000; }
All list items will be formatted with a font size of 10 points and only those within an element containing the dock class will be red.
My second suggestion is that you try applying two or more classes to your HTML element, for instance:
.grid li { font-size: 10pt; }
.dock li { color: #ff0000; }
Now put the grid and dock class into your HTML, and the elements will apply both style definitions:
<ul class="grid dock"> ...
Whatever you consider best for your project: remember that the properties defined in the second style overwrite the properties of the first one (if they do not define the same properties at all, there will be no confusion).
maybe your question is not too strange..
What I understand is that you want to do something like:
.a { prop1: val; prop2: val; }
.b { prop3: val; prop4: val; }
.c { .a; .b; prop5: val; prop6: val; }
You want the class .c to inherit all the properties and values of .a and .b
If this is ok, you can do that using LESS.
To use your LESS code in your sites you have different ways to do it.
First of all check the original site: LESS.org
If you are on Mac check this site: LESS APP + PLUGINS
If you are on PC the less.js plugin should be easier to implement LESS in your sites: less.js usage
Hope it helps.
Happy coding y'all! :)

Is there a way to refer to an html element with multiple classes?

I have the following
<p class="main yellow">Hello World</p>
I would like to write a css element that refers to only elements with main and yellow. Is there a way to do this?
Eg. the following doesn't work, but would be what I'm after
.main + .yellow { color:green }
This should grab it:
.main.yellow { color:yellow; }
Though you may get differing results in different browsers. I use QuirksMode to get an idea of what will/won't work cross browser.
You just need to specify them as
.main.yellow { color: green; }
No space between the two classes.
does this work for you?
.main.yellow{
color:green;
}
As others have already said, what you want is:
.main.yellow { color:green; }
However, let me quickly explain why your first attempt didn't work. The + keyword refers to a following element, i.e. the element after.
Your example would have matched the following HTML...
<p class="main">Hello</p>
<p class="yellow">World</p>
...and styled the second paragraph (.yellow) green. So ".main + .yellow" means "select a .yellow that is immediately after a .main".

Resources