Limit CSS selector scope - html

This is a bit weird and maybe is wrong but that's what I want to do...
My HTML looks like this:
<div class="item is-active">
<div class="item-part"></div>
<div class="item small">
<div class="item-part">
</div>
</div>
</div>
And with CSS I want to do this:
.item.is-active .item-part {
outline:1px solid red;
}
The problem is that the inner .item-part will also be outlined which is not desirable. I want an .item-part to be outlined only if its closest .item is .is-active.
I'd rather not use JS for this nor a direct-sibling selector since the html may differ.
I also don't want to override the rule like this:
.item:not(.is-active) .item-part {
outline:none;
}
Here is a fiddle with a live example
Thank you.

How about (Assuming only one element has the is-active class):
.item.is-active .item-part {
outline:1px solid red; /* active item part style */
}
.item.is-active .item .item-part {/* e.g. child of iten that is not active*/
outline: none; /* disable active item part style */
}
If you can't modify the class names, won't use javascript, and the direct descendant solution doesn't work (e.g. because there may be wrapper-div's sometimes); this is the only solution I can think of...

Just override the style for when your element doesn't have an is-active class:
.item.is-active .item-part {
outline:1px solid red;
}
.item.is-active .item .item-part,
.item .item-part {
outline:none;
}
The .item.is-active .item-part has higher specificty than the .item .item-part selector, so this will always be applied to the .item-part descendants.
JSFiddle demo.

Related

CSS to class + anyclass

I need to add different styles to an element when it has one specific class and other styles when it has that specific class plus another (not specific)
This is because this second class varies with the page
So far I've tried:
.page {display: none;}
.page[class=""] {display: block;}
or
.page {display: none;}
.page.* {display: block;}
Use a class selector to require that it has the class you want.
Use an attribute selector to require an exact match for the specific class attribute value (i.e. exactly matches a string).
Note the limitation that attribute selectors are sensitive to whitespace.
Such:
div {
margin: 1ex;
padding: 1ex;
border: dotted 1px #aaa;
}
.foo {
/* Includes foo */
background: yellow;
}
[class="foo"] {
/* Has *only* foo */
background: red;
}
<div>No class attribute</div>
<div class="">No classes</div>
<div class="foo">Foo</div>
<div class=" foo ">Foo + whitespace</div>
<div class="foo bar">Foo Bar</div>
<div class="foo baz">Foo Baz</div>
Note that class and attribute selectors have equal specificity so order matters.
You can use .page (for elements that have a class page) and [class="page"] (for elements that have only class page), but the order of the styles matter:
.page {
color: blue;
}
[class="page"] {
color: red;
}
/* order matters */
<h1 class="page">PAGE</h1>
<h1 class="page larry">PAGE, LARRY</h1>
To see why the order matters, check this:
[class="page"] {
color: red;
}
.page {
color: blue;
}
<h1 class="page">PAGE</h1>
<h1 class="page larry">PAGE, LARRY</h1>
.page overrides [class="page"].
.page {display: none;}
.page + * {display: block;}

CSS attribute selector begin with

[class*="grid-"]{
border: 2px solid green;
}
[class^="grid-"]{
border: 2px solid red;
}
<div class="row">
<div class="grid-sm-1-3">one</div>
<div class="grid-sm-1-3">two</div>
<div class="other class grid-sm-1-3">three</div>
</div>
<div class="layout-grid-edit">do not match at all</div>
The issue is, if the element has multiple classes then the class^="grid-=" doesn't seem to work, and I can't rely on class*="grid-" because it also matches something like layout-grid-edit which is not desired.
#3zzy - Give this attribute selector a try below. This type of selector will be effective in targeting a class attribute beginning with the whole word grid, immediately followed by a hyphen:
[class|="grid"] { border: 2px solid green; }
See if this does the trick, and let me know.
Replaced:
[class*="grid-"]{
}
With:
[class^="grid-"],
[class*=" grid-"]{
}

meaning and role of [class*=] css class selector

Asking here since I can't pass a proper search query with that.
Here's a code sample:
[class*="button_type"].state_2,
[class*="button_type"]:not(.state_2):hover{
background-color:#fff;
}
Furthermore what would be the use of the :not suffix?
I cannot understand why it isn't just:
.button_type.state_2,
.button_type:hover { etc..}
[class*="button_type"] is CSS class Selector (equivalent to CSS attribute selector) means that will select all elements whose class contains at least one substring "button_type".
take a look at this example:
[class*="button_type"] {
background: red;
width: 50px;
height: 50px;
display: inline-block
}
<div class="button_type"></div>
<span class="one_button_type"></span>
<article class="button_type_final"></article>
Regarding the :not() that means it will select everything but that selector which is inside the :not()
Take a look at this example:
[class*="button_type"] {
background: red;
width: 50px;
height: 50px;
display: inline-block
}
[class*="button_type"]:not(.state_2) {
border: black solid
}
<div class="button_type state_1"></div>
<span class="one_button_type state_2"></span>
<article class="button_type_final state_3"></article>

CSS is there something like a "class subclass"?

