CSS Selector "(A or B) and C"? - html

This should be simple, but I'm having trouble finding the search terms for it.
Let's say I have this:
<div class="a c">Foo</div>
<div class="b c">Bar</div>
In CSS, how can I create a selector that matches something that matches "(.a or .b) and .c"?
I know I could do this:
.a.c,.b.c {
/* CSS stuff */
}
But, assuming I'm going to have to do this sort of logic a lot, with a variety of logical combinations, is there a better syntax?

is there a better syntax?
No. CSS' or operator (,) does not permit groupings. It's essentially the lowest-precedence logical operator in selectors, so you must use .a.c,.b.c.

Not yet, but there is the experimental :is() (formerly :matches()) pseudo-class selector that does just that:
:is(.a .b) .c {
/* style properties go here */
}
You can find more info on it here and here. Currently, most browsers support its initial version :any(), which works the same way, but will be replaced by :is(). We just have to wait a little more before using this everywhere (I surely will).

For those reading this >= 2021:
I found success using the :is() selector:
*:is(.a, .b).c{...}

If you have this:
<div class="a x">Foo</div>
<div class="b x">Bar</div>
<div class="c x">Baz</div>
And you only want to select the elements which have .x and (.a or .b), you could write:
.x:not(.c) { ... }
but that's convenient only when you have three "sub-classes" and you want to select two of them.
Selecting only one sub-class (for instance .a): .a.x
Selecting two sub-classes (for instance .a and .b): .x:not(.c)
Selecting all three sub-classes: .x

No. Standard CSS does not provide the kind of thing you're looking for.
However, you might want to look into LESS and SASS.
These are two projects which aim to extend default CSS syntax by introducing additional features, including variables, nested rules, and other enhancements.
They allow you to write much more structured CSS code, and either of them will almost certainly solve your particular use case.
Of course, none of the browsers support their extended syntax (especially since the two projects each have different syntax and features), but what they do is provide a "compiler" which converts your LESS or SASS code into standard CSS, which you can then deploy on your site.

Related

Can we make an element of block modifier in BEM?

I just wanted to know whether the following code follows BEM methodology best practices? Creating an element for the block modifier i.e. in this case "block--mod" is a modifier for the "block" block. Is it allowed to create a nested element with this pattern: "block--mod__elm".
<div class="block block--mod">
<div class="block__elm block--mod__elm">
</div>
In situations like theming or similar I would use nested selectors. This saves some classes in your HTML and as #Jonathan Nicol said those sub-elements can be hard to follow. Also it will be easier to remove the "branding" later, just remove block class instead of all it's elements.
For example Xmas branding of your header.
.header--xmas .header__logo {
/* Jingle bells, jingle bells, jingle all the way.*/
}
Source: http://getbem.com/faq/#can-a-block-modifier-affect-elements-
I could not find an example of a the .block--mod__elem pattern in Yandex's BEM documentation (Yandex devised the BEM methodology), but an early article about BEM on CSS Wizardry does show an example of a modifier with a sub-element, .person--female__hand:
.person {}
.person__hand {}
.person--female {}
.person--female__hand {}
.person__hand--left {}
Source: MindBEMding – getting your head ’round BEM syntax
Modifiers with sub-elements can be a little hard to follow, but I do not shy away using from them if it seems like the logical approach.
Edit: #NikolayMihaylov's answer gives an alternative approach that I wholeheartedly support. It is more readable and more maintainable.

How to namespace OOCSS classes with competing "scopes"?

