Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CSS class inheritance 1

Status
Not open for further replies.

Olaf Doschke

Programmer
Oct 13, 2004
14,847
DE
The following example of inheritance works, but I wonder if this is standard, or I'm just lucky, that IE interprets it as I intended. I display flags for choosing the language of a webpage with this CSS:

Code:
#flag                  {width:20px; height:12px;}

#flag.english          {background-image: url(Pics/Flags/English.gif);}
#flag.english.active   {filter: Glow(color=#FFFFFF, strength=3);}
#flag.english.inactive {filter:Alpha(opacity=30, finishopacity=25, style=2);}

#flag.german           {background-image: url(Pics/Flags/German.gif);}
#flag.german.active    {filter: Glow(color=#FFFFFF, strength=3);}
#flag.german.inactive  {filter:Alpha(opacity=30, finishopacity=25, style=2);}

The idea is, all flags have the same size, so I define width+height once as id #flag.

Then I subclass this for each language with a picture of the flag (I'll use that style for a div id="flag"), which leads to #flag.english and #flag.german.

A webpage may or may not be available in a language, so I add subclasses .active and .inactive with different filters on the picture to render it active ( with a glow effect) and inactive (dimmed/bleached).

Okay, everythings fine so far.

Now If use this html, it displays the active english flag:
Code:
<div id="flag" class="english active"></div>

And with this html I display the german flag with a filter effect that renders it dimmed (inactive):
Code:
<div id="flag" class="german inactive"></div>

1. Is it standard to specify the subclass german.inactive this way? Do all browsers render that with the right style?

I think filter is also specific to IE, but I may change that if the class name specification works this way.

2. I needed to repeat the definition of active ans inactive style for both languages. I could change the order, eg instead of first defining the english and german flag, I'd define #flag.active and #flag.inactive. But then I would repeat the style for the languages.

Is there a better way to do this, or is that the limitation of class inheritance in CSS?

Bye, Olaf.
 
1. It's not a subclass, but it is standard. IE (IE6 at least, might've been fixed in IE7) however interprets that wrong. There are no levels in classes, they are all equally important. As far as CSS goes, your syntax says: element that has both .english class and .active class. IE6 interprets that both as either. It might work in your scenario, since there aren't any shared rules in both declarations.

2. Your bigger issue is the id. It seems you're repeating id multiple times on the page. Id must only appear once, because it uniquely defines an element.

It's hard to suggest the best way to do this since we cannot see how this looks on the actual website. But how about something like this?
HTML:
<ul id="languageBox">
  <li class="english"></li>
  <li class="german active"></li>
</ul>
CSS:
#languageBox li {
  width: 20px; 
  height: 12px;
  filter:Alpha(opacity=30, finishopacity=25, style=2
}

.english {
  background-image: url(Pics/Flags/English.gif);
}

.german {
  background-image: url(Pics/Flags/German.gif);
}

#languageBox .active {
  filter: Glow(color=#FFFFFF, strength=3);
}
[code]

___________________________________________________________
[small]Do something about world cancer today: [url=http://cancer.iaea.org/]Comprehensive cancer control information at PACT[/url][/small]
 
CSS:
#languageBox li {
  width: 20px;
  height: 12px;
  filter: Alpha(opacity=30, finishopacity=25, style=2);
}

.english {
  background-image: url(Pics/Flags/English.gif);
}

.german {
  background-image: url(Pics/Flags/German.gif);
}

#languageBox .active {
  filter: Glow(color=#FFFFFF, strength=3);
  filter: Alpha(opacity=100);
}
Ooops, some errors crept in the CSS code. I don't know what the finishopacity and style are in alpha filter, so you might have to play around with that. And yes, filter is an IE only command.

___________________________________________________________
[small]Do something about world cancer today: Comprehensive cancer control information at PACT[/small]
 
Hi Vragabond,

You made a good point I didn't thought about, id should be unique.

So the ids should be each language, as that is always only once either active or inactive. The flag size then should rather be a class instead of id.

