coson
coson

Reputation: 8659

Avoiding duplicate styles in CSS

I'm trying to teach myself CSS and have the following markup:

<style type="text/css">
#content { display: block; width: 250px; height: 50px; background-color: #330000; }

/* pink */
#one { height: 25px; width: 25px; background-color: #FFCCCC; float: left; margin: 10px; }
/* hot pink */
#two { height: 25px; width: 25px; background-color: #FF0099; float: left; margin: 10px; }
/* tan */
#three { height: 25px; width: 25px; background-color: #CC9900; float: left; margin: 10px; }
/* aqua blue */
#four { height: 25px; width: 25px; background-color: #33FFFF; float: left; margin: 10px; }
/* yellow */
#five { height: 25px; width: 25px; background-color: #FFFF00; float: right; margin: 10px; }

</style>
</head>
<body>

<div id="content">
    <div id="one"></div>
    <div id="two"></div>
    <div id="three"></div>
    <div id="four"></div>
    <div id="five"></div>
</div>

The page is working correctly, but I'm interested in removing the duplicate code within the CSS itself. I.e. have all height, width, float all in one defintion then override the background color for each of the #id values

When I tried:

#content { height: 25px; width: 25px; float: left; margin: 10px }

then put:

#one { background-color: #FFCCCC; }
#five { background-color: #FFFF00; float: right; }

that didn't work.

Basically I'm trying to remove the amount of duplicate markup.

What am I missing?

Upvotes: 6

Views: 8237

Answers (7)

Pekka
Pekka

Reputation: 449783

You could use classes. Define a base class that contains the common properties:

/* Generic class for all four elements */
div.button {  height: 25px; width: 25px; float: left; margin: 10px; }

and then define 1-4 (I'm using classes here as well, as it is the best practice in many cases, but you can carry on using IDs if you want to):

div.one { background-color: #FFCCCC; ... }
div.two { background-color: #FF0099; ... }

and then assign the base class and the specific class:

 <div id="one" class="button one"></div>

the "button one" part will let both classes' properties apply to the element.

Upvotes: 1

Walker
Walker

Reputation: 134651

You have two options, the first is to use the parent container (in this case the div #content) to set default attributes to each of it's nested divs, to do this you could use code like this:

#content div {
repeat-attributes-here;
}

This will set attributes for every div inside #content.

The second option is to use classes to define the common attributes. The benefit of this is you can still have other divs with different styling options (in case you add something new where you don't want the repeated functionality.

To do this you would do this:

#one {
unique-functionality-here
}

.layout-block {
repeat functionality here
}

Then define the div in the CSS like this:

<div id="one" class="layout-block"></div>

Hope that helps!

Upvotes: 0

Robert Koritnik
Robert Koritnik

Reputation: 105071

There are actually three alternative solutions to your problem

First solution

The first one is very close to what you've written yourself except that it should define CSS for any DIV underneath the one with the id="content":

#content div { height: 25px; width: 25px; float: left; margin: 10px }

Second solution

I should point out that this one is probably more common and gives more flexibility especially if you want subDIVs to not have common classes (in your case sizing). This one changes your markup a bit because you can define multiple CSS classes on a single HTML element:

<div>
    <div class="content one"></div>
    <div class="content two"></div>
    <div class="content three"></div>
    <div class="content four"></div>
    <div class="content five"></div>
</div>

This way your CSS classes change a bit. You have to replace # with a . (dot):

.content { height: 25px; width: 25px; float: left; margin: 10px }
.one { background-color: #FFCCCC; }
...
.five { background-color: #FFFF00; float: right; }

Third solution

This one is very similar to the second one, except that it keeps the IDs of sub DIVs:

<div>
    <div id="one" class="content"></div>
    <div id="two" class="content"></div>
    <div id="three" class="content"></div>
    <div id="four" class="content"></div>
    <div id="five" class="content"></div>
</div>

And CSS:

.content { height: 25px; width: 25px; float: left; margin: 10px }
#one { background-color: #FFCCCC; }
...
#five { background-color: #FFFF00; float: right; }

Upvotes: 0

dockeryZ
dockeryZ

Reputation: 3981

This is where you would make use of classes. IDs are great for when you have a particular element that is unique to the page. But classes, you can define a set of attributes (even set an attribute more important than another). Furthormore, an element can have more than one class where they can't IDs

So what I would do is this

#pink { background-color: #FFCCCC; }
#hotpink { background-color: #FF0099; }
#tan{ background-color: #CC9900; }
#aquablue { background-color: #33FFFF; }
#yellow { background-color: #FFFF00; }

.box {
  height: 25px;
  width: 25px;
  float: left;
  margin: 10px;
}

And specify them in your HTML like this

<div id='pink' class='box'></div>

I like this version the best, because if you ever need to select this element in the DOM explicitly, it would look like

#pink.box {
   height: a different height;
}

Upvotes: 0

Robert
Robert

Reputation: 21388

Here ya go, #content div is what you want. You can go deeper if you needed, ie #content div span a would reference an anchor, nested in a span that's nested in the div that's nested in something with the ID of #content.

http://jsfiddle.net/eDhXs/

#content { display: block; width: 250px; height: 50px; background-color: #330000; }

#content div { height: 25px; width: 25px; float: left; margin: 10px; }
/* pink */
#one { background-color: #FFCCCC; }
/* hot pink */
#two { background-color: #FF0099; }
/* tan */
#three {background-color: #CC9900; }
/* aqua blue */
#four { background-color: #33FFFF; }
/* yellow */
#five { background-color: #FFFF00; }

Upvotes: 0

meder omuraliev
meder omuraliev

Reputation: 186742

You have to specify the node after #content:

#content div { SAME RULES }
#one { INDIVIDUAL }
#five { INDIVIDUAL }

or you can do this:

#one, #two, #five { SAME RULES }
#one { INDIVIDUAL }

You can also give each of those divs a class name and do

.divs { SAME RULES }
#one { INDIVIDUAL }

Upvotes: 4

Quentin
Quentin

Reputation: 944321

You want:

#content div {

i.e. "All the div elements that descend from the element with the id 'content'"

I recommend giving http://css.maxdesign.com.au/selectutorial/ a read.

Upvotes: 4

Related Questions