I am aware that this is asking for a very opinionated answer, as are all naming-convention related questions, I guess.
I am using Harry Roberts BEMIT naming convention, which augments BEM with prefixes/namespaces for object-oriented css.
That allows organizing classes into objects, using the o- prefix, for decoration-free design patterns like the famous media object, and styled ui-components, using the c- prefix (plus some more).
Here is the (generic) example, that is often used in the context of explaining BEM, augmented with the problematic namespaces:
.o-btn {
width: 100%;
}
And here the competing scope, targeting the same (bem)block
.c-btn {
color: white;
background: gray;
}
.c-btn--positive {
background: green;
}
.c-btn--negative {
background: red;
}
To quote the relevant part from Harry Roberts CSS Guidelines (not enough cred to post 2nd link, sorry):
Above, we can see how the .btn {} class simply provides structural styling to an element, and doesn’t concern itself with any cosmetics. We supplement the .btn {} object with a second class, such as .btn--negative {} in order to give that DOM node specific cosmetics.
This explanation to me sounds like the exact justification to do as I did.
Still, it feels incorrect, to use two different namespaces on the same block, possibly confusing.
Which namespace do I chose, if two of them are competing?
Don't be afraid of having different BEM entities on the same DOM node.
Actually pure BEM itself solves this issue with the help of mixes (see https://en.bem.info/methodology/key-concepts/#mix).
The idea is that you should keep button block as universal component with maximum reusability. Then you may add all the cosmetics with the help of theme modifier. And finally add positioning with a help of mix with parent's element (e.g. form__submit).
So you may end up with something like this:
<form class="form">
<button class="button button--theme_awesome form__submit">Send</button>
</form>
You use what your projects require, in my case I much prefer the prefixed syntax (o-, c-, u-), because you're telling to your html elements what they are, a short example using sass syntax:
.c-button{
&.c-button--dark{}
&.c-button--orange{}
}
and you can overwrite bootstrap classes, for example, you don't have to take care about other classes, with this specification you are able to overwrite the default classes you might have, and you can have a mix of css classes in your hmtl element, for example:
<input type="text" class="btn btn-primary c-button c-button-dark" />

Prefixing and Classing everything

Usually when i create some HTML template, i tend to prefix and class (or id) everything, This is my way of keeping the markup more readable, and also it makes styling a lot easier.
For example if create a template called MyTemplate, then i prefix all elements like this
<form id="mt-form-blue" class="mt-form">
<input class="mt-input-large" type="text" />
<input class="mt-input-small" type="text" />
</form>`
I've seen lots of HTML templates, where the creators make very little use of classes and ids.
My question is why? Does using many classes and ids, have an impact on the browser performance? Does it have any dangerous side effects?
CSS selector do impact performance, but how much it impact will depend on its complexity and what operators were used. Usually you won't notice such tnings, but there are plenty of researches for this matter on the web.
Regarding the use of selectors, listing only the basic three, the use of them depends on what is your intention, for example:
tag name selector - When you want apply style to every element of this type
class selector - when you want to reuse your style in more than one element
ID selector - when you want to apply your style to only one element per document
Of course, their use is not limited for the list above but I believe it contains the most common use cases.

Html tagging elements with custom tags instead of using classes

Instead of using the standard class="someclass", I deviated from this pattern and "tagged" the div thus:
<html>
<head>
<style type="text/css">
div[tag1]
{
background-color:Red;
}
</style>
</head>
<body>
<div tag1>test</div>
<div>test</div>
</body>
</html>
What are the drawbacks of this approach (besides the obvious fact that it might confuse some developers)?
Will it work in any browser? (I checked FF, IE and Chrome - it worked in all of them)
To me, it looks more concise than using "class".
Thanks!
I see a few drawbacks to your approach
Specificity: All attributes in the element, with exception to the ID, are parsed as classes. By choosing to go with <div someAtt>, this is always going to have the specificity of a class: 0,0,1,0.
Selectors: You don't make shorter selectors:
The class of an element is also an attribute. You could select an element that has a class like so:
[class="tag1"]{
color:red;
}
This, in fact, is the "normal" way to select an element with an attribute which has a value. The manner in which we select classes is more of a shorthand for the above rule:
.tag1{
color:red
}
Because you're proposing a custom attribute, your selector will be:
[tag1]{
color:red
}
If you're counting characters, the "longhand" attribute selector takes the most space and the class selector the least. You're not making a stylesheet shorter with your approach. Your selector will always be longer by at least one character. Is this a huge deal? No. But it will be over time, and now you have to train someone who takes over your stylesheet on your approach.
Extensibility: Another issue with adding an invalid attribute to your markup is extensibility. Your goal should be extensible markup and CSS, so you want a pattern that's reusable. if you're going to have tag1, tag2, etc, this isn't an extensible pattern.
How do you plan on dealing with reusable styles? What you're saying is that <div tag1 tag2 tag3 tag4> could happen at some point in the future. How do you plan on styling that?
div[tag1][tag2][tag3][tag4]{
color:red;
border-color:red;
outline-color: red;
background-color: red;
}
[tag1]{
color:red
}
[tag2]{
border-color:orange
}
[tag3]{
outline-color:yellow
}
I see tag as a reusable attribute which can accept a changing value:
<div tag="one">
Which results in this selector:
[tag="one"]{
color: green
}
Which ultimately means you have replicated the "class" approach, but with a longer selector and no means to a shorthand (like the . that's the same as [class=""].
Valid Markup: The next issue I see in your approach is that you're using invalid attributes. In HTML5, you can use the data-* approach to pretty much create whatever attributes you want in a somewhat normalized pattern. But invalid attributes such as tag1 could throw off any HTML validators. Additionally, I don't know how screen readers or other accessibility devices might struggle with invalid or unknown attributes.
The Neighborly Way: The final issue that I see is more philosophical. We get a heck of a lot more freedom and flexibility in HTML and CSS than in other development languages. Web browsers are much, much more forgiving of mistakes that we make in HTML and CSS than compiled languages. We shouldn't equate the freedom to be different to the wisdom of following standards and best practices.
The only drawback I can think of is that you lock your css to a tag type. ie with class you could do:
<div class="alignRight"> Some thing </div>
<table class="alignRight">table data</table>
Your approach does not allow for this. Apart from this I don't think it's any technical issue with using your approach.

class="mytest anothertest"...what is anothertest?

Trying to learn html/css. I've been looking at the html & css files of a couple different websites that have something along the line of:
<span class="mytest anothertest">some text goes here</span>
I understand the "mytest" part but what does "anothertest" do? There's no reference to that anywhere in their css or html files.
anothertest is just another class like mytest. You can apply more than one to an element.
There are several possible reasons for the presence of a class name in a class attribute value. Using the class in page stylesheets is probably most widely known, but not the only one:
The class name can be used in JavaScript in order to process a set of elements conveniently. (Using document.getElementsByClass is one way to achieve this; another way is to use jQuery; and you could even hand-code it rather simply.)
Designated class names are used in some metadata systems, such as microformats. Some search engines recognize such names and use them to provide semantic searching (though this approach probably loses to microdata, which uses different attributes).
A class name can be used in a user style sheet, e.g. by a developer who wishes to do some testing. This could well be the case if the class name is literally “anothertest.”
The name might be there to allow future development, e.g. so that elements of a class will be or may be styled in some future version. The designers might have ideas on styling but they haven’t decided on it—they just want it to be easy when they are ready.
It could be just a holdover. It was a class that had some use, but things changed. There was really no particular reason to remove it.
This is a very good question. It involved the difference between id and class.
ID
An ID placed on an element, is a unique identifier for that element. An element may only have one ID, and only one of the same ID may exist on a page. So for instance, the following examples are not possible.
<a id="someid anotherid">Multiple IDs - Wrong</a>
<a id="someid"><span id="someid">Same ID twice - Wrong</span></a>
Class
A class name however, is the exact opposite. An element may have several class names, and the same class name may appear multiple times on a page. Like so:
<a class="someclass anotherclass">Multiple Classes - Correct</a>
<a class="someclass"><span class="someclass">Same Class twice - correct</span></a>
In short, the syntax displayed in the question is simply having 2 class names on one element, which is perfectly acceptable.
Class name are also used to easily select elements in the page with JavaScript. You can use the getElementsByClassName method to access them or using your favorite CSS selector library (ex.: Sizzle) if you need compatibility for older browser.