In the Sass documentation for Placeholder Selectors it says
Sometimes you want to write a style rule that’s only intended to be extended. In that case, you can use placeholder selectors ... Any selectors that include placeholders aren’t included in the CSS output, but selectors that extend them are.
It then gives this example SCSS
.alert:hover, %strong-alert {
font-weight: bold;
}
%strong-alert:hover {
color: red;
}
which compiles to the following CSS
.alert:hover {
font-weight: bold;
}
The documentation seems to stop at this point which doesn't really explain what's going on here. If I just write this SCSS
.alert:hover {
font-weight: bold;
}
it will compile to the equivalent CSS. It doesn't really explain what %strong-alert:hover actually does because there's no output. I understand that's the intended outcome because the quote above says "selectors that include placeholders aren’t included in the CSS output".
But that leads to the question: what is the use-case for them? Can somebody give an example of using %strong-alert:hover?
Placeholder selectors have the additional property that they will not show up in the generated CSS, only the selectors that extend them will be included in the output.
Related
I have two Components and two css file for each component. css file is imported in req component. The problem is each component has same classnames and if i changes css in component it's effecting the other component with same class too.. Pls help.. comment if you don't understand my question
html {
font-family: sans-serif;
}
/*
This rule is not needed ↷
p {
font-family: sans-serif;
}
*/
html {
font-family: sans-serif;
}
p {
line-height: 1.5;
}
/*
This rule is not needed ↷
p a {
line-height: 1.5;
}
*/
About the css priority level,
Basically, the css that follows has a higher priority.
!important> inline style attribute> id> class, other attributes, capital class (like :first-child)> tag element, capital element (like ::before) in order of priority.
If the priorities are the same, the css with a larger number have higher priority.
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
If it is not inside and is imported, the priority is the same.
And because of the inheritance, cascade of css, it will affect if you define p even if it's a different file.
There are also css methodologies such as BEM, SMACSS, and OOCSS. However, this also does not solve the fundamental problem.
From CSS methodologies such as BEM and Atomic CSS through to programmatically encapsulated CSS modules, many are doing their best to sidestep or otherwise suppress these features. This gives developers more control over their CSS, but only an autocratic sort of control based on frequent intervention.
https://www.smashingmagazine.com/2016/11/css-inheritance-cascade-global-scope-new-old-worst-best-friends/
There are options such as shadow dom, but polyfill is also directly linked to performance issues.
If you're using react, I think the approach taken by the next's attitude that is looking at about css is probably the closest to the current best we can see.
I hope you have a look at the way css is divided in next.
https://nextjs.org/
I'm curious what the CSS directive #apply does. I have googled #apply but I couldn't find anything that could explain its meaning properly for me.
What is the usage of such a directive?
The simple way of explaining it would be; introducing variables into CSS (which is a feature of preprocessors, such as Sass), and mixins which are function like behaviors (also in preprocessors).
Imagine that --header-theme is a function (mixin):
:root {
--header-theme: {
color: red;
font-family: cursive;
font-weight: 600;
};
}
h1 {
#apply --header-theme;
}
h2 {
#apply --header-theme;
}
This way, you can use it in many different places without having to rewrite it again (DRY).
Now the variable part could be explained with this example:
:root {
--brand-color: red; /* Default value */
--header-theme: {
color: var(--brand-color);
font-family: cursive;
font-weight: 600;
};
}
h1 {
#apply --header-theme;
}
h2 {
--brand-color: green;
#apply --header-theme;
}
The mixin will have a variable sent to it and change the color.
This is not the limits of the feature, and you can use it for far more. You can read more about mixin and variables in Sass for other ways of using it, and after I suggest you read this blog post.
Now after I got you excited, it is time for the bad news. It is not implemented in browsers yet (Chrome), but it is still worth knowing that it is coming and maybe if you want to prepare yourself start with Sass.
#apply is from a proposal that has since been abandoned, and replaced with CSS Shadow Parts.
the #apply rule, which allows an author to store a set of properties
in a named variable, then reference them in other style rules.
Tailwind uses this as a special directive.
Tailwind's #apply is kind of like a super-class. You can list other classes that should apply to this rule. I think of it as a way to group classes together that are often found together.
#apply is pretty cool. It basically allows you to reuse CSS blocks without having to copy them around and without having to modify their selectors.
It will make it easier to use CSS frameworks and keep semantic class names at the same time.
I found this article to be a nice instruction to this feature.
Unfortunately, at the moment, browser support is basically non-existent. It can be used with a CSS pre-processor such as PostCSS.
It's future is also uncertain, if I understand well. The main advocate behind this feature stopped supporting it.
Is there/what is the best way to set a variable in my CSS stylesheet that is cross browser compatible?
I want to set
color: #123456;
into a variable since I am using it in numerous different spots and if I choose to change that colour I want it all the change.
CSS Variables are a thing but the only browser that has any support for it at this time is Mozilla.
Alternative options:
use Javascript and/or a server-side language to set the variables in your CSS file programatically.
use a CSS preprocessor like SASS. This allows you to create variables. You do have to re-deploy your CSS each time.
consider handling colors a different way in your markup.
Regarding the last one, instead of hardcoding a color into an elements style:
<div class="thisElement"></div>
.thisElement {
font-size: 13px
background: red;
color: #123456;
}
consider using classes for this instea:
<div class="thisElement color1"></div>
.thisElement {
font-size: 13px
background: red;
}
.color1 {
color: #123456;
}
That way you only need to declare the color once in your style sheet. This is essentially 'object oriented CSS'. The idea is that instead of applying monolithic style declarations for each DOM object, you instead declare 'snippets' of style to a bunch of separate classes, then assign those separate classes as you see fit to each DOM object.
In a sense, you've turned the class name, itself, into the variable. You declare it in your CSS once, then use it as many times as needed in your HTML.
If you want to do it in native css you can't. However, you can use technologies / preprocessors like SASS / LESS to achieve exactly what you are describing.
Cross-browser compatibility, variables and calculating.
Once you get used to the syntax (which is really easy to understand and modify) and you are ready to go, SASS creates the "plain" css files for you. Keeps your code clean, simple and easy to maintain.
Have a look at this:
http://sass-lang.com/
Also, here you can find some examples and snippets to have a first impression.
Its not well supported, but this is how it works according to
http://www.w3.org/TR/css-variables/
Custom properties define variables, referenced with the var() notation, which can be used for many purposes. For example, a page that consistently uses a small set of colors in its design can store the colors in custom properties and use them with variables:
:root {
--main-color: #06c;
--accent-color: #006;
}
/* The rest of the CSS file */
#foo h1 {
color: var(--main-color);
}
You can to use a preprocessor like SASS, which has this done much better.
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.
In CSS it is possible to style placeholder text within an input using a combination of vendor-specific pseudo-classes and pseudo-elements (to get the best cross-browser coverage).
These all share the same basic properties (ie: text styling and color declarations).
However whilst I inevitably want to apply the same styles irrespective of browser vendor, it doesn't appear to be possible to combine these together into a comma-separated selector (as you would with any other piece of CSS where you want two selectors to share the same styles).
As an example, I tend to target placeholder styling using the four following selectors:
input:-moz-placeholder
input::-moz-placeholder
input:-ms-input-placeholder
input::-webkit-input-placeholder
(although :-moz-placeholder is being deprecated in favor of ::-moz-placeholder this only occurred with the release of FireFox 19 so at present both are needed for better browser-support).
What's frustrating is that declaring and giving each (the same) style leads to a lot of repetition within the CSS.
So, to make sure that placeholder text is right-aligned and italic, I would end up with:
input:-moz-placeholder{
font-style: italic;
text-align: right;
}
input::-moz-placeholder{
font-style: italic;
text-align: right;
}
input:-ms-input-placeholder{
font-style: italic;
text-align: right;
}
input::-webkit-input-placeholder{
font-style: italic;
text-align: right;
}
What I really want to do is to combine them as one single comma-seperated rule set like this:
input:-moz-placeholder,
input::-moz-placeholder,
input:-ms-input-placeholder,
input::-webkit-input-placeholder{
font-style: italic;
text-align: right;
}
However, despite trying this on a fair few occasions, this never seems to work. It makes me concerned that there's some fundamental part of CSS that I'm not understanding.
Can anybody shed any light on why this happens?
CSS2.1 states:
The selector (see also the section on selectors) consists of everything up to (but not including) the first left curly brace ({). A selector always goes together with a declaration block. When a user agent cannot parse the selector (i.e., it is not valid CSS 2.1), it must ignore the selector and the following declaration block (if any) as well.
Note that since CSS2.1 pre-dates CSS3, "it is not valid CSS 2.1" is written under the assumptions that a user agent is fully CSS2.1-compliant and that CSS3 does not exist in theory. In practice, wherever the spec says "it is not valid CSS" or something to that effect, it should be taken to mean "it is not understood by the user agent". See my answer to this related question for a more in-depth explanation.
Namely, since one vendor's browser doesn't understand other vendors' prefixes, it has to drop any rules that contain those unrecognized prefixes in pseudo-class and pseudo-element selectors.1
For some insight as to why such a rule was put in place, see this answer.
1 Note that WebKit is notorious for partially flouting this rule: it has no trouble parsing rules whose selectors have unrecognized prefixed pseudo-elements (which in this case is ::-moz-placeholder). That said, the :-moz-placeholder pseudo-class in your combined rule will cause it to break anyway.
The specs say that if a user agent doesn't recognize part of a selector, it has to ignore the whole selector and its block.
http://www.w3.org/TR/css3-syntax/#rule-sets
The selector (see the Selectors module [SELECT]) consists of everything up to (but not including) the first left curly brace ({). A selector always goes together with a {}-block. When a user agent can't parse the selector (i.e., it is not valid CSS3), it must ignore the {}-block as well.