I have 20 inputs in a page that are styled as buttons using the class property (that is, in the css I define borders, padding, width, etc).
But I want each one to have a different background color. In my current CSS I have 20 classes (one for each input) which are copies of all the style properties except for background-color.
It is working OK like this, but I feel somewhat uncomfortable repeting code. In there a very simple way to define most of the properties for all inputs (borders, padding, width...) and then specify the background-color, one for each input?
HTML
<input type="text" class="btn red" value="Red">
<input type="text" class="btn green" value="green">
<input type="text" class="btn blue" value="blue">
<input type="text" class="btn black" value="black">
<input type="text" class="btn orange" value="orange">
CSS
.btn{
border:1px solid grey;
width:50px;
height:10px;
padding:10px;
margin: 10px;
}
.red{
background-color:red;
}
.green{
background-color:green;
}
.blue{
background-color:blue;
}
.black{
background-color:black;
color:white;
}
.orange{
background-color:orange;
}
Here is the fiddle
You can use multiple classes on elements and use a common class on the elements for the shared styles and then a different class (or id) for the custom styles specific to that element.
e.g.
HTML
<input type="text" class="input-class red" />
<input type="text" class="input-class green" />
CSS
.input-class {
margin: 0;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
You could use a different selector to target all text inputs rather than having a common class aswell:
input[type="text"] {
margin: 0;
}
As well as the above, you can create more specific selectors like:
.input-class.red {
background-color: red;
}
.input-class.green {
background-color: green;
}
input[type="text"].red {
background-color: red;
}
input[type="text"].input-class.red {
background-color: red;
}
Which will only target elements that match those selectors, situations where this might be useful is when you might have a class with the same name elsewhere that you don't want to be affected.
For example you might have already:
.red {
color: red
}
So you don't want an input with red text on a red background so you can chain the class selectors together to be more specific.
Like your "subclass":
.class {
/* for <elem class="class"> only */
}
.class.subclass {
/* for <elem class="class subclass"> only */
}
Is there a very simple way to define most of the properties for all
inputs (borders, padding, width...) and then specify the
background-color, one for each input?
Firstly, define the styling for all inputs, e.g. (or use a shared class etc):
input{
border:...
padding:...
}
Then, if the inputs are all children of the same top level parent, you can isolate specific ones using the :nth-of-type selector:
input:nth-of-type(1){
background-color:red;
}
input:nth-of-type(2){
background-color:blue;
}
Alternatively, provide each with a relevant class designation
There is not in native CSS, but you have other ways of doing this at your disposal:
You can define a common class that holds all of the style that are common across the inputs:
.my-inputs {
border 1px solid #ccc;
padding: 15px;
}
and then you can modify that as needed
.my-inputs.city {
width: 100px;
}
.my-inputs.state {
width: 50px;
}
So that in your markup, you can do things like this:
<input type="text" class="my-inputs state">
Another way you can do this is to use a CSS preprocessor which does afford you the ability to do class inheritance. Take a look at the documentation for LESS and SASS:
http://lesscss.org/
http://sass-lang.com/

Separators between elements without hacks

One thing I often want to do when laying out a website is to have some elements next to each other, with separators between them. For instance, if I have three elements, I'd want two separators between them, and nothing at either end.
I achieve this in various ways. For vertical stacking of elements, I sometimes use <hr />. Horizontally, I might do something like:
<div>
<span class="notend">things</span>
<span class="notend">stuff</span>
<span>items</span>
</div>
.notend {
border-right: solid black 1px;
}
Is there a more semantic way of doing this? I want to have separators between elements without putting styling elements into the HTML part, or using non-semantic classes. I don't mind of this requires hacky CSS, I just want to get stuff to do with styling away from the HTML files.
Use this:
#menu span + span {
border-left: solid black 1px;
}
http://jsfiddle.net/thirtydot/QxZ6D/
That will apply border-left to all except the first span.
The adjacent sibling selector (+) is supported in all modern browsers except IE6.
Another way to do it is this, which is sometimes nicer because you can keep all the declarations for the "menu buttons" in one block:
http://jsfiddle.net/thirtydot/QxZ6D/1/
#menu span {
border-left: solid black 1px;
/*
a: bunch;
of: stuff;
*/
}
#menu span:first-child {
border-left: 0
}
This has exactly the same level of browser support as the first solution.
Note that if you like this solution, it's better to use :first-child rather than :last-child, because :first-child (from CSS2) is supported in IE7/8 and :last-child (only introduced in CSS3!) isn't.
you can do like this also:
span {position:relative; margin-left:5px}
span:after {
content:"|";
position:absolute;
left:-5px;
}
span:first-child:after {
content:"";
}
In this method you can also use others separators like / , \ , .
http://jsfiddle.net/sandeep/UNnxE/
how about something like this in your example:
<div>
<span>things</span>
<span>stuff</span>
<span>items</span>
</div>
div span{
border-left: solid black 1px;
}
div span:last-child{
border:none;
}
no need for additional classes.
Well for a start, you can simplify it to this:
<div>
<span>things</span>
<span>stuff</span>
<span class="end">items</span>
</div>
span {
border-right: solid black 1px;
}
span.end {
border-right: none;
}
If you're willing to drop some support in older browsers, you can reduce that to this, using the :last-child pseudo-class:
<div>
<span>things</span>
<span>stuff</span>
<span>items</span>
</div>
span {
border-right: solid black 1px;
}
span:last-child {
border-right: none;
}
I often want to have a series of items with semi-colons between them.
Here's what I do for this:
.semi-list span:not(:last-of-type)::after {
content: "; ";
}
<div class="semi-list">
<span>Item One</span>
<span>Item Two</span>
<span>Item Three</span>
</div>
It's a pretty flexible solution.
Ref:
https://www.w3schools.com/cssref/sel_not.asp
https://www.w3schools.com/csSref/sel_last-of-type.asp
Something like this?
CSS:
#note_list span {
display:inline-block;
padding:0 10px;
}
.notend {
border-right:1px solid #000000;
}
HTML:
<div id="note_list">
<span class="notend">things</span>
<span class="notend">stuff</span>
<span>items</span>
</div>