Prevent a LESS Mixin being applied if it is within itself? - css

I have a LESS mixin applied to a number of different classes. Its possible for one element with the mixin to be within another element which also have the mixin. When this is the case I dont want the child element to have the styling applied.
http://codepen.io/anon/pen/NPBWXM
.style1() {
padding: 10px;
border: 1px solid red;
}
.elm1 {
.style1;
}
.elm2 {
.style1;
}
<div class="elm1">Element 1</div>
<div class="elm2">
Element 2
<div class="elm1">Element 1</div>
</div>

No, it appears this is not possible.

Related

css having a range after a class attribute

I have three class : product1, product2, product3. I can add css to all these class as follows:
.product1, .product2, .product3{
// add css here
}
But I am looking for more cleaner code to track 1 to 3 followed by 'product' and add css to these. My expectation can be Pseudocode Examples:
.product1to3{
// fun with css.
}
Is there any approach in css?
There is no such kind of css pseudo on what you wanted to achieve.
You can try to use SASS to achieve what you wanted.
and then use the #for Directive
SASS
#for $i from 1 through 3 {
.product#{$i} { width: 20px; }
}
CSS
.product1 {
width: 20px;
}
.product2 {
width: 20px;
}
.product3 {
width: 20px;
}
Also you can try to use LESS
Hope this helps
pure css implementation JSfiddle
So basically you need an "Attribute Begins With Selector" i.e select all classes which start with "product" and then you can use nth child attribute to select range
div[class^="product"]:nth-child(n+4):nth-child(-n+5) {
background: red;
}
Really good article on complex css and nth:child
/* This selects all the elements which have the class name starting with
"product"
*/
[class ^= "product"] {
//CSS
}
If you have an unknown / high number of ".product(x)", and for whatever reason don't want to use an extra class to target them, you can get away with an attribute selector that matches all elements that have a class containing "product".
[class*="product"]
div{
border:2px solid tan;
height:40px;
}
[class*="product"]{
background:steelblue;
}
<div class="product1"> product 1 </div>
<div class="product2"> product 2 </div>
<div class="not"> not a product</div>
<div class="product3"> product 3 </div>
<div class="product4"> product 4 </div>
It occupies just 1 line of compiled CSS, so it's minimal footprint, but be careful how you apply it.
Not an answer for the OP but for others that may find their way here remember that you can use multiple classes for each element.
html
<div class="product product1"></div>
<div class="product product2"></div>
<div class="product product3"></div>
css
/* shared styling */
.product {
display: flex;
background-color: gray;
border: 1px solid red;
}
/* individual styling */
.product1 {
color: black;
}
.product2 {
color: white;
}
.product3 {
color: blue;
}

Styling adjacent groups of like classes as a block via CSS? Obvious or impossible?

I have an interesting problem, consider this HTML:
<div class="foo">Hello</div>
<div class="foo">World</div>
<div class="bar">Hotel</div>
<div class="bar">Romeo</div>
<div class="bar">Foxtrot</div>
<div class="foo">Ford</div>
<div class="foo">Prefect</div>
This content is dynamically generated and I never know when the class is going to flip. Is there a pure CSS way of styling groups of elements of a class? For example, I want each adjacent group of class "foo" to be bold and have a specific margin while each adjacent group of class "bar" I want to be red in color.
**Hello**
**World**
Hotel
Romeo
Foxtrot
**Ford**
**Prefect**
Help me stackoverflow, you're my only hope!
How about:
.foo + .bar,
.bar + .foo{
margin-top:10px;
}
This will add 10px of margin every time a .bar div follows a .foo div, or vice versa.
.foo + .bar,
.bar + .foo {
margin-top: 10px;
border-top: solid 1px black;
}
<div class="foo">Hello</div>
<div class="foo">World</div>
<div class="bar">Hotel</div>
<div class="bar">Romeo</div>
<div class="bar">Foxtrot</div>
<div class="foo">Ford</div>
<div class="foo">Prefect</div>

What does a space preceding :nth-child(n) do?

