selector for nth nested elements - css

I am working on a tree view of undeterminable nestability, but would like to define some nested rules for styling. For example, I want the first level item to have a particular border. Nested items immediately underneath to have a different border. I have a working example, but it is static and verbose. I know there has to be a better way using selectors, but I can't seem to make it work. Here is my current solution-
.item {
border-left-color: #somecolor1;
}
.item > .item {
border-left-color: #somecolor2;
}
.item > .item > .item {
border-left-color: #somecolor3;
}
.item > .item > .item > .item {
border-left-color: #somecolor4;
}
.item > .item > .item > .item > .item {
border-left-color: #somecolor5;
}
So this works, but obviously it is kind of verbose. Is there a better way?

In CSS the selector string is largely describing the nesting structure, and there does not currently exist any generational skipping selectors such that you might theoretically do something like .item:nth-grandchild(4) to replace your fifth example.
If reducing verbosity of your css is of high importance to you (lets say you have up 10 or even 100 levels of nesting you are switching on), then really you need to look into modifying the html itself in order to reduce the css needed. That can be done dynamically via server-side scripting (PHP, etc.), or client-side scripting (Javascript), or statically by you. Which way you choose will depend on a variety of factors.
The html modification can be in the form of more specific classes or direct style properties, but I recommend the former. Here are at least four ways css would be reduced:
#1 Multiple Classes, One Indicating Level
Sample HTML
<div class="item L-1">
<div class="item L-2">
<div class="item L-3">
</div>
</div>
</div>
Sample CSS
.item.L-1 {
border-left-color: #somecolor1;
}
.item.L-2 {
border-left-color: #somecolor2;
}
.item.L-3 {
border-left-color: #somecolor3;
}
#2 Multiple Classes, One Indicating Color
Sample HTML
<div class="item LBC-1">
<div class="item LBC-2">
<div class="item LBC-3">
</div>
</div>
</div>
Sample CSS
.item.LBC-1 {
border-left-color: #somecolor1;
}
.item.LBC-2 {
border-left-color: #somecolor2;
}
.item.LBC-3 {
border-left-color: #somecolor3;
}
#3 Single Class Name Indicating Level
Sample HTML
<div class="item-L1">
<div class="item-L2">
<div class="item-L3">
</div>
</div>
</div>
Sample CSS
[class *= "item-"] {
/* common css properties for the items goes here */
}
.item-L1 {
border-left-color: #somecolor1;
}
.item-L2 {
border-left-color: #somecolor2;
}
.item-L3 {
border-left-color: #somecolor3;
}
#4 Style Properties for Each Item
Sample HTML
<div class="item" style="border-left-color: #somecolor1">
<div class="item" style="border-left-color: #somecolor2">
<div class="item" style="border-left-color: #somecolor3">
</div>
</div>
</div>
Sample CSS
/* none to control color */
Discussion of "Best"
Often dynamic solutions end up producing html like that of #4, which ends up making the html very verbose, and I personally would not recommend it. However, those dynamic solutions do not need to do that, but could instead add class names like #1-3.
What is ultimately "best" depends a lot on what you are trying to achieve, how much control you have, and what other properties need changing as well. Personally, I would avoid #2 as well, because it begins to tie presentation too much to html by having a class name associated with the "left border color." To me, solution #1 or #3 would be best, as those are simply setting classes that help the css to know what "level" the .item is at, which then allows for specific targeting to that level for anything you may need it for.
Of course, if you were really dealing with 100 nested levels, then even for solutions #1-3, you might want to look into some css preprocessor to generate the 100 levels of code needed. But the css output would still be far less than the long selector strings needed using the current method you are doing.

Related

CSS Selector Within a Selector

