I want to apply a CSS rule to any element whose one of the classes matches specified prefix.
E.g. I want a rule that will apply to div that has class that starts with status- (A and C, but not B in following snippet):
<div id='A' class='foo-class status-important bar-class'></div>
<div id='B' class='foo-class bar-class'></div>
<div id='C' class='foo-class status-low-priority bar-class'></div>
Some sort of combination of:
div[class|=status] and div[class~=status-]
Is it doable under CSS 2.1? Is it doable under any CSS spec?
Note: I do know I can use jQuery to emulate that.
It's not doable with CSS2.1, but it is possible with CSS3 attribute substring-matching selectors (which are supported in IE7+):
div[class^="status-"], div[class*=" status-"]
Notice the space character in the second attribute selector. This picks up div elements whose class attribute meets either of these conditions:
[class^="status-"] — starts with "status-"
[class*=" status-"] — contains the substring "status-" occurring directly after a space character. Class names are separated by whitespace per the HTML spec, hence the significant space character. This checks any other classes after the first if multiple classes are specified, and adds a bonus of checking the first class in case the attribute value is space-padded (which can happen with some applications that output class attributes dynamically).
Naturally, this also works in jQuery, as demonstrated here.
The reason you need to combine two attribute selectors as described above is because an attribute selector such as [class*="status-"] will match the following element, which may be undesirable:
<div id='D' class='foo-class foo-status-bar bar-class'></div>
If you can ensure that such a scenario will never happen, then you are free to use such a selector for the sake of simplicity. However, the combination above is much more robust.
If you have control over the HTML source or the application generating the markup, it may be simpler to just make the status- prefix its own status class instead as Gumbo suggests.
CSS Attribute selectors will allow you to check attributes for a string. (in this case - a class-name)
https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
(looks like it's actually at 'recommendation' status for 2.1 and 3)
Here's an outline of how I *think it works:
[ ] : is the container for complex selectors if you will...
class : 'class' is the attribute you are looking at in this case.
* : modifier(if any): in this case - "wildcard" indicates you're looking for ANY match.
test- : the value (assuming there is one) of the attribute - that contains the string "test-" (which could be anything)
So, for example:
[class*='test-'] {
color: red;
}
You could be more specific if you have good reason, with the element too
ul[class*='test-'] > li { ... }
I've tried to find edge cases, but I see no need to use a combination of ^ and * - as * gets everything...
example: http://codepen.io/sheriffderek/pen/MaaBwp
http://caniuse.com/#feat=css-sel2
Everything above IE6 will happily obey. : )
note that:
[class] { ... }
Will select anything with a class...
This is not possible with CSS selectors. But you could use two classes instead of one, e.g. status and important instead of status-important.
You can't do this no. There is one attribute selector that matches exactly or partial until a - sign, but it wouldn't work here because you have multiple attributes. If the class name you are looking for would always be first, you could do this:
<html>
<head>
<title>Test Page</title>
<style type="text/css">
div[class|=status] { background-color:red; }
</style>
</head>
<body>
<div id='A' class='status-important bar-class'>A</div>
<div id='B' class='bar-class'>B</div>
<div id='C' class='status-low-priority bar-class'>C</div>
</body>
</html>
Note that this is just to point out which CSS attribute selector is the closest, it is not recommended to assume class names will always be in front since javascript could manipulate the attribute.
Related
I need a pure CSS way to select an element based on part of an HTML attribute value. For example, I want to select this element:
<div data-gt="{'type':'select_me'}"></div>
based on the fact that the element has a data-gt value that contains select. The closest I can get is using [data-gt~=select] as a CSS selector, but that searches for whole words only. So if the word select in the HTML attribute was surrounded by spaces like {'type':' select _me'}, it could find it no problem, but it can't find it because it's preceded by a quote and followed by an underscore.
Note: The example above is a simplified version of what I want to do, so no I can't just change how the HTML attribute is generated and no I can't predict any of the surrounding data in the data-gt attribute.
Just curious if there is a pure CSS way to do this? I know it could be handled with Javascript, but that doesn't work for my purposes.
You can use the * attribute selector:
Represents elements with an attribute name of attr whose value
contains at least one occurrence of value within the string.
[data-gt*="select"] {
color: red;
}
<div data-gt="{'type':'select_me'}">Select Me</div>
<div data-gt="{'type':'please_dont'}">Don't Select Me</div>
What CSS selector is the first part in square brackets?
[ui-view].ng-enter-active {}
It is not an attribute selector that would be this right?
ui-view[content] {}
It is indeed an attribute selector. An attribute selector and a class selector are both simple selectors, and simple selectors in a sequence may be arranged in any order, with the exception that a type or universal selector, if present, must come first.
This means [ui-view].ng-enter-active and .ng-enter-active[ui-view] are both valid and equivalent, matching an element that has a class "ng-enter-active" as well as an attribute named "ui-view". The former seems strange at first only because you rarely see attribute selectors appearing first in a simple selector sequence.
Your second example, ui-view[content], contains a type selector, ui-view. Because of this, unlike your first example, it cannot be rewritten as [content]ui-view, since, as mentioned, type selectors must come first.
That is an attribute selector. It would select an element that has both a ui-view attribute as well as the class ng-enter-active. That attribute selector doesn't care about the actual value of the attribute. So for example, it would correctly select the following:
<div ui-view class="ng-enter-active"></div>
as well as:
<div ui-view="valueDoesntMatter" class="ng-enter-active"></div>
It's attribute selector, so:
The first one
[ui-view].ng-enter-active
means element with class ng-enter-active and attribute ui-view, eg.
<div class="ng-enter-active" ui-view="abc">
<div class="ng-enter-active" ui-view> <!-- or with attribute without value -->
The second one,
ui-view[content]
means element ui-view (you probably forgot dot, class="ui-view") with attribute content
<ui-view content="abc">
OR probably, if you forgot . in selector
<div class="ui-view" content="whatever">
See more about attribute selector: http://quirksmode.org/css/selectors/selector_attribute.html
Why do we need the CSS [attribute|=value] Selector at all when the CSS3 [attribute*=value] Selector basically accomplishes the same thing, the browser compatibility is nearly similar? Is there something that the first CSS selector does and the second isn't able to? This is the first time to encounter two very similar selectors and wonder why the first one exists in the first place.
From the doc:
[attr|=value] Represents an element with an attribute name of attr.
Its value can be exactly “value” or can begin with “value” immediately
followed by “-” (U+002D). It can be used for language subcode matches.
[attr*=value] Represents an element with an attribute name of attr and
whose value contains at least one occurrence of string "value" as
substring.
Visual differences:
[attr|=value]
/* Any span in Chinese is red, matches simplified (zh-CN) or traditional (zh-TW) */
span[lang|="zh"] {color: red;}
<span lang='zh'>zh</span>
[attr*=value]
/* All links to with "example" in the url have a grey background */
a[href*="example"] {background-color: #CCCCCC;}
<a href="www.example.com">example<a/>
In the same code example:
div[color|="red"] {
background: red;
}
div[color*="blue"] {
color: blue;
}
<div>
<div color='red-yellow'>This shoud has only red background</div>
<div color='blue'>This shoud has only blue color</div>
<div color='red-blue'>This shoud has blue color and red background</div>
<div color='blue-red'>This shoud be only blue color</div>
</div>
References
Attribute selectors
There are a lot of differences between these two selectors
[lang|=en] {
background: yellow;
}
[lang*=en] {
color:red;
}
<p lang="en">Hello!</p>
<p lang="en-us">Hi!</p>
<p lang="en-gb">Ello!</p>
<p lang="usen">Hi!</p>
<p lang="noen">Hei!</p>
<p><b>Note:</b> For [<i>attribute</i>|=<i>value</i>] to work in IE8 and earlier, a DOCTYPE must be declared.</p>
The [attribute|=value] selector is used to select elements with the specified attribute starting with the specified value.
The [attribute*=value] selector matches every element whose attribute value containing a specified value.
See the example to get a clear idea about both the selectors.
They are distinctly different:
[attr|=value]
Represents an element with an attribute name of attr. Its value can be exactly “value” or can begin with “value” immediately followed by “-” (U+002D). It can be used for language subcode matches.
[attr*=value]
Represents an element with an attribute name of attr and whose value contains at least one occurrence of string "value" as substring.
https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
The first selector ensures the attribute value starts with the value submitted, the second only requires the attribute value contains it.
This would be helpful if you had to distinguish between attributes that had the same string in different positions within the same attribute.
CSS has evolved over time, and as it has evolved the need and want for more selectors, and functions has increased.
The CSS [attribute|=value] Selector was defined before CSS3 (latest version), and was available in CSS 2.1. As noted in the page you linked to:
used to select elements with the specified attribute starting with the specified value.
Whilst this is handy in most cases, sometimes there are frameworks, which come with structured css in the from of someString_somethingUseful_somethingElse for its class definition.
Now say I wanted to select all elements with the somethingUseful bit in it. The above selector would not allow me to do this, as the somethingUseful bit of the class definitions located in the middle of the class name. the same with the somethingElse bit, it is located at the end.
Thus in CSS3, we saw the introduction of [attribute*=value] selector which allows us to select elements which may have these keywords as a substring in their definition (though not necessarily at the front) See:
selector matches every element whose attribute value containing a specified value.
Is there a kind of condition statement in SASS or SCSS for following HTML elements?
<div class="header" id="1">
<div class="header" id="2">
I found this Solution:
Different Styles for same class name but different id
But this seems the traditional solution, what I image is syntax like this:
.header{
[if #1]{
}
[else if #2]{
}
}
If there do not exist such syntax, I wonder what is the concern of such implementation?
Thanks!
Selectors themselves are made up of conditional statements. Since the ID and class are on the same element, concatenate the selectors using & as per normal:
.header{
&#\1 {
}
&#\2 {
}
}
Even though it might seem strange to append an ID selector to a class selector, it's perfectly valid. ID selectors don't have to be at the beginning of a compound selector like type or universal selectors do. But if it still rubs you the wrong way, there is nothing wrong with just using the ID selectors alone without qualifying them with the class selector (unless those same IDs are used differently elsewhere, in which case you should really rethink your HTML structure).
Note also that you need to escape the digits with a backslash in order for the ID selectors to be recognized, as CSS identifiers cannot normally start with a digit.
I'm reading the book: CSS Mastery: Advanced Web Standards Solutions, and finding the css code inside is almost writed in this format:
elementName#idName
elementName.className
but, I'm used to write code ignoring element name with this format:
#idName
.className
so, I want to figure out what difference is between the two format.
Actually, I understand when should use type.class. And, I just want to find out the impact when I use type.class insead of only using .class when there is only one kind of tag here.
There must be some impact on performance.
Here's a real life scenario as when to use elementName and when to just use class or id name:
HTML:
<a class="blue">I'm blue and underline</a>
<span class"blue">I'm blue and bold</a>
CSS:
.blue {
color:blue //will make both <a> and <span> blue
}
a.blue {
text-decoration:underline // will make only the <a> tags underline
}
span.blue {
font-weight:bold //will make only the <span> tags bold
}
but remember when it comes to IDs you should not have duplicate IDs on your page anyway, this is more practical for classes
The difference between the two is that the first:
element.class
Is calling the element with that specific class.
And the second:
.class
Is calling all elements that contain this class
I think that the element inclusion in the selector is a holdover from days where some browsers required it (I think IE5 does, but I could be wrong). This is no longer necessary, and it does not make sense to include element selector for at least three reasons:
It slows the selector down since the element selector is slower than the other two -- especially id. Assuming selection is optimized so that fast selection is done first (e.g. the element with the matching id is found before the element selector is checked), there is still the additional step of checking the element selector.
It's not as extensible since you can't change the element without also having to change the selector. The implication is also that div.class would function differently than label.class, but I think that the class should be descriptive enough.
It changes the specificity of the selector. This could be very frustrating for some developers who may want to change <div class="foo"> from green to red:
div.foo { color: green; }
/* below is not applied since the above has higher specificity */
.foo { color: red; }
I've never heard an argument that supports type.class unless old browsers need to be supported.