SCSS/CSS Using :not selector for only certain elements - css

I have a common element which contains articles, and want to treat all but the first child differently as follows:
.listing{
article{
// Some styles
}
article:not(:first-child){
// Some more styles
}
}
All well and good. However on some listings they should all be treated the same, so I don't want to include the article:not(:first-child) selector, it needs to be like the following:
.listing.alt{
article{
// Some styles
// Some more styles
}
}
How can I combine these two rules without repeating everything?

Ok I think I've figured it out using Sass:
.listing{
article{
// Generic Styles
}
&.alt article,
&:not(.alt) article:not(:first-child){
// More Styles
}
}
I also see that my original code example was a bit weird so I've updated it so it's a bit more correct.

HTML
<div class="listing">
<article>1</article>
<article>2</article>
<article>3</article>
</div>
<div class="listing alt">
<article>1</article>
<article>2</article>
<article>3</article>
</div>
CSS
.listing:not(.alt) article:not(:first-child) {color:gainsboro;}
Updated demo

Related

CSS Modules & ReactJS: Parent and child CSS classes in different components

So I am building a react application and have a quick question. If I have two separate components:
and
with CSS classes navigation.css and navigationLogo.css respectively. In navigation.css I have a class named .main and in navigationLogo.css I want to have a class like so:
.main .main_in_logo {
color: red;
}
But with CSS Modules I am unable to do this, any ideas on a work around?
I just feel that the explanations here are not complete enough. In css you do .parentSelector .childSelector in order to select the child. The same rule is for css modules, but in your html/jsx you should add to the parent and the child the relevant className -> styles.parentSelector , styles.childSelector.
<div className={styles.container}>text</div>
This way you can have in your css something like:
.banner .container{
background-color:reb;
}
.banner .container{
background-color:blue;
}
Sometimes you use libraries and you want to change something somewhere down the DOM inside the library and you can't change its source code. In this case you can use the :global like this:
.parentElement :global(div)
.parentElement :global(#some-lib-element-selector)
I was looking for the same problem and didn't find the solution here, maybe because the post is 3 years old. The accepted answer is, in my opinion but not mine only, not scalable.
I don't really know if this is something new, but I found out what I would do in vanilla CSS adapted to CSS modules.
Here is what I did and fully suits my needs:
/* parent.css */
.main {
...some CSS...
}
/* logo.css */
#value main from "./parent.css";
.logo {
...some CSS...
}
.main .logo {
color: red
}
Here, we are using #value, which is a CSS modules variable and allows us to bind with another file to build a selector including the final name of the parent "main".
As strange as it looks to me, it took some time to find out about this solution, I hope this will save some time and help other people!
Why you need to create .main .main_in_logo - the main idea of styles with parent elements its not to broke your css with other styles in the future. But its impossible with css modules, because your styles will be unique forever.
But even you really need it you can use global css for these 2 components - documentation about global css for react-css-modules.
The child component should not have a css rule that is dependent upon the parent css classname.
the child should just be:
.main_in_logo { color: red; }
If you need to define styles that involve both parent and child, then the easiest way is to define the styles completely in the parent:
/* navigation.css */
.main .main_in_logo {
color: red;
}
Then have the parent pass the css class to the child and tell the child to use it:
// Navigation.js
<NavigationLogo className={navigationCss.main_in_logo} />
// NavigationLogo.js
<div className={"foo " + this.props.className}>stuff</div>
You don't need to be specify which child class you are referring to when using CSS modules in ReactjS.
so doing:
.main_in_logo {
color: red;
}
will be enough in the stylesheet.
I ended up using CSS the normal way but with BEM convention.
I mean after all, what the CSS modules do is adding the [this_name].module.css to your css classes anyway. If you typed it correctly in the first place, there's no need of using this. It's just a new abstract that allow newbies so they can just do stuff without having to worry about class names clashing.
// Main.jsx
import './Main.css'
import Logo from './Logo.jsx'
const Main = () => {
return (
<div className="main">
<Logo className="main__logo" />
</div>
)
}
/* Main.css */
.main {/* do magic */}
.main__logo {/* do magic but for Logo component */}
So maybe you had Logo component like this..
// Logo.jsx
import './Logo.css'
const Logo = () => {
return (
<div className="logo">
<img className="logo__img" />
</div>
)
}
/* Logo.css */
.logo {/* do magic for logo */}
.logo__img {/* do magic for logo's image */}
This feels much more natural.

Can I adhere to OOCSS separation of container and content when object style need to depend on parent container?

My question is different than this one, but it's regarding the same principle, so this quote is relevant here too:
from https://github.com/stubbornella/oocss/wiki
Essentially, this means “rarely use location-dependent styles”. An object should look the same no matter where you put it. So instead of styling a specific h2 with .myObject h2 {...}, create and apply a class that describes the h2 in question, like h2 class="category".
But what if the design dictates that an object's style changes when it's inside certain containers? Here's a simplified example of my problem. Let's say there's an object called foo, and a container object called bar. foo and bar have their own location-independent styles:
.foo {
...
}
.bar {
...
}
But when foo is inside container bar like so, its color needs to change when the user hovers over bar:
<div class="bar">
...
<div class="foo">
...
</div>
...
</div>
It seems in this case, you can't avoid writing a location-dependent selector that looks like this:
.bar:hover .foo {
// color style
}
One solution I thought of is to introduce a class that's explicitly dependent on bar (named using BEM naming convention to be explicit about parent-child relationship), and add it to the foo object:
<div class="bar">
...
<div class="foo bar__foo">
...
</div>
...
</div>
.bar:hover .bar__foo {
// color style
}
I want to confirm, is this a good way to handle the issue? Are there other ways in OOCSS as well?
The big concern here isn't that your chaining classes together, it's that your classes are location independent. Nesting is going to happen. Approaches like OOCSS are great because they help to you know when things like nesting and class-naming is going awry.
Mark Otto released a Code Guide last week and here are some relevant points:
Keep selectors short and strive to limit the number of elements in each selector to three.
Scope classes to the closest parent only when necessary (e.g., when not using prefixed classes).
He also provides these examples:
/* Bad example */
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }
/* Good example */
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }
In short: Aim to scope a class to it's parent. Don't go further than 3 selectors.
You're fine going with:
.bar:hover .foo { ... }
Further Reading
Stop The Cascade
Scope CSS Classes with Prefixes

