Using OR in CSS selectors - css

I have an element which appears on many pages and I would like to style it differently based on the class of the high-level div which it is present in. For example, if I want to change the color of my logo depending on the "type" of page it is present on. Then let's say these types can be grouped (so typeA, typeB and typeC should use one color while typeD and typeE should use another). Also, as high-level div's these types are used for other things as well so they cannot be merged.
.typeA #logo,
.typeB #logo,
.typeC #logo{
color: #ffffff;
}
.typeD #logo,
.typeE #logo,{
color: #000000;
}
Is there a way to chain together with some selector so that I don't have to make this code look so nasty. This example is small but the real-world version involves a whole lot more types. Is there a way to do something like:
.typeA || .typeB || .typeC #logo{
color: #ffffff;
}

As others said, CSS doesn't support that kind of grouping.
If you have control over your markup, why not just add a common class to each group of type classes then select that common class?
Example:
<div class="typeA type1">
<span id="logo">Site Title</span>
</div>
<div class="typeD type2">
<span id="logo">Site Title</span>
</div>
.type1 #logo { color: #ffffff; }
.type2 #logo { color: #000000; }

In short: no.
There are systems like LESS which make this possible but the rendered css will still look like your first example

Sorry, not in straight CSS, no. There are projects like http://sass-lang.com/ that require an external compiler to do what you want, however.

This isn't possible with pure CSS. It can be done however with a meta language like SASS. Check out http://sass-lang.com/ for more information.

There is no "or" in css that i know of. Just use a different selector that is a parent of typeA,B and C like "containerA" or "containerB"

Related

How to change classes while object oriented css with bem?