While I was writing a bit of CSS, a situation that I have never encountered before using the :nth-child(n) appeared and I was doubt of what is actually happening.
When I use pseudo classes, I write them without a space between the selector, like so:
div#wrap:hover {
border-bottom: 2px solid orange;
}
/* OR */
div#wrap:nth-child(4) {
border-bottom: 2px solid orange;
}
But it didn't work the way I expected, so I tried inserting a space between the selector and the pseudo class. Surprisingly, it worked:
div#wrap :nth-child(4) {
border-bottom: 2px solid orange;
}
What is happening to make this work?
div#wrap :nth-child(4) {
border-bottom: 2px solid orange;
}
<div id="wrap">
<h1>Heading 1</h1>
<p>This is a test!</p>
<h2>Creating content</h2>
<p>The next paragraph uses the <strong>.html</strong> method to create a new element.</p>
</div>
You're misunderstanding the selector. It selects the element that is also the :nth-child(n) which also has the preceding element as a parent.
When there is no selector preceding, it defaults to *:nth-child(n)
Because you probably only want to apply this to direct descendants and not every element which is the fourth child of its parent and a descendant of the parent, I would use .element > *:nth-child(n) to only apply to direct descendants.
div#wrap > *:nth-child(4) {
border-bottom: 2px solid orange;
}
div#wrap > *:nth-child(4) {
border-bottom: 2px solid orange;
}
<div id="wrap">
<h1>Heading 1</h1>
<p>This is a test!</p>
<h2>Creating content</h2>
<p>The next paragraph uses the <strong>.html</strong> method to create a new element.</p>
</div>
If you wanted to be more specific and only select the fourth child if it is a <p> element, you can use .element > p:nth-child(n). This will select all <p> elements that are the fourth direct descendant of elements matching the div#wrap selector.
div#wrap > p:nth-child(4) {
border-bottom: 2px solid orange;
}
div#wrap > p:nth-child(4) {
border-bottom: 2px solid orange;
}
<div id="wrap">
<h1>Heading 1</h1>
<p>This is a test!</p>
<h2>Creating content</h2>
<p>The next paragraph uses the <strong>.html</strong> method to create a new element.</p>
</div>
If you want to select the second <p> element directly descending from each div#wrap, you can use .element > p:nth-of-type(n) like so:
div#wrap > p:nth-of-type(2) {
border-bottom: 2px solid orange;
}
div#wrap > p:nth-of-type(2) {
border-bottom: 2px solid orange;
}
<div id="wrap">
<h1>Heading 1</h1>
<p>This is a test!</p>
<h2>Creating content</h2>
<p>The next paragraph uses the <strong>.html</strong> method to create a new element.</p>
</div>
What does the space do?
Space before :nth-child(4) is equal to *:nth-child(4). * is a global CSS selector. So if any child element which is 4th in the list of elements of any parent, the CSS rules are applied to that element.
But using #wrap before the nth-child will limit the scope of the selection within the #wrap element.
Alternate Solution(Understanding how nth-child works):
You can also use: p:nth-child(4) which targets the paragraph element which is 4th with respect to the parent element which is #wrap.
:nth-child will select irrespective of whatever the element is, or what the sibling elements are. You will need to use :nth-of-type to differentiate.
* {
font-family: Helvetica;
}
p:nth-child(4) {
border-bottom: 2px solid orange;
}
p:nth-of-type(2) {
background: lightblue;
color: #fff;
}
<div id="wrap">
<h1>Heading 1</h1>
<p>This is a test!</p>
<h2>Creating content</h2>
<p>The next paragraph uses the <strong>.html</strong> method to create a new element.</p>
</div>
A space in a CSS selector means the next part is a descendant (not direct descendant) of what was previously selected.
tr td means a <td> inside a <tr>.
table td means a <td> inside a <table>.
In your case, the :nth-child() pseudo-class is applied after the <div> so it matches for the nth (4th...) child of that div. Had you removed the space, it would match a the 4th div with id "wrap" (which doesn't exist)

Should module child elements be nested in module modifiers?

When writing css using BEM if you need to make changes to a module element when it is in a sub-module do you nest the module-element in the sub-module or create a new class name for the module-element?
Creating a New Class
Creating a new class name(i.e. module--modifier__element) seems to be more in the spirit of BEM. It prevents unnecessary specificity. But it also adds a lot of extra work adding an extra class to each element within the module.
Nesting
Nesting the existing element class within the module modifier(i.e. module--modifier module__element {} will add some extra specificity but saves you a lot of work(at least for large modules) and makes the markup easier to maintain. For example if you needed to change the modifier of a module you would only have to change it one place in the markup rather than having to change it on every child element.
In addition to that if not all of the child elements change then you will have to refer to the css to figure out which child elements need a class added to them.
EXAMPLE CODE
.module {
display: block;
width: 90%;
height: 2rem;
margin: 2rem auto;
padding: 0.5em;
background: #fff;
border: 2px solid #333;
}
.module--modified1 {
background: #333;
border: none;
}
.module--modified2 {
background: #baa;
border: 3px solid #8f8;
}
.module__element {
color: #333;
text-align: center;
}
/* Option 1 */
/* In sass this would actually be nested within the module_modified1 block */
.module--modified1 .module__element {
color: #fff;
}
/* Option 2 */
.module--modified2__element {
color: #fff;
font-size: 1.3em;
}
<div class="module">
<div class="module__element">Module</div>
</div>
<div class="module module--modified1">
<div class="module__element">Module Modifier 1</div>
</div>
<div class="module module--modified2">
<div class="module__element module--modified2__element">Modulue Modifier 2</div>
</div>
Both options are valid. Reduce the specificity is a good practice, but make the code simple is also a good practice.
However, BEM blocks have to be context-free. If a block can be recursively included into itself, then cascades must be avoided. For example, a generic block fun-rounded-block could be recursively reused like this:
<div class="fun-rounded-block fun-rounded-block--blue-version">
<div class="fun-rounded-block__content">
<div class="some-block-here">
<div class="fun-rounded-block">
<p class="fun-rounded-block__content">element in the sub-block here</p>
</div>
</div>
</div>
</div>
In this example, you cannot use a cascade for styling elements because the selector .fun-rounded-block--blue-version .fun-rounded-block__content would interfere with the sub-block.

How to import a selector style into another selector style?

I know that we can import a css style into another css style. That's not the thing I'm going to talk about.
I want to create a css style that depend on other css style. In other word, I want to create my own cascading tree system. How can I do that?
For example, how I pictured it in my mind:
div.priceinfo { border: 1px solid gray; width: 200px; }
div.disabled { background-color: gray; color: 333333; }
div.shippinginfo { depend: div.pricebox; border-color: green; }
div.taxinfo { depend: div.pricebox; border-color: blue; }
so I can use it like this:
<div class="priceinfo"> ... </div>
<div class="shippinginfo"> ... </div>
<div class="taxinfo disabled"> ... </div>
but I do not want like this:
<div class="priceinfo shippinginfo"> ... </div>
<div class="priceinfo taxinfo disabled"> ... </div>
I know that the last way is possible, but I'm curious whether there's any way I can do something like the one I described earlier? Thanks for the help.
I think you have to see a LESS CSS for this. a LESS CSS provides a coding for CSS.
http://lesscss.org

Resources