Combine Two Classes in CSS?

I have tried to combine to classes in CSS, but I end up failing. I used this code:
.container{
.ningbar
}
What I would like to do is combine the items in the ningbar layer with the items in the container layer. Thanks, Phineas.
This would do the job:
.container { /*container rules*/ }
.ningbar { /*ningbar rules*/ }
.container,.ningbar { /*shared rules*/ }
.container, .ningbar { }
Use the same rules for both.
why do you want to combine two classes ? I would make two seperate classes and use them in my controls as below
CSS:
.class1{
/* All styles for class1*/
}
.class2{
/* All styles for class2*/
}
HTML:
<div class="class1 class2"></div>
This way you can add both classes to your controls/DOM elements keeping them seperate in your CSS.
In order to use another styles' for another class, there is LESS, if I can say.
In a nutshell, LESS will help you to maintain more easily, and comprehensible your styles' files. You will be able to add variables, to avoid repetitions of same colors' codes, for instance.
You can view more detail on LESS's website : http://lesscss.org/
But, it's probably a complicated way, to simply add properties from another class.
For Combining two class you can us
.Class1 .Class2 {
//All style for combination of these two classes
}

CSS element back to default style

Is there a fast way in CSS to remove all of the styles applied to an element? For example, say a tab menu of some sort:
<div class='outer'>
<div id='d1'></div>
<div id='d2'></div>
<div id='d3'></div>
<div id='d4'></div>
</div>
The CSS is applied...
.outer { foo:blee; bar:blah; bas-bloo:snork; /*...long long list...*/ }
Now, I want #d3 (for example) to return to default styling, but I don't want to explicitly unset all of the parent styles:
#d3 { remove-styles:all } /* <- [I made this up, obviously] */
Pipe dream or possibility?
In CSS3, yes. You could use the negation pseudo-class:
.outer:not(#d3) { foo:blee; etc etc }
Too bad CSS3 support is a little lacking at the moment with most browsers...
With CSS level less than 3, you're screwed. Sorry.
No. Not feasibly possible. Just override it.

Is this CSS reference correct and supported syntax: .slider.wide {}

I have a slider that's marked up like so:
<div class="slider wide">
//slider html in here
</div>
And another marked up like so:
<div class="slider narrow">
//slider html in here
</div>
Is it possible to reference each of these like this in my CSS file by in a way concatenating the class names:
.slider.wide { //css specific to the wide slider goes here }
.slider.narrow { //css specific to the wide slider goes here }
No, you make three classes .slider, where you put common slider css, and .narrow where you put narrow slider specific css, and .wide where you put wide slider specific css.
.slider { //css common among all sliders goes here }
.wide { //css specific to the wide slider goes here }
.narrow { //css specific to the narrow slider goes here }
Yes, .slider.narrow is valid. It's not exactly concatenating the class names, it's making two different class selectors and applying them to the same element. So .narrow.slider is also valid and will match the same elements.
The problem with using multiple class selectors against a single element is that is doesn't work in IE6. This browser will ignore all but the last class selector. So to support that browser you typically end up using something like class="slider wide-slider".

Resources