Can a CSS Pseudo-Class Be Namespaced

Can a CSS pseudo-class be namespaced?

Namespaces, as part of the document language, do not apply directly to pseudo-classes or pseudo-elements, as they're defined in CSS and not the document language (e.g. XML). Element types and attributes, however, are defined in the document language as opposed to CSS, which is why they can be namespaced. Consequently, in a sequence of simple selectors, the universal selector specifically means "any type".

The universal selector is only implied for other simple selectors and pseudo-elements when used without a namespace (this is why selectors like .foo, #target, [type="text"], :first-child and ::before are valid, and generally used with languages like HTML where CSS is most commonly used for styling). From the spec:

If a universal selector represented by * (i.e. without a namespace prefix) is not the only component of a sequence of simple selectors selectors or is immediately followed by a pseudo-element, then the * may be omitted and the universal selector's presence implied.

Therefore, in your example, the selector is invalid because there's neither a universal selector or a type selector between the | and the ::

/* These are all invalid */
*|:first-child
ns|::first-letter
|::before

If you specify a namespace, you must specify the universal selector if you don't select a specific type instead:

*|*:first-child
*|*::before

The same goes when selecting elements in an ns namespace:

ns|*:first-child
ns|*::before

Or when selecting elements that are not in a namespace:

|*:first-child
|*::before

Namespacing pseudo-selector by css class

I would expect this code to turn the second span blue, which is not the case.

You have a fundamental misunderstanding of the :last-child pseudo-class; it matches only if the element to which the pseudo-class is applied, only if that element is the last-child of its parent. It is not equivalent to :last-of-type() selector (and even that pseudo-class disregards class-names and id, and selects an element based on its element-type (<div>, <p> etc).

In future, :nth-match() might serve your purpose, but that's yet to be implemented (so far as I'm aware) in any browser, and is part of the Selectors Level 4 module.

References:

  • :last-child.
  • :last-of-type().
  • :nth-match().
  • :nth-last-match().
  • Selectors Level 4 module.

Less Namespaces Pseudo and Other Selectors

# pseudo-selectors:

In short: you can't. Only id and class (i.e. # and . respectively) selectors can be used as mixins. Pseudo and tag selectors cannot. See Mixins.

If you're planning to re-use some styles just define those as a (parametric) mixin:

#namespace {
.whatever-suitable-name() {
prop: value;
}

.class:focus {
.whatever-suitable-name();
}
}

.anotherClass {
#namespace > .whatever-suitable-name();
}

# .class + .class:

#Namespace > .class + .class; // not working either

Partially because of above (i.e. not every selector can be used as a mixin), but in this particular case you actually still can access that selector combination. Though the only "officially recommended" syntax for invoking a namespaced mixin is: #namespace > .mixin, unofficially: "combinators" (e.g. >, +, ~, whitespace etc.) are essentially ignored when compiler matches selectors for a mixin call, so:

#namespace {
.class + .class {
prop: value;
}
}

.anotherClass {
#namespace > .class > .class; // OK
#namespace .class .class; // OK
#namespace.class.class; // OK
#namespace.class > .class; // OK
// etc.
}

See also #1205.

How can I handle XML namespaces in CSS Selectors or in jQuery?

CSS allows you to specify namespaces for use with selectors within stylesheets.

However, jQuery doesn't support this since you have no way of declaring the XML namespace in the first place (as jQuery has nothing to do with CSS besides borrowing from its selector syntax), so you have to treat the colon as a literal character instead by escaping it like so:

xml.find("channel > itunes\\:image")

Namespace/prefix for CSS classes, shared between Javascript and (S)CSS

I don't know of an easy way to have it defined in only one place. It's simple enough to have it only defined in two places, though: once in the javascript and once in your SASS. In the javascript you can use a global variable (or however else you store your constant values), and in SASS you can define the prefix like this:

$prefix: 'prfx-';

.#{$prefix}grid {
/* compiles to .prfx-grid */
}

.#{$prefix}other {
/* and so on */
}

