Forum Moderators: not2easy

Message Too Old, No Replies

Class Versus ID Precedence For DIVs

         

Planet13

4:41 am on Nov 12, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



When styling a DIV with both an ID and a class, I am a bit confused as to when to leave off the class.

For example: I want several similar divs to have a top border, except for the first div.

<div id="first_one" class="has_top_border">
This is the first div. It should NOT have a border
</div>

.has_top_border {
border-top: 1px solid #999999;
}

Now I know that the DIV above SHOULD have a border. But if I try something like this:

#first_one .has_top_border {
border-top: hidden;
}

It still has a border.

The only way for me to hide the top border is to leave off the class:

#first_one {
border-top: hidden;
}

So why does

#first_one {

work while the

#first_one .has_top_border {

doesn't work?

not2easy

5:17 am on Nov 12, 2014 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



#first_one .has_top_border
will have a border because the class has a border.
#first_one
is an id, not a class. You can only use the #id once on a page. Classes can be used again and again. So if they all have a border except one, use the #id to set the properties for the one that is different from the rest - or use a different class.

You can use
:hidden;
as a variable for the display property of an element, but not a property. It doesn't work.

Planet13

5:50 am on Nov 12, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@ not2easy:

Thanks for the reply.

Let me start with your second statement first:

You can use :hidden; as a variable for the display property of an element, but not a property. It doesn't work.

Should I be using top-border: none; instead of top-border:hidden; ?

~~~~~

Also, what is the best way to use classes / ids then if there are 10 divs that have SEVERAL properties that are similar EXCEPT for one div where there is a single property that is different?

Are you saying that I have to give the tenth div a different class entirely if I want to change ONE of the properties?

So if I have 10 nearly identical DIVs, the only difference being 9 of them have a blue background and one has a red background, I have to write out ALL the properties for both of them?

<div class="blue">
I have 9 of these
</div>
<div class="red">
I have one of these
</div>

.blue {
padding: 5px auto 10px;
margin: 5px 8px;
color: #999;
max-width:250px
background-color:blue;
}

.red {
padding: 5px auto 10px;
margin: 5px 8px;
color: #999;
max-width:250px
background-color:red;
}

~~~~~

Or do I write it out like this:

<div class="my_div blue">
I have 9 of these in blue
</div>
<div class="my_div red">
I have one of these in red
</div>

.my_div {
padding: 5px auto 10px;
margin: 5px 8px;
color: #999;
max-width:250px
}

.blue {
background-color:blue;
}

.red {
background-color:red;
}

Or do I have to write out the above .blue and .red classes as:

.my_div .blue {
background-color:blue;
}

and

.my_div .red {
background-color:red;
}

not2easy

6:19 am on Nov 12, 2014 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



For tasks like this, there is always more than one way to do it and it depends on what is before it, what properties are being inherited as to what needs separate classes. If you have a container for the main body of your page, for example and it is called #page.div and it surrounds all the content that is in that part of the page then you can set margins color and width there. All <div> elements inside that div will inherit the properties. You could have a class div.blue and a class for div.red within that container where you only need to specify the different background color or border. If 2 <div>s share a background color but not a border property, that's two classes.

What you want to do is to determine how many different appearances you need for the content you are styling and apply broadly the properties shared by all the elements and narrowly the properties applied "only this time" or "only twice". It needs to be spelled out for each different property you want to apply.

lucy24

9:48 am on Nov 12, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Simplest approach: don't use ids for styling at all. You don't need them.

Fotiman

3:20 pm on Nov 12, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




Now I know that the DIV above SHOULD have a border. But if I try something like this:

#first_one .has_top_border {
border-top: hidden;
}

It still has a border.


That's because the selector you've written means "All class 'has_top_border' that are CHILDREN of the element with id 'first_one'". But in your markup, the .has_top_border is not a child of #first_one, it's the same element. What you would need instead would be this:

#first_one.has_top_border {
border-top: hidden;
}

Note, there is no space between the selector #first_one and .has_top_border. That means find the element that has and ID of #first_one AND a class name of has_top_border.

The reason specifying only #first_one works is because you're targeting the correct element. The way you have the class, you're targeting a CHILD of that element, which is not what you really want.

@not2easy

You can use :hidden; as a variable for the display property of an element, but not a property. It doesn't work.

That's incorrect. border-top is shorthand that sets border-top-color, border-top-style, and border-top-width. hidden is a valid value for border-top-width, so a rule like this is perfectly correct:
border-top: hidden; /* means border-top-width: hidden */

@Planet13

Are you saying that I have to give the tenth div a different class entirely if I want to change ONE of the properties?

No, you don't necessarily have to do that. One option is to use an ID which will have a higher specificity than the class. In general, though, (as lucy24 pointed out), you should probably try to avoid using IDs for styling.
A better option for your example may be to use the :first-child pseudo class. For example:

.has_top_border {
border-top: 1px solid #999999;
}
.has_top_border:first-child {
border-top: hidden;
}


<div class="has_top_border">
This is the first div. It should NOT have a top border
</div>
<div class="has_top_border">
This has a top border
</div>
<div class="has_top_border">
This has a top border
</div>


Side note: class names like "has_top_border" are not good. Use class names that are a little more semantic and represent the "content" as opposed to describing some visual property.

Planet13

3:56 pm on Nov 12, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@ Lucy24:

"Simplest approach: don't use ids for styling at all. You don't need them."


What? Why Not?

A lot of the wordpress templates I see have IDs assigned to DIVs instead of classes in the template.

@ Fotiman:

"That's because the selector you've written means "All class 'has_top_border' that are CHILDREN of the element with id 'first_one'". But in your markup, the .has_top_border is not a child of #first_one, it's the same element."


Fotiman: You are (definitely) a genius and (quite possibly) psychic, because I was JUST ABOUT TO start a thread asking, "What is the difference between "#some_id .some_class and" "#some_id.some_class"

Thanks in advance for answering that so clearly BEFORE I had a chance to ask!

Also, what are the winning lottery numbers?

(Can't hurt to ask.)

Fotiman

4:19 pm on Nov 12, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



4, 8, 15, 16, 23 and 42
;)

not2easy

4:31 pm on Nov 12, 2014 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



@Fotiman - Thank you for clearing that up. Do appreciate getting it right! No thanks for the Lottery numbers...

lucy24

8:55 pm on Nov 12, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I was JUST ABOUT TO start a thread asking, "What is the difference between "#some_id .some_class and" "#some_id.some_class"

I think it was one of your other recent threads where I explained the space. Go back and check. But your current question is a little different. When there's no space, and the elements on both sides are id and/or class names rather than element types, it means "An element that belongs to BOTH of these."

.onename .twoname
=
<something class = "onename">
{optional blahblah while the class stays open}
<something class = "twoname">

.onename.twoname
=
<something class = "onename twoname">

A single element can belong to more than one class, instead of or in addition to one id.

An id is a specific identifier used to point to one individual element. Could be for navigation; could be for use with a script. A class is for use with stylesheets. It has no other function.

When you've been using CSS for a while and start becoming comfortable with it, you may one day notice that class suchandsuch is always and exclusively applied to id thisandthat. That's the point where you can throw out the CSS for ".suchandsuch" and instead write the rule for "#thisandthat".

Fotiman

9:04 pm on Nov 12, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




A class is for use with stylesheets. It has no other function.

Oh, not true. A class can be VERY useful when combined with JavaScript as well. You can most definitely have classes that apply no presentation but are used by scripts to attach event handlers, or perform some other function. :)

Planet13

5:00 pm on Nov 13, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thank you both, Lucy24 and Fotiman, for the above.

Planet13

5:10 pm on Nov 13, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@ Lucy24:

When there's no space, and the elements on both sides are id and/or class names rather than element types, it means "An element that belongs to BOTH of these."


so the SPACE basically means, "has a parent / grandparent element at ANY level", right?

.bar {
color: red;
}

.foo .bar {
color: blue;
}



For the html:

<p class="bar"> This is red</p>

<div class="foo">
<p class="bar">This is blue</p>
<div>
<p class="bar">This GRANDchild of .foo is ALSO blue</p>
<div><p class="bar">This GREAT-grandchild of .foo is ALSO blue</p>
</div>
</div>
</div>


Please let me know if the above is wrong. Thanks.

lucy24

6:06 pm on Nov 13, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



A class can be VERY useful when combined with JavaScript as well. You can most definitely have classes that apply no presentation but are used by scripts to attach event handlers, or perform some other function.

... which I should remember, because I've done it myself. Fortunately I was arguing from the opposite direction: if you're concerned purely with styling, leave the id attribute alone for now.

has a parent / grandparent element at ANY level

If the word you're groping for is "descendant" then yes, you understand :) There is a special CSS symbol that means "child" and there are also selectors for first child (also, in newer browsers, last child, even-numbered child and assorted others). But let's get a firm grip on descendants first.

I hope you whipped up a quick HTML page to test the CSS you just quoted, because seeing things in action can be a big help. Here you goofed: a <p> paragraph is an element by itself; it can't have block-level descendants. Change it to <div class = "bar"> and then leave the div open until the end, and you'll see the difference. "descendant" (or "child") doesn't simply mean "after". It means "inside".

You might find it easiest to experiment using elements that have built-in descendants. For example
table.foo td {blahblah}
tbody.widget tr {blahblah}
tr.bar td {blahblah}

or similarly <ul> and <li>.

Planet13

9:01 pm on Nov 13, 2014 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thank you, Lucy.