Essentially what I am trying to do is have one element react as the hover state of a different element.
.page-template-page-services-new .imgBlock:hover { .page-template-page-services-new .ButtonService {color: #6395ce; background-color: #fff; } }
Not currently working - is this a thing? If not, how might I accomplish it. I know the selectors are correct, they work independently.
What I think you are referring to is that you've seen something akin to
.selector-one{
//style definitions
.selector-two{
//other style definitions
}
}
This comes from pre-processors such as SCSS (Sass) or LESS, I'll assume you can do a quick google on those.
For the other part of your question, yes, you can style an element differently if it's parent container or even a sibling is hovered.
Example
.container-hover:hover .red-on-hover{
background-color:red;
}
.sibling-hover:hover + .sibling-hover{
background-color:blue;
}
<div class="container-hover">
<h3>Other Text</h3>
<div class="red-on-hover">Background will turn red on hover</div>
</div>
<p class="sibling-hover"> When I am hovered, my sibling will be blue</p>
<p class="sibling-hover"> Blue? Blue</p>
For the sibling hover, please note that if you added more .sibling-hover elements that all but the first one would be able to turn blue if you hovered over it's immediately prior sibling.
It can work if they have a parent child relationship.
.page-template-page-services-new {
background: #ccc;
}
.page-template-page-services-new .imgBlock:hover .ButtonService {
color: #6395ce;
background-color: #fff;
}
<div class="page-template-page-services-new">
<div class="imgBlock">
<img src="http://placehold.it/100/100" alt="">
<div class="ButtonService">
<p>
This is a test
</p>
</div>
</div>
</div>

How can I make a same class name unique to different pages

I am using single CSS file for all my pages, but I come across with this problem. I have an almost identical (with minor differences) element on two different pages ( let's say home page and about page; This is my CSS codes for a specific element in the Home page, I want to use this for another page with minor differences. How do I name those two classes,
Do I need to use completely separate class names like .home.topcontainer { and .about.topcontainer { etc, or is there any robust way handling this issue?
What is the best way of naming CSS blocks for different pages, if I am using a single CSS file for my whole website to avoid me get confused over class names?
Thanks
CSS
.top_container {
position:relative;
top:3px;
height:144px;
z-index:1;
background-color: #143952;
width: 90%;
left:5%;
right:5%;
font-family: 'Scope One', serif;
overflow:hidden;
min-width:900px;
The best practice is to add some relevant class in body tag (as you can see in several CMS like magento etc.) and then use like this:
<body class="home">
<div class="top_container">
<!-- Do something -->
</div>
</body>
--or--
<body class="about">
<div class="top_container">
<!-- Do something -->
</div>
</body>
now you can use css like:
.home .top_container{}
.about .top_container{}
Let's assume this is your Home page
<div id="home">
<div class="top_container">
//stuff
</div>
</div>
And this is your about page:
<div id="about">
<div class="top_container top_container_about">
//stuff
</div>
</div>
Now, in your CSS file, add the style for the 'top_container' class like so:
.top_container {
//css styles common to the top_container element
}
And then write the style that's unique to the top_container in the about section:
.top_container_about {
//css style unique to the about section
}
This is one way which takes advantage of the 'Cascading' property of a 'Cascading Style Sheet'.
Commonly used practice here is to use a base class and a variation to that base class. That way we use the base css-class for both elements and change it a little by overwriting some values with the variant-class. You didn't specify how you want the top containter to change but here is an example:
.top_container {
background: #000;
color: #fff;
width: 200px;
height: 50px;
padding: 10px;
}
.top_container.top_container--narrow {
width: 100px;
}
<div class="top_container">
Default
</div>
<div class="top_container top_container--narrow">
Narrow
</div>
I add the page name to the body class, and make changes like that using CSS like
.style {
margin: 0;
}
.home .style {
margin: 10px;
}
From what I learned in coding scss, it is better to make your class name a general one. In css only you can make it like this:
CSS
.top-container{
width: 100%;
}
.top-container.about{
width:60%
}
.top-container.contact{
width:30%
}
HTML
home.html
<div class="top-container"></div>
about.html
<div class="top-container about"></div>
contact.html
<div class="top-container contact"></div>
The about class will override whatever style you have in top-container. So its easy to use, short and quite simple. You can use this in making your class name a more general one.
If there are same elements on both pages such as Header then you can use the same class name for them on both pages so that they will look exactly identical on both pages. And for making some changes to those elements you can use different CSS selectors. In the below given code, I have used class and id as selectors.
I HOPE THIS ANSWER MEETS YOUR REQUIRMENTS.
Homepage: header background color is blue.
<header class="top_container" id="home_header">
<!--YOUR WEBSITE HEADER-->
<h1>TITLE</h1>
</header>
<div>
<!--YOUR SITE CONTENT-->
</div>
About page: header background color is red
<header class="top_container" id="about_header">
<!--YOUR WEBSITE HEADER-->
<h1>TITLE</h1>
</header>
<div>
<!--YOUR SITE CONTENT-->
</div>
CSS file:
.top_container{
background-color: blue;
color: white;
}
#about_header{
background-color: red;
}
I would do like so. Cause you might have a .top-container on every page you need to set like a "default" style for .top-container. So CSS Cascading Style Sheet. Cascade from top and if an element needs to be a little different just set the differences in a more specific defined class. Something like so:
.top-container {
/* apply all styles for .top-container */
}
.home.top-container {
/* this .top-container will have all styles from .top-container defined above */
/* so only define all DIFFERENT things for .home.top-container here */
}
.about.top-container {
/* define all DIFFERENT things for .about.top-container here */
/* like before it will always have the .top-container styles */
}

CSS selector for odd- and even-level descendants? [duplicate]

I am working on a tree view of undeterminable nestability, but would like to define some nested rules for styling. For example, I want the first level item to have a particular border. Nested items immediately underneath to have a different border. I have a working example, but it is static and verbose. I know there has to be a better way using selectors, but I can't seem to make it work. Here is my current solution-
.item {
border-left-color: #somecolor1;
}
.item > .item {
border-left-color: #somecolor2;
}
.item > .item > .item {
border-left-color: #somecolor3;
}
.item > .item > .item > .item {
border-left-color: #somecolor4;
}
.item > .item > .item > .item > .item {
border-left-color: #somecolor5;
}
So this works, but obviously it is kind of verbose. Is there a better way?
In CSS the selector string is largely describing the nesting structure, and there does not currently exist any generational skipping selectors such that you might theoretically do something like .item:nth-grandchild(4) to replace your fifth example.
If reducing verbosity of your css is of high importance to you (lets say you have up 10 or even 100 levels of nesting you are switching on), then really you need to look into modifying the html itself in order to reduce the css needed. That can be done dynamically via server-side scripting (PHP, etc.), or client-side scripting (Javascript), or statically by you. Which way you choose will depend on a variety of factors.
The html modification can be in the form of more specific classes or direct style properties, but I recommend the former. Here are at least four ways css would be reduced:
#1 Multiple Classes, One Indicating Level
Sample HTML
<div class="item L-1">
<div class="item L-2">
<div class="item L-3">
</div>
</div>
</div>
Sample CSS
.item.L-1 {
border-left-color: #somecolor1;
}
.item.L-2 {
border-left-color: #somecolor2;
}
.item.L-3 {
border-left-color: #somecolor3;
}
#2 Multiple Classes, One Indicating Color
Sample HTML
<div class="item LBC-1">
<div class="item LBC-2">
<div class="item LBC-3">
</div>
</div>
</div>
Sample CSS
.item.LBC-1 {
border-left-color: #somecolor1;
}
.item.LBC-2 {
border-left-color: #somecolor2;
}
.item.LBC-3 {
border-left-color: #somecolor3;
}
#3 Single Class Name Indicating Level
Sample HTML
<div class="item-L1">
<div class="item-L2">
<div class="item-L3">
</div>
</div>
</div>
Sample CSS
[class *= "item-"] {
/* common css properties for the items goes here */
}
.item-L1 {
border-left-color: #somecolor1;
}
.item-L2 {
border-left-color: #somecolor2;
}
.item-L3 {
border-left-color: #somecolor3;
}
#4 Style Properties for Each Item
Sample HTML
<div class="item" style="border-left-color: #somecolor1">
<div class="item" style="border-left-color: #somecolor2">
<div class="item" style="border-left-color: #somecolor3">
</div>
</div>
</div>
Sample CSS
/* none to control color */
Discussion of "Best"
Often dynamic solutions end up producing html like that of #4, which ends up making the html very verbose, and I personally would not recommend it. However, those dynamic solutions do not need to do that, but could instead add class names like #1-3.
What is ultimately "best" depends a lot on what you are trying to achieve, how much control you have, and what other properties need changing as well. Personally, I would avoid #2 as well, because it begins to tie presentation too much to html by having a class name associated with the "left border color." To me, solution #1 or #3 would be best, as those are simply setting classes that help the css to know what "level" the .item is at, which then allows for specific targeting to that level for anything you may need it for.
Of course, if you were really dealing with 100 nested levels, then even for solutions #1-3, you might want to look into some css preprocessor to generate the 100 levels of code needed. But the css output would still be far less than the long selector strings needed using the current method you are doing.

How to apply different CSS styles to 2 elements with the same class name?

I created a website that has different navigation menus. In 2 menus, I use the same HTML class element.
I have a .css file that styles that class element in 1 menu. However, in another menu, I would like to style the elements differently.
Yes, I know I can rename the class name, but to be consistent with what I have right now in the structure of my markup, and also the fact that the class name is used to style multiple other elements, how would I be able to apply different styles to 2 different elements with the same class name?
Can this be done using some kind of if statement condition in CSS?
For example, in 1.html:
<div class="classname"> Some code </div>
In 2.html:
<div class="classname"> Some different code </div>
Since I just want to style this "one" element differently in 2.html, can I just add an id attribute along with the class attribute, and use both the id and class and somehow as the selector?
Once again, I would not like to remove the class name at all, if possible.
Thanks!
I'll just add that typically when there are multiple menus you might have them wrapped in a different structure. Take for instance:
<nav class='mainnav'><div class="classname one"> Some code </div></nav>
<div class='wrapper'><div class="classname"> Some different code </div></div>
You can easily target these:
.mainnav>.classone {}
.wrapper>.classone {}
Or if the parent html has a class:
<div class='ancestor1'><div><div class="classname one"> Some code </div></div></div>
<div class='ancestor2'><div><div class="classname one"> Some code </div></div></div>
.ancestor1 .classname {}
.ancestor2 .classname {}
Obviously this depends on where in the html they might be.
You can add another class name to each element.
<div class="classname one"> Some code </div>
<div class="classname two"> Some different code </div>
And then aplpy different rules to them:
.classname.one {
border: 1px solid #00f;
}
.classname.two {
border: 1px solid #f00;
}
Edit:
Updated Demo link: http://jsfiddle.net/8C76m/2/
If you must keep only one class for each element, you may try the nth-child or nth-of-type pseudo-class:
.classname:first-child {
font-size: 2em;
}
.classname:nth-of-type(2) {
color: #f00;
}
Ref:
http://www.w3schools.com/cssref/sel_firstchild.asp and http://www.w3schools.com/cssref/sel_nth-of-type.asp
Just give each one a different id
#firsthtml .classname {
}
#sechtml .classname {
}
Be sure to use the space, as #firsthtml.classname is something totally different.
<div class="classname" id="firsthtml"></div>
<div class="classname" id="sechtml"></div>
You could also use two different class names
<div class="classname secondclassname"></div>
Define secondclassname in your css with the additional css
.classname.secondclassname{
}
You can also do something like this:
<div class="classname"> Some code </div>
<div class="classname second"> Some different code </div>
And the CSS for the first .classname would be something like that:
.classname:not(.second) {}
For the second element it goes easily:
.classname.second {}
I know this is a poor way of doing it, the suggestions from previous answers are helpful, but try this maybe:
First menu:
<div class="classname"> Some code </div>
Second menu:
<div class="classname" style="margin-bottom:0;color:Black;width:100px;height:100px"> Some other code </div>

hover two objects affecting on one object

i have a problem of making two objects that when i hover on one of them, it will change one object. for example, i have object bar1, bar2, and bar3. i want to make when i hover on bar1 or bar3 will change the bar2.this is the css code:
.bar2{
left:0.5%;
right:0.5%;
}
.bar1:hover + .bar2{left:5%;}
.bar3:hover + .bar2{right:5%;}
and this is my html code:
<div style="position:absolute;">
<div class="bar1">
</div>
<div class="bar2">
</div>
<div class="bar3">
</div>
</div>
from that code i just can affect bar2 by hovering on bar1, but not with bar3.
Every body please help me. and thanks for helping.
What you need to do is something like this: live demo here (click).
<div class="bar1">Bar 1
</div>
<div class="bar3">Bar 3
</div>
<div class="bar2">Bar 2
</div>
css:
#one {
background: red;
}
#two {
background: white;
}
#three {
background: blue;
}
#one:hover ~ #two, #three:hover ~ #two {
background: black;
}
.bar3:hover + .bar2 or .bar3:hover ~ .bar2 is only going to select .bar2 if .bar2 is AFTER .bar3.
It might make more semantic sense for the elements to be in a different order, but in a lot of cases (such as yours here), the result is visually the same even with the order changed. If you can't change the order in order to select things this way, then you would have to resort to javascript to select adjacent elements that are previous.
There is talk of having a parent selector in css4. That would be nice :)

Resources