Well I'm watching videos about oop css with bem. I didn't understand one thing. I have a media object and I use it everywhere like in navbar and content and footer etc. So how shall I change the media object and insiders. I guess 3 ways there are.
1 - I can catch inside other blocks grandchild chooser
it will like ".navbar .media".
This way makes me worrying because of grandchildren is making slow and complicated I think. Don't think about only .media. I have to select media-item etc etc...
2 - I can give another class to .media like .navbar together
it will like ".navbar.media".
This way need more classes to html so it makes me thinking.
3 - I guess there is no third option if there is please let me know :) Which way I shall do.
Thank you already.
You should add an extra class, navbar__media (that's a double underscore for descendant), and add that to the media elements inside of the navbar.
A rule of BEM/OOP CSS is that an element should always have their style defined by the classes they have, and not based on where they are in the DOM.
For reference: http://getbem.com/naming/
Example:
<div class="navbar">
<div class="media navbar__media"></div>
</div>
<div class="media"></div>
With this css:
.navbar {
background: #00f;
}
.media {
background: #f00;
}
.navbar__media {
background: #0f0;
}

Make LESS remove useless IDs when compiling

One feature I really love with LESS is nested rules. It makes the stylesheet much cleaner that way and you can find an element very quickly.
I was wondering if there's an option when compiling to optimize selectors. For example...
#global {
/* Styles here maybe */
.container {
/* Styles here maybe */
#sidebar {
/* Styles here maybe */
.title {
font-weight: bold;
}
}
}
}
will be compiled to #global .container #sidebar .title { font-weight: bold; }.
But the first two selectors are useless, since #sidebar should be unique in my page.
Is there a way to ask LESS to compile this to #sidebar .title { font-weight: bold; } instead?
Your assumption is wrong that multiple IDs in CSS are redundant. Imagine, as an example, a site where the CMS generates the page type into the output, like that it's the contact page:
<body id="contact">
<section id="content">Blah</section>
</body>
According to your logic, the following piece of CSS would be a candidate for 'optimization':
#contact #content {
background:red;
}
Now however, your home page has <body id="home"> of course in this imaginary CMS. And suddenly the content of your homepage has a red background because you decided to erroneously optimize that #contact selector out of the CSS, while it most certainly shouldn't have a red background according to this rule.
So no, LESS cannot do this because it would break code. If you don't want the selectors, don't use them and don't put them in your code.
Other answers, including the accepted one, have explained convincingly why LESS cannot simplify your nested selectors in the way you want.
Actually, SASS has the ability to do this:
#global {
.container {
#at-root #sidebar {
.title {
font-weight: bold;
The #at-root directive essentially ignores all the higher nesting selectors. I don't know if LESS has something similar. The above compiles into simply
#sidebar {
.title {
font-weight: bold;
But there is a deeper issue here, starting with the fact that you "love" nested rules in LESS. Stop loving them quite so much. I don't know about you, but most people love nested rules because they think it's cool to exactly mimic the hierarchical structure of their HTML. The SASS docs even claim this as a benefit:
Sass will let you nest your CSS selectors in a way that follows the same visual hierarchy of your HTML.
So people with HTML such as
<div class="foo">
<ul>
<li class="item">
write LESS like
.foo {
ul {
li.item {
This is a horrible, horrible idea, It makes the structure of CSS completely dependent on the structure of the HTML. If you change one nesting level in the HTML, your CSS breaks. Often this approach is combined with a lot of rules defined against tag names such as ul instead of class names, which aggravates the dependency, so changing the ul to ol in the HTML breaks the rules again. Or it's combined with rules based on Bootstrap classes such as col-md-6, so if you ever change that to col-md-4 things break again.
CSS rules should be orthogonal to the HTML. They represent a different dimension. They represent styling concepts which are applied selectively throughout and across the HTML.
I am guessing that you wrote
#global {
.container {
#sidebar {
.title {
font-weight: bold;
because you are adopting this mistaken idea of mirroring the HTML structure in your LESS. Then, you notice that this compiles down to having selectors which contain multiple IDs, which you imagine must be inefficient (although, actually, the degree of inefficiency is minimal). You yourself are writing extraneous nesting levels in your LESS, then complaining that they may be slowing down performance!
Worse, you've hard-wired assumptions about the HTML structure into your CSS. It's of no consequence that the sidebar happens to fall inside a .container which is inside a global element. So don't write them. Perhaps at some point you decide to change the container class to container-fluid. Boom, instantly your CSS breaks. What is the point of conditionalizing the fact that the title should be bold on it being contained with a container class, which in any case is a layout-related class that has (or should have) nothing to do with styling? If you're going to duplicate your HTML structure in your CSS using preprocessor nesting, just go back to writing inline styles. At least that way you'll only have one file to change when you change your HTML around.
When designing CSS, you should think just as hard about the design of the rules as you do about the design of classes and methods when writing JS. In this case, you need to ask yourself, "What characterizes the situation where I want some title to be bold? What drives that? What is the nature of boldness? What am I indicating by boldness? What is the semantic notion indicated by boldness?"
Let's say that you want all titles to be bold. Then you simply say that:
.title { font-weight: bold }
Let's say that you want a title to be bold only when it's in the sidebar. Then you simply say that:
#sidebar .title { font-weight: bold; }
My suggestion here is to go cold turkey. Stop using nesting during a withdrawal period. Write rules with the minimum number of selector components. Refactor your classes to have semantic names (such as title-emphasis). Once you're "sober", you can go back to cautiously using LESS's nesting capability when it is useful, such as perhaps for hover:
#boo {
color: red;
&:hover {
color: blue;
}
}
This is actually useful and saves you from writing #boo twice, and groups the rules in an easy-to-understand way.

Do CSS functions exist?

I'm not sure what to call this, but basically let's say I have a style that I use a lot,
.somepattern{
font-size:16px;
font-weight:bold;
border:2px solid red;
}
but sometime I want to change the font-size and the color for border. Is it possible to treat this code as a library, where I can set the style to a div
<div class="somepattern">Text</div>
but still control the 16px and red like we do with functions?
I know I'm late to the party but the selected answer IS NOT the right answer since it's deferring it to CSS preprocessors.
To answer the specific question "Do CSS functions exist?", the answer is: Yes.
However, CSS functions work completely different than the OP's concept initially is.
cuixiping's answer seems the most correct answer.
Examples of CSS functions are:
url()
attr()
calc()
rotate()
scale()
linear-gradient()
sepia()
grayscale()
translate()
A detailed, comprehensive list can be found here:
CSS functions on MDN Updated link 18/9/20
You can't programatically control CSS from your markup, but you can use one of the many CSS extensions to make CSS work more like a compiled language.
http://lesscss.org/
http://sass-lang.com/
If we wrote your example in LESS, we'd get something like this:
.somepattern(#color: red, #size: 16px) {
font-size:#size;
font-weight:bold;
border:2px solid #color;
}
And then you could use it in your LESS file like so:
.myclass {
.somepattern(green, 20px);
}
Nope. No CSS functionality like you require. At least not directly.
But there are at least two rather generic ways for you to use to accomplish what you need:
Class combining
You can of course combine as many classes as you like in any element like:
<div class="heading run-in">
Some heading
</div>
Lorem ipsum dolor sit amet...
and you'd have CSS defined as:
.heading {
color: #999;
font-size: 16pt;
font-weight: bold;
border-bottom: 2px solid red;
display: block;
margin: 1.5em 0 .5em;
}
.run-in {
display: inline;
margin: 0;
font-size: 1em;
}
LESS CSS
And there is of course LESS CSS project that lets you define variables (and has other sugars as well) and use them in other classes.
LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions. LESS runs on both the client-side (IE 6+, Webkit, Firefox) and server-side, with Node.js.
If your server platform is .net there's a project DotLessCSS with a library in .net as well. And there's also T4 template by Phil Haack.
Mind that there are many CSS preprocessors/enhancers like LESS CSS as well:
SASS
xCSS
HSS
CleverCSS
And probably some others that I didn't mention. Some support nesting CSS3 selectors as well others don't. Some are aimed at particular server-side technology some don't. So choose wisely.
you can redefine style by adding the style tag to your HTML:
<div class="somepattern" style="font-size:5px">Text</div>
or by applying multiple classes like class="somepattern small".
HTML
<div class="somepattern small"> Text </div>
CSS
.small {
font-size:5px;
}
the small class will be applied after the somepattern class and will therefore override any properties set in the some pattern class.
Even later to the party!
You can now do this with css custom variables.
In our css using the var() function:
.some-pattern {
font-size: var(--font-size);
font-weight: bold;
border: var(--border);
}
Then in our html defining the custom variables inline:
<div
class="some-pattern"
style="--border: 3px double red; --font-size: 16px;"
>
test
</div>
What you described is actually done with style attribute.
<div class="somepattern" style="font-size:10px;">Text</div>
I think this is exactly what you want. And it is not recommended, because it breaks the usual (good) pattern of spitting content and its visual style. (Although, honestly, I do use it a lot. ;-))
its a css class. It cannot be used like functions if that's what you are asking. There is no code library as its not a compiled. CSS is just presentation semantics (formatting) of a document written in a markup language. You can include all css classes in a .css file and use it where ever you want instead.
I've come to realize through the comments of others that this solution overcomplicates the problem at hand. This solution works but there are easier and better alternatives that do not depend on server-side scripting.
You can actually control your stylesheet if you make it a php file stylesheet.php?fontsize=16 and then inside your stylesheet you can retrieve the variable
<?php
header("Content-type: text/css");
$fontsize=16;
?>
.somepattern{
font-size: $fontsize;
font-weight:bold;
border:2px solid red;
}
Yes, it's possible. But you have to make it on your own with the help of Recatjs(u don't have to go deeper, basic is enough for this). Actually, think like that If bootstrap can make such things where we just have to define the class name and it automatically designes HTML files, then why we cannot do it.
Here's the image of my code(https://i.stack.imgur.com/hyePO.png)
and this is how I used it in my jsx code (https://i.stack.imgur.com/yK6VD.jpg)
Do you mean inline styles ? <div class="somepattern" style="border-color:green">Text</div>

Can I join 2+ styles together into a superstyle?

I was looking to join 2 styles together to make a super style for easy use and customisation of my page.
Is it possible to define something like this? (if so how)
.bold { font-weight: bold;}
.color1 {color: white;}
.boldColor {.bold; .color1;}
where .boldColor is effectively
.boldColor {font-weight:bold; color:white;}
I want this so that I can have styles thoughout the page and be able to easily change the colors in many places in 1 place. I'm currently using <p class="bold color"> but some of my class defs are becoming long so I'd like to be able to use <p class="boldColor">
Thanks
You can't do exactly what you are asking for but you can get similar effects by using a comma to separate multiple css selectors that share the same properties.
.bold, .boldColor {
font-weight: bold;
}
.color1, .boldColor {
color: white;
}
This way class="boldColor" will have the same effect as class="color1 bold".
This is not possible using normal CSS. You would usually do this, as you already say, by combining class names: bold color
There are CSS "pre-compilers" that can do advanced things on CSS stylesheets, like working with variables. I don't know of any that does "class fusions" like you request but I'm sure they can be helpful in reducing code size. Check out LESS and xCSS, for example.
No, the CSS spec does not support this.
No you cannot do this. How you are doing it currently is ideal.
Check out LessCss (.NET version)

Use HTML tag names, classes or IDs in CSS?

In designing the HTML and CSS for a page, when should I use
img.className
versus
.className
versus
#idName
or some other variant?
Are there guidelines or recommendations?
Summary from answers
Thank you to all answerers - there is some excellent stuff here!
make CSS as specific as possible
use an OO approach
order: #id, tag, tag.className, .className
when to use each selector, also class/ID comparison
give selectors names based on purpose, not what they look like
use advanced selectors for smaller code, leave CSS classes for exceptions/overrides only
manage ASP.NET munging ID
In general you should be as specific as the item demands.
There is no general rule, it depends on the style in question.
A lot of people will recommend you keep to the lowest specificity with the theory that this allows the maximum cascading reuse but this is absolutely toxic in real world situations where you have multiple developers all working on slightly different versions of what a .foo might look like. Pollution from inheritance you did not want leads to massive bloat in trying to undo that locally or time-loss in refactoring.
The best guideline I always offer is to try and think of CSS in OO terms: class selectors map to interfaces more or less, tags map to classes, and ID selectors map to instances. Consequently decide if the style you want to apply really applies to that thing, all things like it, or anything which wants it.
I also strongly encourage you to make use of high level IDs on wrapper elements so you can write selectors in a namespace like fashion (i.e. #foo .bar, #foo .baz where #foo is unique to a page or set of page designs) which allows you both a level of specificity which reduces cross-design pollution and a level of generality which lets you make the most of cascading CSS reuse.
Best of both worlds.
It depends on the intended semantics, and, as others said, be as specific as possible.
#idName for unique elements on the page. Good examples are #header and #footer
TAGNAME for general purpose page styling.
TAG.classname and .classname for exceptions/overrides to the above rules.
And don't forget the use of advanced selectors. A bad example:
<style>
H1{ font-size: 200%; color: #008; }
#mainMenu { color: #800; }
.in_the_menu { color: #800; font-size: 150%; }
</style>
<h1>Hello World!</h1>
<div id="mainMenu">
<h1 class="in_the_menu">My Menu</h1>
</div>
The same could have been achieved with:
<style>
H1{ font-size: 200%; color: #008; }
#mainMenu { color: #800; }
#mainMenu H1 { color: #800; font-size: 150%; }
</style>
<h1>Hello World!</h1>
<div id="mainMenu">
<h1>My Menu</h1>
</div>
The second example gets rid of the superflous "class" attribute on the H1 element in the "mainMenu" div. This has two important benefits:
The HTML code is smaller and cleaner
You are less likely to forget to add the class attribute
If you take good care of you CSS, and make use of proper advanced selectors, you can nearly completely leave out CSS classes. And keep them only for exceptions/overrides.
Take this example which draws boxes with headers:
#content H2{
border: 1px solid #008789;
padding: 0em 1em;
margin: 0.2em 0em;
margin-bottom: 1em;
font-size: 100%;
background: #cccb79
}
#content H2 + DIV{
margin-top: -1em;
border-left: 1px solid #008789;
border-right: 1px solid #008789;
border-bottom: 1px solid #008789;
margin-bottom: 1em;
}
Now, as soon as you follow a H2 with a DIV in the #content element, you have a nice box. other DIVs and H2s are left alone:
<div id="content">
<h2>Hello Box!</h2>
<div>Some text</div>
<div>Some more text</div>
<div>Some more text</div>
<h2>And another title</h2>
</div>
If you get these rules right, you hardly ever need classes, and can work with IDs and TAG names alone. And as an added bonus, your HTML will be a lot nicer to read and maintain.
You preference should be, in order from highest to lowest:
id
tag
tag.className
.className
ID selectors are fast. Tag selectors are reasonably fast. Pure class selectors are slow because the browser essentially has to interrogate every element and see if each has that class. Getting elements by ID or tag name are "native" operations from a browser's context.
Also, I find it good practice to make your CSS selectors as restrictive as possible otherwise it just turns into a mess and you end up getting all sorts of unintended consequences where CSS rules apply where you didn't otherwise expect, which often forces you to create a similar yet different selector just so none of the rules regarding the first don't apply (translating into more mess).
Basically if you know if you only use a class on div elements then do this
div.className
not
.className
If you apply a class to several elements just list them:
h1.selected, h2.selected, h3.selected
instead of
.selected
In practice I find very few situations where you need to use "naked" class selectors or where it is advisable to do so.
you should use the selector best describing your rules
id: when you want to select one single element
.classname: when you want to style elements regardless of their tag
tag.classname: when you want to style only tags with the given class
tag tag tag: when you want to style all subelements of a tag
Class selectors
.className
This is to be used when you have more than one element on the page that you would like to apply the same style to. It can be to any tag element. So in the following all will use the same style as set out by the .className.
<p class="className"></p>
<img src="/path/to/image.png" class="className" />
But you can also restrict it like so:
img.className
By placing the tag along with the style definition, you're saying that this style is only to be used when it's the class used by that particular tag, in this case, an image.
HTML code will look like this:
<img src="/path/to/image.png" class="className" />
If you have other elements on the page using the same class style, but are not of the same tag, then the styles set out in this will not be applied and they will take on the more generic version as mentioned in the first example.
So repeating the example above:
<p class="className"></p>
<img src="/path/to/image.png" class="className" />
Only the image will take on the style as set out by img.className whereas all the rest will take on the style rules set in .className.
ID selectors
#idName
This is to be used when there is only one instance of a particular element that you wish to apply the style to.
You can also force it to apply only in certain tag conditions as you have earlier with the class definitions.
p#idName
This example will only apply to the paragraph block marked with the ID:
<p id="idName">
If you were to put that id on another element, like this:
<div id="idName"></div>
Then it will not take on the style set out and be ignored.
As to your two first selectors, the first of the two will overwrite the second, as it's more specific. You can calculate the specificity of a selector.
One thing worth noting is that some server side scripting technologies (most notably ASP.NET) don't play well with using IDs for your styling. If there is a chance your design will be used with such a technology, I recommend forgetting about #id selectors and use tag.className instead.
The reason is that ASP.NET actually changes the ID that ends up in the HTML based on a number of criteria, if the tag is output by a server side control.
I know this is a pretty old question but for all those who are reading this just now...
There are 4 categories of rules in general:
ID Rules, Class Rules, Tag Rules, Universal Rules.
And it's important to mention that class selectors are faster than tag selectors. So you should always use them in the following order
1. ID Selector
2. Class Selector
3. Tag Selector
4. Universal Selectors
In your case you should never use the tag name before class name.
You can find more information here: Writing efficient CSS
It really depends on the situation:
.error{
color:red;
}
p.error{
background-color:yellow;
}
div.error{
background-color:grey;
}
Always use the cascading effect of CSS to your advantage.
It's good practise to use the least specific rules you can for each rule.
How you structure your CSS will depend on the particular needs of the design.
Yes. You may want to use the same classname for two elements in the future. Be explicit and clear. This will also prevent class-rules from overlapping onto unintended elements.
h1.title { font-size:18px; } /* My h1's are big */
p.title { font-size:16px; } /* My p's are smaller */
.title { color:#336699; } /* All titles are blue */
Use ID's only when necessary, and only once per page.
When to use what depends on what you want to select. img.className (type selector + class selector) selects only IMG elements that’s in the class “className” while .className (just class selector) selects any element that’s in that class and #idName (id selector) any element with the ID “idName”.
But besides that, the selector all have a differente specificity that affects the order in which the properties of that rules overwrite the one of others.
So if you have an IMG element with the ID “idName” that’s in the class “className”:
<img src="…" id="idName" class="className">
The properties of the rules would be applied in the following order (specificity from highest to lowest):
#idName
img.className
.className
But when you use a specific class only for one specific type of elements (e.g. “className” only for IMG element), you can go with only .className.

Resources