How it looks on the page: I have flags for each language I intend to provide a translation for, they are positioned fixed in the upper right corner from left to right. The active language has a glow, then there are available languages, which flags are shown normal and if no translation is available, the flag is shown inactive. So I already simplyfied the example, as I did not define CSS for the normal flag.

It's just a small case, but I miss hat real inheritance in CSS. I might also try to define .active and .inactive independantly and see if it works.

I'll get back with my results later. Thanks for your input.

Bye, Olaf.
 
okay, now here's my solution, which is based on suggestions I found here:
Code:
body      {background-color:#000000;}

.flag {width:24px; height:16px; position:absolute; top:10px; background-repeat:no-repeat; background-position: 2px 2px;}

#english  {background-image: url(Pics/Flags/English.gif); right:70px;}
#german   {background-image: url(Pics/Flags/German.gif); right:40px;}
#french   {background-image: url(Pics/Flags/French.gif); right:10px;}

.active       {filter: Glow(color=#FFFFFF, strength=2);}
.notavailable {filter:Alpha(opacity=30, finishopacity=25, style=2);}

html to show it:
Code:
<div id="english" class="flag active" ></div>
<div id="german"  class="flag notavailable" ></div>
<div id="french"  class="flag"></div>


Instead of defining the flag class I could also:
Code:
body      {background-color:#000000;}

#english, #german, #french {width:24px; height:16px; position:absolute; top:10px; background-repeat:no-repeat; background-position: 2px 2px;}

#english  {background-image: url(Pics/Flags/English.gif); right:70px;}
#german   {background-image: url(Pics/Flags/German.gif); right:40px;}
#french   {background-image: url(Pics/Flags/French.gif); right:10px;}

.active       {filter: Glow(color=#FFFFFF, strength=2);}
.notavailable {filter:Alpha(opacity=30, finishopacity=25, style=2);}

and then on the html side would only need to specify one class:
Code:
<div id="english" class="active" ></div>
<div id="german"  class="notavailable" ></div>
<div id="french"></div>

Bye, Olaf.
 
Of course, given that your list of languages is a list, using my example of an unordered list would be semantically more correct. Also you could, through dependent classes, define the flag standard properties to a list item (li) element (like I did), avoiding both the necessity for an extra class (clutters the html) or defining all the language ids (clutters the css and does not really scale well if you add languages).

___________________________________________________________
[small]Do something about world cancer today: Comprehensive cancer control information at PACT[/small]
 
You're right with the list semantic. I'll try to incorporate that, too.

Yes, my approach wouldn't work well with much more than 3 languages, but you wouldn't want to flood each page with many flags.

Thanks again.
 
Now here's what I ended up with, incorporating your idea of an ul for the languages:

CSS:
#languages    {position:absolute; top:10px; right:0px;}
#languages li {position:relative; padding-right:10px; float:left;
               width:30px; height:18px; background-repeat:no-repeat;}

.en           {background-image:url(Pics/Lang/eng.gif);}
.de           {background-image:url(Pics/Lang/ger.gif);}
.fr           {background-image:url(Pics/Lang/fre.gif);}

.active       {top:-1px;}
.avail:hover  {cursor:hand; top:-1px;}
.unavail      {opacity:.30; moz-opacity:.30; filter:Alpha(opacity=30);}

Code:
<div id="languages">
<ul>
<li class="lang en active"></li>
<a href="page.de.html"><li class="lang de avail"></li></a>
<li class="lang fr unavail"></li>
</ul>
</div>

Now it would be easy to extend that with additional languages, although it will look overloaded with much more than three.

Bye, Olaf.
 
It seems you have a useless "lang" class in your html. And you put an anchor element around the list item elemt. However, it should be the other way around. Anchor (<a>) is an inline element, while list item (<li>) is a block-level element.

In addition, I would remove one of the states. If you have three states, active, available and unavailable you could stick with available as being default and just change the properties of the default one when it is unavailable or active.

___________________________________________________________
[small]Do something about world cancer today: Comprehensive cancer control information at PACT[/small]
 
You're right, I eliminated the lang class and forgot to remove it from the html.

Thanks for warning with the false usage of an inline element outside of a block element. There should be only li within ul, right? And other html only within the li blocks. I wonder if it would work and span the a href along the background image of the li block, so that a click on the flag will cause the navigation to that translation.

Bye, Olaf.
 
Here's how I've done it on . I've only got English and Italian versions (so far), but the code would work for more:
Code:
<ul class="langlinks">
  <li><a class="ita" href="/ita/index.shtml" lang="it" xml:lang="it" title="Legga questa pagina in Italiano">Italiano</a></li>
</ul>
With this CSS:
Code:
ul.langlinks { 
margin : 1em 0; 
padding : 0; 
} 

ul.langlinks a { 
text-decoration : none; 
color : #ffdd99; 
background : #339933; 
padding : 5px 0 5px 30px; 
} 

ul.langlinks li { 
list-style : none; 
padding : 0; 
font-family : "Times New Roman", Times, serif; 
font-size : larger; 
font-weight : bold; 
margin : 0 0 10px 3px; 
} 

ul.langlinks a:hover { 
color : #ffffcc; 
background : #339933; 
}

ul.langlinks a.eng { 
background : url(/images/engshad.gif) no-repeat left center; 
} 
ul.langlinks a.eng:hover { 
background : url(/images/eng.gif) no-repeat left center; 
} 
ul.langlinks a.ita { 
background : url(/images/itashad.gif) no-repeat left center; 
} 
ul.langlinks a.ita:hover { 
background : url(/images/ita.gif) no-repeat left center; 
}
The <a> element has enough left-padding to accommodate the image to the side of the text, both will be clickable. I don't like to rely on just have having the flag image - what about people that don't see/load images?

Also, if you've got lots of these little flag images, you may want to look into CSS Sprites as a way of effectively downloading them all at once.

-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
Thanks Chris, I'll surely add alt/title tags.

Vragabond, I tried your sugestion to remove the avail class and make it the default, but that does not work out well:

CSS:
#languages     {position:absolute; top:10px; right:0px;}
#languages li  {position:relative; padding-right:10px; float:left;
                width:30px; height:18px; background-repeat:no-repeat;}
#languages li:hover  {cursor:hand; top:-1px;}

.en            {background-image:url(Pics/Lang/eng.gif);}
.de            {background-image:url(Pics/Lang/ger.gif);}
.fr            {background-image:url(Pics/Lang/fre.gif);}

.active        {top:-1px;}
.unavail       {opacity:.30; moz-opacity:.30; filter:Alpha(opacity=30);}
.unavail:hover {top: 0px;}

I coded the hover behaviour with the li tag, but that makes it the default of moving the flag up one pixel also for unavailable languages, where it should stay fixed and not look as if you could activate it.

Therefore I introduced .unavail:hover, but the top:-1px; from the li:hover seems to have precedence over the unavail definition. So the unavailable language flag jumps up if you hover over it, which looks like you can actiave it.

So I think on the CSS side I end up with what I already got.

Embedding the a tag within the li tag and removing the lang class from the html works okay.

Bye, Olaf.
 
I could revert to making en,de and fr ids instead of classes, as it's not really classes, they are only used once each per page and so the are ids.

I think that makes it very readable too:
Code:
<div id="languages">
<ul>
<li id="en" class="active"></li>
<li id="de" class="avail"><a href="page.de.html"></a></li>
<li id="fr" class="unavail"></li>
</ul>
</div>

Thanks, for me that's okay now.

Bye, Olaf.
 
with alt/title:
HTML:
<div id="languages">
<ul>
<li id="en" class="active"></li>
<li id="de" class="avail" tag="Seite auf Deutsch" title="Seite auf Deutsch"><a href="page.de.html"></a></li>
<li id="fr" class="unavail" alt="français non disponible" title="français non disponible"></li>
</ul>
</div>

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top