Inherit css property from another property of a different class - css

Is there a way to get the below to work?
.class1 {
line-height:20px;
}
.class2 {
height: class1.line-height;
}
I know that css variables would be the way to go but since it is in experimental phase, it would not be a suitable for our project. Is there any other way?

You can't really use dependencies like that in CSS without a preprocessor such as SASS or LESS. But you can apply more than one class to the HTML.....
<div class="class1 class2"></div>
In this case, class1 would contain the line-height, then class2 would contain any other properties you want to apply to that particular div.
Any similar properties between class1 and class2 would allow class2 to take precedence, since it's loaded after class 1, assuming the CSS hierarchy is logical.
For example:
.class1 { line-height: 1.3; background-color: red;}
.class2 { background-color: blue; }
The div would have a line-height of 1.3x and a background color of blue.

yeah.. you can't use dependencies like that in CSS.
you have to use SASS or LESS..
you can do like this in SASS
.class1 {
line-height:20px;
}
.class2 {
#extend.class1
}

Five years later...
I know that css variables would be the way to go but since it is in experimental phase, it would not be a suitable for our project.
As it's 2021 (and no-one is using Internet Explorer 11 anymore, phew, and all the major browsers fully support CSS Variables CSS Custom Properties) so you can now use var().
If you simply want to only define 20px once to avoid repeating yourself in CSS, then set a custom-property on a common ancestor of both .class1 and .class2 elements: most people use html (or html:root or just :root) for this:
:root {
--my-height: 20px;
}
.class1 {
line-height: var(--my-height);
}
.class2 {
height: var(--my-height);
}
Now, if you want .class2 elements to "inherit" their height: from any ancestor class1 elements instead of <html>, then this should work:
:root {
--my-height: 50px; /* Default value for .class2 elements which are not descendants of .class1` */
}
.class1 {
--my-height: 20px; /* Redefining the value */
line-height: var(--my-height);
}
.class2 {
height: var(--my-height);
}
...or if you want only .class2 descendants of .class1 to use the value:
:root {
}
.class1 {
--my-height: 20px;
line-height: var(--my-height);
}
.class1 .class2 {
height: var(--my-height);
}
But you probably shouldn't be setting line-height anyway - doing-so is a sign that you're misusing display: inline; or vertical-align:;.

Related

Sass: placeholder behaviour for selectors

I'm having some trouble understanding the placeholder behavior for selectors when compiled into css. So I've created a placeholder inside a class selector (.test) and I'm trying to extend it into another class (.test1) inside a third class (.test2). it compiled into css without any error although I'm curious how the selectors formed when compiled. here are the output and code snippets.
This is not actual use case but I'm just wondering how the selectors formed in the output?
.test {
%placeholder {
font-size: 14px;
}
}
.test2 {
.test1 {
#extend %placeholder;
}
}
Output
.test .test2 .test1, .test2 .test .test1 {
font-size: 14px;
}

how to use `or` in css selector to select its child?

I want to select a child dom with below css selector:
.parentA .child{
}
.parentB .child{
}
how can I combine them into one selector? I have tried below but doesn't work:
.parentA,.parentB .child{
}
To answer your specific question, there is no OR in CSS. There is only AND and you use , (comma) for it.
Which is to say whenever you want to assign the same set of rules to more than one selector, you can separate each case using a comma:
.parentA .child,
.parentB .child {
/* rules here */
}
They apply separately, which is to say the above is equivalent with this non DRY (hence wrong) way of writing it:
.parentA .child {
/* rules here */
}
.parentB .child {
/* rules here */
}
To apply the DRY principle to selectors, if they share a pattern, you could use SASS (or other pre-processors) and nest selectors, like this:
.parentA, .parentB {
.child {
/* rules here */
}
}
But SASS is a CSS pre-processor which, when parsed, will result in the CSS mentioned initially.
Have you tried?:
.parentA > .child,
.parentB > .child{
}
In plain CSS you have to repeat the entire selector, .parentA .child, .parentB .child, but if you use LESS, Sass or other preprocessors, you can do:
.parentA, .parentB {
.child {
color: red;
}
}
Which will get compiled out to the former for you so you don't have to repeat yourself.

Select multiple classes with same property

I have multiple classes like this with same property:
.class1 > div{
background-color: red;
}
I try to reduce the CSS code with:
.class1, .class2, .class3 > div{
background-color: red;
}
But it doesn't work properly, it only takes the last class in this case .class3.
Is there a way to properly do this?
If you want the child div selected for each of the classes, you'll need to specify it with the selector for each class like so:
CSS
.class1 > div, .class2 > div, .class3 > div {
background-color: red !important;
}
Single Selector (Wrong)
Selector For Each Class (Right)
You will be able to use :matches pseudo-class in CSS Selectors Level 4.
:matches(.class1, .class2, .class3) > div {
...
}
It only works in certain browsers at the moment, e.g. latest Apple Safari.
For now, you will have to use the old syntax, :any with their respective prefix in Firefox and Chrome. Not supported in IE and Edge.
:-moz-any(.class1, .class2, .class3) > div { ... }
:-webkit-any(.class1, .class2, .class3) > div { ... }
:-moz-any(.class1, .class2, .class3) > div {
background: aqua;
}
:-webkit-any(.class1, .class2, .class3) > div {
background: aqua;
}
:matches(.class1, .class2, .class3) > div {
background: aqua;
}
<div class="class1"><div>1</div></div>
<div class="class2"><div>2</div></div>
<div class="class3"><div>3</div></div>
<div class="class4"><div>4</div></div>
<div class="class5"><div>5</div></div>
Hopefully, the standard :matches will be available in all the major browsers in the near future. Other than that, please write the whole selectors for each one and separate them with commas:
.class1 > div,
.class2 > div,
.class3 > div {
...
}
References:
4.2. The Matches-Any Pseudo-class: :matches()
Complex CSS Selectors Inside Selectors
Can I use :matches() CSS pseudo-class

