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.
Related
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.
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/
On my website, I'm constantly doing style="font-size: #ofpx;". However, I was wondering if there's a way to do it with scss so that, when I declare a class, it would also change the font size. For example:
<div class='col-lg-4 font-20'>whatever here</div>
and this would change my font-size to 20. If I did font-30, it would change my font-size to 30 and etc...
What I have so far:
.font-#{$fontsize} {
font-size: $fontsize;
}
This can't be done for arbitrary sizes. The nature of SCSS is that is needs to be flattened down to CSS before it gets applied to the HTML. What you are asking for, however, is essentially to create rules at run-time rather than compile-time.
In other words, SCSS makes it easier to write some of the repetitive parts of CSS, but it doesn't allow you to do anything new that wasn't already possible with plain old CSS.
What you're asking for is also a code smell. It smells like your markup isn't semantic enough. The purpose of a CSS class is to group objects with similar characteristics, but you're using them instead to describe the styles they impart. I would suggest stepping back and reconsidering what it is that you really want.
You obviously have details of certain elements that are context-dependent. For example, maybe you are applying these rules to buttons when you want to make them smaller or larger than usual. You need to identify the scenarios in which the buttons change. Maybe they are 20% smaller if they are in a modal dialog? Then write your normal .button rules, and also create rules for .modal .button which make it smaller.
If you're positive that you want to define font-size for each element within the HTML (and sometimes there are good reasons for doing so), just continue using inline styles. The only reason inline styling is frowned upon is because it combines model and view logic in a way that harms reusability; however, what you are requesting does so in exactly the same way. This is what inline styles were made for. Don't re-invent the wheel.
With all of that said, you can use sass loops to automatically generate classes for integers within a range. For example:
/* warning: this is generally a bad idea */
#for $i from 1 through 100 {
.font-#{$i} {
font-size: #{$i}px;
}
}
This is not a good idea. Pragmatically speaking it doesn't offer any advantages over just using inline styles and with large ranges your resulting file will be larger (which affects website load times).
Aside: There is a CSS philosophy (or fad, if you're feeling ungenerous) called Atomic CSS (or sometimes Functional CSS) which defies the classical advice given in this answer. I won't give an opinion on its effectiveness at producing clean, maintainable code, but it does typically require more tooling than SCSS alone if used with the degree of specificity requested in this question.
Just going to add, mixins are great, but if you want a util class (attach a class to an element, get that font-size applied to it, do a for-loop in SCSS like so..
#for $i from 1 through 4 {
$fontsize: 10px * $i;
.font-#{$i} {
font-size: $fontsize;
}
}
compiles to
.font-1 {
font-size: 10px;
}
.font-2 {
font-size: 20px;
}
.font-3 {
font-size: 30px;
}
.font-4 {
font-size: 40px;
}
If you want the class to match the # of pixels...
#for $i from 1 through 4 {
$base: 10;
$fontsize: $base * $i;
.font-#{$fontsize} {
font-size: $fontsize + 0px;
}
}
Which compiles to
.font-10 {
font-size: 10px;
}
.font-20 {
font-size: 20px;
}
.font-30 {
font-size: 30px;
}
.font-40 {
font-size: 40px;
}
Codepen example.
When using "words" instead of "numbers" for variables, and the word not being at the end of the classname. I could work something out using CSS Attribute selectors ("wildcard selector"). I can iterate over a map object, and use text values to build CSS selectors.
SASS
//map
$colors: (
primary: #121212,
success: #8bcea8
);
//loop
#each $color, $value in $colors {
//can't do this: div.first-class.is-style-#{$color}-component
//can do this:
div.first-class[class*="is-style-#{$color}-component"] {
background-color: $value;
}
}
HTML
<div class="first-class is-style-primary-component"></div>
This will generate a div.myComponent[class*="is-style-primary-component"] selector and so <div class="first-class is-style-primary-component"></div> (.first-class is not required, selector could be div[class*="is-style-#{$color}-component"] or even [class*="is-style-#{$color}-component"] only).
Yet, in some cases of CSS class naming, it could be limited due to the wildcard selector, which is "larger" than a specific class selector rule.
Of course, inline style tags are bad form. So yes, you should add some classes for font size, or just set font size on the elements you need to as you go. Up to you. If you want, you could use a mixin like so:
#mixin font-size($size) {
font-size: $size;
}
.some-div { #include font-size(10px); }
But that's probably overkill unless you get a group of rules that usually go together.
Just for those of you who might stumble across this question in a more recent time and are new to FrontEnd Development.
What Woodrow Barlow said about using inline-styles instead of rule specific classes isn't quite an up-to-date opinion. For instance, Bootstrap has some of those and Tachyons is entirely built upon them. Actually this practice is called Atomic CSS or Functional CSS.
It's better explained by John Polacek in his CSS Tricks article:
https://css-tricks.com/lets-define-exactly-atomic-css/
You can use mixins like this
#mixin font($fontsize) {
font-size: $fontsize;
}
.box {
#include font(10px);
}
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.