Multi-language Web Site and Background Images
When one wants to replace text with an image, she uses some image replacement technique (I personally prefer Mike Rundle’s, but it’s really just a matter of taste). However, at the multi-language web site it could be a real trouble—you will have to make different background images for each language anyway, but let’s see if we can make multi-language CSS at least a little bit easier to manage. With the launch day knocking on a door, it’s not uncommon to make a mistake in language-specific CSS rules. With server-side parsing, you don’t have to worry about multiple rules. Parsing and gzipping of CSS files with PHP (or ASP) is nothing new, but with web.burza, we went a step further.
Hey! Server-side parsing is new to me!
It’s okay, we are going from the beginning : )
To force parsing of CSS file, we save it as PHP/ASP file, for example: instead of style.css, we save it as style.php or style.asp, depending whether we host on the Apache with PHP or on the Windows server with ASP. We call CSS in HTML as usual:
<link rel="stylesheet" type="text/css" href="style.php" /><!-- or style.asp -->
Browsers don’t recognize just any file as CSS, so we must ‘tell’ browser that this is CSS file. We send the header information by placing following lines at the top of the server-side parsed CSS file:
<?php header ("Content-type: text/css"); ?>
or for ASP:
<% Response.ContentType = "text/css" %>
This should do just fine for the starters. You want more? Google it.
I already learned about server-side parsing, tell me about multi-language trick
Since the CSS file is parsed, we can also send queries either by GET or POST method. If those words are nothing familiar to you, let’s just say—we can make some conditions when requesting CSS file. If we call our CSS like:
<link rel="stylesheet" type="text/css" href="style.php?language=en" /><!-- or style.asp?language=en -->
we have sent the query string. Next, we modify CSS file so it ‘understands’ this query, by adding following line:
<?php
header ("Content-type: text/css");
$language = (isset($_GET['language']) && $_GET['language'] == 'en') ? 'en' : 'other_language';
?>
or for ASP:
<%
Response.ContentType = "text/css"
If Request.QueryString("language") = "en" Then
language = "en"
Else
language = "other_language"
End if
%>
Now that we set our language variable, we can write it anywhere in the CSS file, for example:
<?php
header ("Content-type: text/css");
$language = (isset($_GET['language']) && $_GET['language'] == 'en') ? 'en' : 'other_language';
?>
/* CSS rules */
body { background-image: url(text_in_an_image_<? echo $language; ?>.gif) }
or for ASP:
<%
Response.ContentType = "text/css"
If Request.QueryString("language") = "en" Then
language = "en"
Else
language = "other_language"
End if
%>
/* CSS rules */
body { background-image: url(text_in_an_image_<% Response.Write(language) %>.gif) }
See how it works at web.burza’s English and Croatian CSS files.
This trick is pretty simple and it makes your life easier if you’re just coder. If you also do graphics—well, I’m sorry… you’ll have to make images for each language manually : ).

7 Comments
hi there,
how about sticking the lang attribute (using the cascade http://www.w3.org/TR/REC-html40/struct/dirlang.html#h-8.1.2) somwhere and then use attribute selectors for each lang imgtext pair
Comment (#) by dave — 17th April 2005.
Dave, this could be applied in a perfect world, with the perfect browsers. On the other hand, it’s much easier to maintain a single CSS rule, like shown above, than setting something lengthy, like:
body:lang(en) { background-image: url(text_in_an_image_en.gif) }body:lang(hr) { background-image: url(text_in_an_image_hr.gif) }
body:lang(fr) { background-image: url(text_in_an_image_fr.gif) }
body:lang(de) { background-image: url(text_in_an_image_de.gif) }
for every image replacement.
Comment (#) by marko — 17th April 2005.
wondered why i was in such a good mood this morning, I had completely forgot about that other browser :)
your solution is cool, i use somthing similar myself, there was no criticism intended, I was just thinking about more static solutions
eg having the lang on the body as a className and one sheet with .lang irelement {…..}
I went to check on ppk’s site about css browser compatibility and the attribute selector article hasn’t been updated for 17 months that says it all really doesn’t it …
Comment (#) by dave — 17th April 2005.
For multilingual sites, I’d recommend using a SWITCH (or SELECT CASE in the case of ASP) instead of an IF to do the languge selection.
Eg.
switch(Request.QueryString("language")){
case 'en': language='en'; break;
case 'fr': language='fr'; break;
case 'es': language='es'; break;
default: language='en';
}
Comment (#) by Jonathan Snook — 18th April 2005.
Server-side CSS files are very handy indeed, being able to insert different rules based on a visitor’s request is awesome!
I used a similar technique to deliver targeted masthead images (a different masthead for each state in the United States). Used the exact same approach and it worked perfectly.
One should use dynamic CSS files with caution though, at least with regard to high-traffic sites. I try to put all my dynamic rules in one little ASPX file, rather than the primary CSS file. I have seen instances where the server-side file took a while to load, in which case the web page displayed a FOUC.
ASP is growing antiquated quickly, I’d recommend moving on to ASP.NET if Microsoft is your platform of choice.
Comment (#) by Justin Perkins — 18th April 2005.
Wouldn’t it be easier to just use the base tag?
<base href="http://site.com/lang/">then for css do
<style type="text/css">import "css/main.css";
</style>
and just copy the css file into all required language/css subfolder (or just symlink it) and there you go, one rule, appropriate images used, path problems fixed
Comment (#) by zsepi — 18th April 2005.
@Jonathan:
I’m not very proficient in ASP anymore, but you’re right—it could be also done with an array:
<?php$languages = array('en','hr','fr','de');
if (isset($_GET['language'])) {
foreach($languages as $lang_code) {
if ($_GET['language'] == $lang_code) {
$language = $lang_code;
}
}
}
?>
but it could be too complicated for those who are not so PHP savvy, or not? : )
Comment (#) by marko — 18th April 2005.
Sorry, the comment form is closed at this time, but if you have anything to say, please send me a message.