I have example (js-fiddle)
I want hide all tbody elements, that doesn't contains elements tr elements without class "day_label" and "hide"
In this exmaple i have stats for day, and i need to hide all day if there is no any record for day.
What you want is basically a CSS parent selector (tr.hide < tbody { display: none; }), this doesn't exist yet. (soon!) However, this can be done quite easily with a library like jQuery:
$("tbody").each(function() {
if ($(this).children("tr:not(.hide):not(.day_label)").length) { //Not 0
$(this).addClass("show");
}
});
CSS:
tbody { display: none; }
tbody.show { display: block; }
Demo: http://jsfiddle.net/SO_AMK/RqBCY/
To effectively select a parent based on it's children - what you are asking - is not possible with CSS (at this particular frozen moment in time).
You have two three ;) options:
When generating your HTML (either with a server side language or in JS) generate your parents with classes that describe the state of the children. This way you can target the parent directly.
Use JavaScript to target your parent and then calculate whether or not it has the right kind of children. If it does, then apply a className that adds the styles you require.
For other situations you can also do as Abe Petrillo states - which is to inverse your logic and only enable when a particular selector is found. However I believe this wont work for what you are trying to do as it involves more complcated 'conditional logic' than can be implemented.
Not sure what you mean, but you could hide all rows, and then show the rows that are relevant:
tbody tr { display:none; }
tbody tr.day_label { display: block; }
Related
By “wheel” I mean the nested selector path.
I’ve converted a somewhat large CSS file to LESS for the most part, nesting rules in DOM order. However, some of my styles are being overridden. Basically, all of the “plain” styles have been nested making their output CSS rules extremely specific (which I want). What’s not so specific are the rules where the parent elements have classes attached. Example:
Regular nested rules:
.grandparent {
some: style;
.parent {
other: style;
.child {
you: get;
.grandchild {
the: picture;
}
}
}
}
So, the issue I’m having is adding styles to the grandchild if the grandparent has a specific class attached. Something like:
.grandparent.visiting .grandchild {
visibility: hidden;
}
Is there a way to neatly add .visiting to the big hierarchy I’ve already built? Or do I have to redo the entire nesting order for all the child element selectors affected by .grandparent.visiting?
Not sure if this a noob thing. I just started with LESS a couple weekends ago. But I can’t seem to find any solutions using :not and the & selector (as superb as it is) doesn’t seem to help here either.
You can reference the current selector using the & symbol, then write selectors after it as it was in one line.
.grandparent {
some: style;
&.visiting {
.grandchild{
visibility: hidden;
}
}
}
Let's say I have a styled checkbox (think material design, where there is a bit going on to achieve the desired checkbox style). Which block is responsible for modifying a parent-dependent child block?
Example Component - Checkbox
So I have the following:
<div class="Checkbox">
<label class="Checkbox__label">
<input class="Checkbox__input" type="checkbox" checked=true />
<span class="Checkbox__icon glyphicon glyphicon-ok"></span>
<span class="Checkbox__text">{label}</span>
</label>
</div>
I style up each element within the block for the base checkbox. Within the context of the application, the checkbox block can live in many other blocks (with their own BEM structures).
Example of other blocks
The checkbox with have slightly difference appearance when say within the "Compact Panel":
<div class="Panel Panel--compact">
<p>Disclaimer.. [text]</p>
<Checkbox label="I Agree" />
</div>
Option One - Parent "knows" about child
So.. should the Compact Panel be "aware" of the various children blocks, and style them, so:
// Checkbox.scss
.Checkbox {
margin: 15px;
// .. other
}
// Panel.scss
.Panel {
&.Panel--compact {
margin: 0;
padding: 2px;
}
&.Panel--compact .Checkbox {
margin: 0;
padding: 1px;
}
}
Option Two - Child "knows" about parent
Or, the panel has zero awareness, and the checkbox checks for parent scope.
// Checkbox.scss
.Checkbox {
margin: 15px;
padding: 15px;
// .. other
}
.Panel.Panel--compact .Checkbox {
margin: 0;
padding: 1px;
}
// Panel.scss
.Panel {
&.Panel--compact {
margin: 0;
padding: 2px;
}
}
Option Three - ?
Maybe there are other options.
Usually with BEM if they look different, they are different.
Usually.
There are a number of different choices for handling context and state with BEM. Each has different pros and cons, so which you use will depend heavily on your use case.
The first option I'll mention is to use descendant selectors. You've already identified this choice, and are running into the usual problem of "where does the code belong?"
For the following examples, I'm going to rely on LESS syntax, this is only to make it easier for me to demonstrate relationships in the code.
Descendant Selector
If you're going to use a descendant selector, I recommend that the code be grouped with the child block.
widget.less
.widget {
&__container {
...
}
...
}
checkbox.less
.checkbox {
&__label {
...
}
...
// using inversion to override checkbox styles in a widget
// this will render to `.widget .checkbox` instead of
// `.checkbox .widget` due to the `&` placement
.widget & {
}
}
The reason I recommend associating the styles with the inner block is because the styles will affect the checkbox, and the cascade order will be important.
If the styles were associated with the parent, reordering the parent styles relative to the child styles could adversely affect how the styles render.
Consider this inclusion order:
site.less
#import 'widget';
#import 'checkbox';
If the styles were part of the widget, they could be overridden by a selector of equal specificity in checkbox.less.
Modifiers
I recommend using modifiers for state. I don't generally consider position or context to be "state", so modifiers may not be appropriate. Additionally, multiple modifiers on the same element can be difficult to reason about and therefor difficult to style.
Assuming you're not using a modifier on the checkbox block, then it may be simpler to add the modifier for the case where it's used in a panel.
.checkbox {
&__label {
...defaults...
}
...defaults...
&--alt {
&__label {
...overrides...
}
...overrides...
}
}
Of course, this requires that the markup be updated for the particular case where it's used in a panel, but then it also opens you up to using the checkbox with the same styles elsewhere.
Different Selector
I'm going to reiterate my first point: If they look different they are different.
This doesn't mean you have to start from scratch on the checkbox. BEM allows for object oriented styles. Come up with a new name, and extend* the checkbox:
checkbox.less
.checkbox {
&__label {
...
}
...
}
checkbox-2.less
#import (reference) 'checkbox';
.checkbox-2 {
.checkbox;
&__label {
...overrides...
}
...overrides...
}
* in LESS I'm using a mixin for this as it's generally better suited toward extending and overriding styles than using the :extend feature of the language. Feel free to use the :extend feature, just be aware that selector order will matter.
Refactor the Need Away
Sometimes I run into cases where I want to use a descendant selector or modifier because I need to bump a block for positioning purposes in a container.
In these cases, I often find that the container itself is what should be changed. I can usually tell that it's the container when I need to update the child to have different:
margins
padding
position
top, right, bottom, left
width
height
flex
Refactoring comes with other challenges, however I often end up using container divs to normalize the insertion region for blocks that contain other blocks; YMMV.
tl;dr: Which Should I Pick?
Can you (reasonably) update the markup?
YES: If you can easily update the markup to use different classes, I'd recommend extending your checkbox block as a new block. Naming things is hard though, so be sure to document which one is which somewhere.
NO: If you can't easily update the classes, using modifiers wouldn't be a great choice either. I'd recommend skipping that one, and falling back to the good ol' descendant selector. In BEM you really want to avoid descendant selectors, but sometimes they're the right tool for the job.
According to this documentation, the use of nested selectors should be avoided in BEM, but "is appropriate for changing elements depending on the state of a block or its assigned theme". This means that you can use a block's modifier to style its elements, but I couldn't find any mention of using a block's modifier to style its child blocks.
I think the best approach would be to add modifiers to both .Pannel and .Checkbox blocks, like: .Panel--compact and .Checkbox--context-compact. This way you won't create a dependency between them, which is a BEM principle.
If somehow you can't add a modifier to .Checkbox depending on it's context, I think the closest option would be the second one, where the child behaves differently depending on the state of its parent.
This is the "right" way:
I'm quite surprised why the accepted answer doesn't mention BEM "mixes".
In these scenarios, that is, when a block should change style when used within another block, the official BEM documentation recommends using a block AND an element class on the same DOM node.
So, in your case, this would be the markup:
<div class="Panel Panel--compact">
<p>Disclaimer.. [text]</p>
<div class="Checkbox Panel__checkbox" /> <!-- Here is the change -->
</div>
And this would be the CSS/SCSS:
// Checkbox.scss
.Checkbox {
margin: 15px;
padding: 15px;
// .. other
}
// Panel.scss
.Panel {
&__checkbox {
margin: 0;
padding: 2px;
}
}
It's really that easy and simple. The other answers are overcomplicating this unnecessarily, and I don't know why, the BEM documentation has a clear answer to this question. You can also find many articles online that explain the very same technique I just described.
I recently started a react project and I would like to share my experience on styling react components.
Cascading styles within react components are really confusing. So first thing is try to write class per element. If you want you can wrap using a main class which defines the component.
.panel {
.checkbox {
}
}
I use css-modules. This is super awesome. This tool can create unique classes so you don't need to worry about duplicating same name in other components. You can learn more from their git page and there are many articles online.
If you are using sass and need to use variables you can define a separate sass file in a different folder (let's say ../assets/variables.scss), in your component scss file you can import it and use all variables. Same goes to mixins and functions.
In your case don't worry about child and parent relationship, write single classes for all elements you need to style. Sometime you may need to target children using parent.
A good read
basically just want to know if the attached image shows a valid CSS usage? I'm using a lot of nested divs lately and this is how I'm targeting them in my CSS. It works really well but I'm just curious if it's a good way of doing it? Or is there an easier / more efficient way?
Thanks!
link to the image
First of all: yor way is totally ok and the efficiency depends on the whole page. Maybe it can get more efficient with those ideas:
If your div-classes or ids are unique
You can also write just the class - you dont have to write the whole path then. Instead of
#content > .inner > .content > div { }
it is possible to write for example
.content > div { }
Helpful when you are using nested divs
When using nested divs you very often have to type a lot of code multiple times:
#content > .inner > .content { }
#content > .inner > .content > div {}
#content > .inner > .footer {}
#content > .inner > .footer > div {}
There are very helpful scripts called LESS and SASS (both of them work pretty much the same). They allow you to write everything just one time like
#content {
.inner {
.content {
// some stuff
div {
// some stuff
}
}
.footer {
//some stuff
div {
// some stuff
}
}
}
}
The direct child selector (ie. > ) is fine, but personally I don't like it because it makes it difficult to move and re-use styles. For example if I want to use .content somewhere other than #container I'm going to have to change a whole heap of CSS. Ideally you should be able to re-use blocks of markup without having to change CSS.
The direct child selector is best used to limit the depth to which a style is applied. For example it would be appropriate to use .content > p if you want the style to apply only to direct children so you can have another style for deeper children. If that's not the case then you might as well just use well named class and ID selectors.
I want to exclude last and second last child of th to apply some css property.Individually it come be done like
.List thead tr th:not(:last-child){
//Some Css properties
}
and same for second last child.Can it be combined using not operator in one css selector?
CSS3 brings us the :nth-last-child() selector. To combine multiple :not items just add them to the end.
JSFiddle
li:not(:last-child):not(:nth-last-child(2)) {
color:red;
}
According to caniuse.com this method may be only fully supported from IE9. I say may be because caniuse isn't specific enough. Personally, I don't go out of my way to support < IE9 anymore unless it's a requirement.
.List thead tr th:nth-last-of-type(1) ,.List thead tr th:nth-last-of-type(2) {
/*Some Code*/
}
Try This
I need a css3 selector to target an element when the :target equals the id of the element (easy) or when the :target is empty (impossible?). It’s hard to explain, so let me give you a simple example.
div {
background: blue;
}
div:target, div:no-target {
background: red;
}
But of course the :no-target pseudo class doesn’t exist ;). Is there a way around this without using Javascript? Thanks in advance!
Sigh. I feel like I'm resurrecting a dead topic, but it needs a real answer.
It's possible to do this with CSS alone, just by using :last-child and a general sibling combinator, in the form of :target ~ :last-child:
.pages > .page:target ~ .page:last-child,
.pages > .page {
display: none;
}
/* :last-child works, but .page:last-child will not */
.pages > :last-child,
.pages > .page:target {
display: block;
}
The rules applies in the following steps:
hide all pages
show both targeted page and the last page
if a page is targeted, hide the last page (.page:target ~ .page:last-child)
(live example)
Edit: Apparently this is very similar to the accepted answer in an older, previously mentioned, related post.
There is a great answer for this over at default-target-with-css
It revolves around this trick that seems to have problems in iOS. It's been fixed in Safari, so maybe it'll be in iOS 5?
All I can think of is that you have some javascript that checks to see if the hash is empty. If so, it adds a class to the body tag called "noHash". Then, you can use the fact that there is the noHash class available in your CSS rules.
if (window.location.hash.length <= 1) {
document.body.className += " noHash";
}
Then, your CSS could be like this:
div {
background: blue;
}
div:target, body.noHash div {
background: red;
}
If there's any circumstance where a user might add a hash value after the fact, then you may have to watch for that to make sure the noHash class gets removed appropriately.
Note: you don't have to add the class name to the body tag. You can add it to any parent object that covers all the objects you wish to affect.
Why don't you use div:not(:target) or div:target:empty?