LESS CSS nesting classes

I'm using LESS to improve my CSS and am trying to nest a class within a class. There's a fairly complicated hierarchy but for some reason my nesting doesn't work.
I have this:
.g {
float: left;
color: #323a13;
.border(1px,#afc945);
.gradient(#afc945, #c8da64);
.common;
span {
.my-span;
.border-dashed(1px,rgba(255,255,255,0.3));
}
.posted {
.my-posted;
span {
border: none;
}
}
}
I can't get the .g.posted to work. it just shows the .g bit.
If i do this it's fine:
.g {
float: left;
color: #323a13;
.border(1px,#afc945);
.gradient(#afc945, #c8da64);
.common;
span {
.my-span;
.border-dashed(1px,rgba(255,255,255,0.3));
}
}
.g.posted {
.my-posted;
span {
border: none;
}
}
I'd like to nest the .posted in .g though. Any ideas?
The & character has the function of a this keyword, actually (a thing I did not know at the moment of writing the answer). It is possible to write:
.class1 {
&.class2 {}
}
and the CSS that will be generated will look like this:
.class1.class2 {}
For the record, #grobitto was the first to post this piece of information.
[ORIGINAL ANSWER]
LESS doesn't work this way.
.class1.class2 {} - defines two classes on the same DOM node, but
.class1 {
.class2 {}
}
defines nested nodes. .class2 will only be applied if it is a child of a node with the class class1.
I've been confused with this too and my conclusion is that LESS needs a this keyword :).
.g {
&.posted {
}
}
you should add "&" before .posted
If the ampersand is located right next to the child element in nesting, it is compiled into a double class selector. If there is space between & and selector it will be compiled into child selector. Read more about nesting in Less here.

Nesting CSS classes

Can I do something like the following?
.class1{some stuff}
.class2{class1;some more stuff}
Update 1: There is a CSS3 spec for CSS level 3 nesting. It's currently a draft.
https://tabatkins.github.io/specs/css-nesting/
Update 2 (2019): We now have a CSSWG editors draft
https://drafts.csswg.org/css-nesting-1/
Update 3 (2022): We now have a W3C First Public Working Draft https://www.w3.org/TR/css-nesting-1/
If approved, the syntax would look like this:
table.colortable {
& td {
text-align:center;
&.c { text-transform:uppercase }
&:first-child, &:first-child + td { border:1px solid black }
}
& th {
text-align:center;
background:black;
color:white;
}
}
.foo {
color: red;
#nest & > .bar {
color: blue;
}
}
.foo {
color: red;
#nest .parent & {
color: blue;
}
}
Not possible with vanilla CSS. However you can use something like:
Sass
Sass makes CSS fun again. Sass is an
extension of CSS3, adding nested
rules, variables, mixins, selector
inheritance, and more. It’s translated
to well-formatted, standard CSS using
the command line tool or a
web-framework plugin.
Or
Less
Rather than constructing long selector
names to specify inheritance, in Less
you can simply nest selectors inside
other selectors. This makes
inheritance clear and style sheets
shorter.
Example:
#header {
color: red;
a {
font-weight: bold;
text-decoration: none;
}
}
Not with pure CSS. The closest equivalent is this:
.class1, .class2 {
some stuff
}
.class2 {
some more stuff
}
Not directly. But you can use extensions such as LESS to help you achieve the same.
No.
You can use grouping selectors and/or multiple classes on a single element, or you can use a template language and process it with software to write your CSS.
See also my article on CSS inheritance.
I do not believe this is possible. You could add class1 to all elements which also have class2. If this is not practical to do manually, you could do it automatically with JavaScript (fairly easy to do with jQuery).
If you cannot wait until native CSS nesting goes official, you can use Container Queries to do it. As of now, it is supported (partially) by Chrome & Edge 105+, as well as Safari 16+.
It will looks like this:
.class1 {
container-type: inline-size;
container-name: my-container;
// other style rules
}
#container my-container (min-width: 0px) {
.class2 {
// some style rules
}
}
More details can be found at here.
Try this...
Give the element an ID, and also a class Name. Then you can nest the #IDName.className in your CSS.
Here's a better explanation
https://css-tricks.com/multiple-class-id-selectors/

Resources