It may not be as nice as having a single definition across both the javascript and CSS, but changing in two places is certainly better than a global find-replace. Theoretically, you could probably add a Ruby extension to SASS that would read the prefix value out of a file that the Javascript code could access via AJAX, but it seems to me that such a system wouldn't be worth the extra effort to get it set up and working properly.

Can we achieve anything with the new CSS :is() pseudo-class that we can't already achieve with comma-separated queries?

You are actually dealing with basic examples but consider more complex ones like the following:

.box h1, .box h2, .box h3, .box h4

In order to avoid repeating the .box we use

.box :is(h1, h2, h3, h4)

As far as I know, this was the main motivation for :is(): avoid rule duplication.

Another common example is the table selectors:

table tr td, table tr th

now will become

table tr :is(td, th)

Can you style XHTML elements in another namespace using id and class name css selectors?

Frankie,

porneL's answer is right -- in XHTML mode you have to use different CSS rules, because there is nothing 'special' about @id an @class.

Even armed with this knowledge, your problems aren't over though. :)

The temptation might be to just put HTML and XHTML CSS selectors together, and apply them to the same rule:

@namespace xf url(http://www.w3.org/2002/xforms);

xf\:input.surname, xf|input[class~="surname"] {
color: green;
}

However, a further problem is that IE will ignore the entire rule, because it doesn't like the XHTML syntax. So littered through Ubiquity XForms you'll see things like this:

@namespace xf url(http://www.w3.org/2002/xforms);

xforms\:hint.active, xf\:hint.active {
display: inline;
}

xf|hint[class~="active"] {
display: inline;
}

As you can see we've had to repeat the styling with different selectors. (This is something we're hoping to address with a function that will abstract out the style-setting task. Then you'll only have to write one rule.)

Note a couple of extra things:

  • that the HTML rules are using ':' as a literal character (hence the '\' to escape), and know nothing of namespaces;
  • the XHTML CSS rules use the '~=' operator, which means that the attribute must contain the value specified, rather than be exactly equal to it.

What does *|* this mean in CSS?

It means "all elements in all namespaces that are :link."

More on universal selectors and namespaces.

CSS :not pseudo-class applying broadly and not targeting specific element

Keep this in mind:

:not() is equivalent to *:not()

When there is no selector prefixing the :not() pseudo-class, a universal selector is implied:

6.2. Universal
selector

If a universal selector represented by * (i.e. without a namespace
prefix) is not the only component of a sequence of simple selectors
selectors or is immediately followed by a pseudo-element, then the *
may be omitted and the universal selector's presence implied.

Therefore, the rule you have:

:not(.mind) {
color: red
}

... is saying apply red color to all elements except the element with the class mind.

Okay, except in this case, the color property is inheritable, so even though the red doesn't get applied to the .mind element, it still gets the red through inheritance from the .parent element.

Here's what the browser is doing:

Sample Image

A quick way to test this behavior is with the border property, which is not inheritable.

In the example below, using your selector, you'll notice that the border doesn't get applied to .mind, and your selector works as you were expecting:

:not(.mind) {
color: red;
border-bottom: 1px dashed black;
}
<div class='parent'>
<div class='child'>One</div>
<div class='child'>Two</div>
<div class='child'>Three</div>
<div class='child'>One</div>
<div class='child'>Two</div>
<div class='child'>Three</div>
<div class='child'>One</div>
<div class='mind'>mind</div>
<div class='child'>Three</div>
<div class='child'>
<p>First paragraph</p>
</div>
</div>

Is anyone actually using css namespaces?

They cover completely different use cases.

CSS namespaces are for applying CSS to XML documents that mix elements from different XML namespaces. e.g. so you can target <foo:p> and <bar:p> without confusion.

SMACSS covers techniques for writing robust CSS that doesn't interfere with other parts of the page. e.g. so that .title in your address book HTML doesn't get muddled with .title in your list of publications HTML.


Further details from the spec:

Note: In HTML, the xmlns attribute has absolutely no effect. It is basically a talisman. It is allowed merely to make migration to and from XHTML mildly easier. When parsed by an HTML parser, the attribute ends up in no namespace, not the "http://www.w3.org/2000/xmlns/" namespace like namespace declaration attributes in XML do.



Related Topics



Leave a reply



Submit