David Hurth's blog

Simple Round Corners in CSS


If you have developed a web 2.0 application you have probably used some technique to create rounded corners. Well, over at Search-This.com they have put together a good post about techniques for creating rounded corners. The tutorial attempts to make the process of creating rounded corners simple.

Below is an excerpt from the post.

One Size Fits All

We are going to use a single image (20px x 20px) to provide our rounded corners and to save on using different images we will use one image only and simply place each corner into place using the background-position property. The image is completely round but I'll only be showing one quadrant of it at a time and therefore we can supply all four corners with one simple image weighing in at only 300 bytes.

Figure 3


The benefit of using a single image is that all corners get loaded immediately after the first corner is drawn so there is virtually no delay.

Cut It Out

You may think that you could simply place the image in the four corners of a rectangular box but things aren't as simple as that. Our box needs to have a background color and as we are using a white corner image we need a white background for our box. However, if we place a transparent corner in the corner of that box then in fact nothing really happens. The reason is that the transparent part of the image lets the white background show through and all we get is the square box we started with.

In order for the corners to work properly the corner of the box must be over the background color of the element outside our current box. We therefore need to drag the round corners outside the box to start with but that presents more problems. Here is a screenshot of what the corners will look like outside the box so you can understand what's going on

Figure 4


As you can see we have a problem whatever we do! If the images are inside the rectangle then they become invisible. If they are outside the rectangle then it looks even worse as figure 4 above shows

What we really need is a rectangular box where the four corners are cut-out to give a cross-shaped effect. If we made sure that the cut-out matched the radius of our circle (10px) then we could pop our corners nicely into place.

We can achieve this by nesting an inner box inside our outer box and then dragging it outside of the parent using a negative top and bottom margin. If we also give side padding to the parent and top padding to the child we can get a cut out effect like this.

Figure 5


The CSS mark up for this is as follows:


  1. * {margin:0;padding:0}
  2. h1 {margin:.5em;}
  3. body {
  4. background:#e5e5e5;
  5. color:#000;
  6. }
  7. .box{
  8. float:left;
  9. background:#fff;
  10. padding:0 10px;
  11. margin:10px;
  12. display:inline;/* IE double margin bug*/
  13. }
  14. .one{width:40%}
  15. .inner{
  16. background:#fff;
  17. padding:10px 0;
  18. margin:-10px 0;
  19. position:relative;
  20. }

Followed by the simple HTML:


  1. <div class="box one">
  2. <div class="inner">
  3. <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed convallis mauris eu ipsum. Proin volutpat facilisis dui. Sed pretium pulvinar arcu.</p>
  4. </div>
  5. </div>

The next step is to provide four elements and place our corners into position with static positioning. We will be leaving a 10px padding around our box so that we have room to position the corners nicely without affecting the inner content. (Don't be tempted to use absolute positioning because IE is always 1px out when the distance traveled is an odd pixel number. This happens on right and bottom absolutely placed elements and can destroy a layout like this.)

I am going to use a div with nested span to provide elements for the corners but if you wanted to reduce mark up you could use a nested "b" element as suggested by Eric Meyer (although its use for background images is not likely to be very semantic). Using a nested b element would also negate the need for a class as you are unlikely to have any other elements like this on your page. Anyway I am sticking with the div and nested span as it is easier to follow.

The HTML we need for this is as follows:


  1. <div class="box one">
  2. <div class="inner">
  3. <div class="top"><span></span></div>
  4. <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed convallis mauris eu ipsum. Proin volutpat facilisis dui. Sed pretium pulvinar arcu.</p>
  5. <div class="base"><span></span></div>
  6. </div>
  7. </div>

The extra div and span has been placed inside the .inner element which means we must drag the top corners upwards into the padding area and then outwards into free space so that the transparent corners can show. The reverse process is needed for the bottom corners. There are a couple of "haslayout" bugs to squash on the way and IE6 also needs position relative applied to make the corners show.

The revised CSS and HTML for the whole section is shown below.


  1. * {margin:0;padding:0}
  2. h1 {margin:.5em;}
  3. body {
  4. background:#e5e5e5;
  5. color:#000;
  6. }
  7. .box{
  8. float:left;
  9. background:#fff;
  10. padding:0 10px;
  11. margin:10px;
  12. display:inline;/* IE double margin bug*/
  13. }
  14. .one{width:40%}
  15. .inner{
  16. background:#fff;
  17. padding:10px 0;
  18. margin:-10px 0;
  19. min-height:0;/* ie7 haslayout issues fix*/
  20. position:relative;
  21. }
  22. * html .inner{height:1px}/* ie6 haslayout issues fix*/
  23. .top,.base{
  24. margin:-10px -10px 0;
  25. background:url(images/one-round-test2.png) no-repeat left top;
  26. height:10px;
  27. position:relative;
  28. font-size:10px;
  29. }
  30. .base{
  31. background-position:left bottom;
  32. margin:0 -10px -10px;
  33. }
  34. .top span,.base span{
  35. background:url(images/one-round-test2.png) no-repeat right top;
  36. display:block;
  37. height:10px;
  38. font-size:10px;
  39. }
  40. .base span{background-position:right bottom;}

I have also added a content div in the middle just to tidy things up and the revised HTML is as follows:


  1. <div class="box one">
  2. <div class="inner">
  3. <div class="top"><span></span></div>
  4. <div class="content">
  5. <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed convallis mauris eu ipsum. Proin volutpat facilisis dui. Sed pretium pulvinar arcu.</p>
  6. </div>
  7. <div class="base"><span></span></div>
  8. </div>
  9. </div>

The font-size:10px in the CSS is there to restrict IE's height to 10px; otherwise it would increase the element to the full current font-size and spoil the effect. The result of the above code can be seen in these live examples:

Example 1

Example 2

Example 3

For ease of use the CSS has been left in the head so that you can view source and inspect it easily.

You can read the full tutorial by clicking here.

So go out there and make those non-stylish rectangular boxes into boxes with rounded corners!

Will Internet Explorer 8 Pass the Acid2 and Acid3 Tests?


Over at CNET's News.com they have posted an interesting story about if Internet Explorer 8 will pass the Acid2 and Acid3 test. The Acid tests are design to make it possible for web developers to create web sites that comply to standards so that they know that the design will be cross browser compliant.

Below is an excerpt from the post.

What will happen when you type http://webstandards.org/acid2 in your freshly installed IE 8? Will Acid2 be displayed correctly when you hit the test button?

Microsoft has been asked that question, but it has not given an answer. I think that the company is considering three possible scenarios.

One scenario could be that IE 8 will require users or authors to "opt in" to support standards. For example, in order to render Acid2 correctly, users could be required to modify IE 8's default settings. This breaks with the guidelines of the test, and IE 8 will therefore not pass in this scenario.

A second scenario could be that Microsoft requires Web pages to change the default settings by flagging that they really, really want to be rendered correctly. Web pages already have a way to say this (called "doctype switching," which is supported by all browsers), but Microsoft has all but announced that IE 8 will support yet another scheme.

If it decides to implement the new scheme, the Acid2 test--and all the other pages that use doctype switching--will not be rendered correctly.

A third scenario could be to hard-code the Web address of Acid2 into IE 8. This way, the page is given special treatment to make it look like the browser is passing the test. It should be obvious that this breaks the spirit of the test and doesn't warrant a passing grade.

I predict that Microsoft will implement at least one of these scenarios to limit the impact of standards. This would be damaging for the Web, and I therefore hope that my prediction is completely and absolutely wrong. The IE 8 team has shown that it can render Acid2 correctly. Now it's time for Microsoft to put its code to good use.

Read the full post here.

Hopefully Microsoft will get IE 8 to render Acid2 and Acid3 correctly for the good of the web (although, it won't make me change from Firefox).

As always we would love to hear your thoughts on this or any web related technologies. If you have something to say you can blog about it on this blog once you create a free account (once logged in just click on "Create content" => "Blog entry" and then blog).

Building User Interfaces Using Google Web Toolkit (GWT) : Video


Today I found an interesting video about building user interfaces using the Google Web Toolkit (GWT). This was taken from a presentation at the IndicThreads.com Conference on Java Technology held in Pune, India (I found the video over at IndicThreads.com).

Below is an excerpt from the post:

Chris Schalk's session on 'Building User interfaces using GWT' presented at the IndicThreads.com Conference On Java Technology 2007 held in Oct 2007 in Pune, India.

This session serves as an up to date review of the latest technologies and methodologies for "Building User interfaces using GWT". Specifically covered is - What is Google Web Toolkit (GWT), the potential of Ajax, what GWT brings to Ajax, what GWT focuses on, the Ajax Architectural Shift, building Ajax apps with Java(TM) technology and important GWT applets.

The GWT Mission is to radically improve the web experience for users. This is achieved by allowing developers to use existing Java tools to build no-compromise Ajax for modern browser users.

Speaker- Chris Schalk is a Developer Advocate for Google and helps promote Google Ajax technologies around the world. He is also one of the original members of the OpenAjax Alliance. Prior to Google, Schalk was a Principal Product Manager and Java Evangelist for Oracle's application server and development tools division. While at Oracle, he worked to define the overall Web development experience for Oracle JDeveloper and ADF Faces (Trinidad). He is also the co-author of JavaServer Faces: The Complete Reference published through McGraw-Hill Osborne

To read the full post click here and you can watch the video below.

It is always nice to see more information on the GWT as it is a great tool for Java developers that would like to make Ajax applications.

Build a customizable RSS feed aggregator in PHP


Over at IBM's developerWorks they have a good post on creating a RSS feed aggregator in PHP. As RSS has become a standard form of syndication for much of the webs content (especially in web 2.0 sites) the ability to aggregate feeds can be a good recourse.

Below is an excerpt from the post:

Functional components

The RSS function described in this article is made up of the following components, explained in the following order:

* Feed reader
* Feed sources input
* Feed aggregator
* Feed results output

These simple components combine to provide a powerful RSS feed aggregator function that can be integrated with other applications in a variety of ways. In the following sections, we will look inside the PHP code snippets that make up each of these components. Figure 2 depicts an overview of these functional components:

Figure 2. Overview of RSS functional components

Observe the following in Figure 2:

* The feed reader component does the bulk of the job and focuses on obtaining feeds provided by a given feed source. A feed source is nothing but a URL at which a particular content provider periodically syndicates the content for a given information category. For instance, a feed source might point to a URL at which the New York Times publishes all its latest news blurbs about the business category/channel using the XML-based RSS format.
* The feed aggregator component takes several user-specified feed sources as input and then it invokes the feed reader component to get all feed items from each customized feed source.
* The feed sources input component defines and reads the details about the user-specified feed sources. The feed source details can be provided in the form of a string stored in system memory, via an input file, or as records in a database.
* The feed results output component stores the aggregated RSS feed item results received from a particular feed source. It can store the results as a string in system memory, into a file, or into database tables.

To simplify our work, we will be combining the feed sources input and the feed results output components to be part of the feed aggregator component. (You can download a fully documented set of PHP source files for these components from the Download section.) You can extract these files to your machine and run them with your own customized set of RSS feed sources. As explained in a previous section, a PHP environment with XML and cURL library support is a prerequisite for doing this. (Refer to the Conclusion section to understand the many ways in which you can use the code for the RSS feed aggregator.)

You can read the full post here

You can download the code here.

As always we would love to hear about any interesting uses of RSS that you may have. You can write about them in this blog by signing up for a free account (once you login click on Create content => Blog Entry).

Alternate Ajax Techniques


Today I found an interesting post on alternative Ajax techniques (meaning techniques that do not use the XMLHttpRequest object). It is interesting to look at other techniques to load content without a page refresh (although I know that some would say that if you don't use the XMLHttpRequest object that it isn't really Ajax at all).

Below is an excerpt from the post:

Dynamic Script Loading

The first alternate Ajax technique is dynamic script loading. The concept is simple: create a new <script/> element and assign a JavaScript file to its src attribute to load JavaScript that isn't initially written into the page. The beginnings of this technique could be seen way back when Internet Explorer 4.0 and Netscape Navigator 4.0 ruled the web browser market. At that time, developers learned that they could use the document.write() method to write out a <script/> tag. The caveat was that this had to be done before the page was completely loaded. With the advent of the DOM, the concept could be taken to a completely new level.

The Technique

The basic technique behind dynamic script loading is easy, all you need to do is create a <script/> element using the DOM createElement() method and add it to the page:

var oScript = document.createElement("script");

oScript.src = "/path/to/my.js";


Downloading doesn't begin until the new <script/> element is actually added to the page, so it's important not to forget this step. (This is the opposite of dynamically creating an <img/> element, which automatically begins downloading once the src attribute is assigned.)

Once the download is complete, the browser interprets the JavaScript code contained within. Now the problem becomes a timing issue: how do you know when the code has finished being loaded and interpreted? Unlike the <img/> element, the <script/> element doesn't have an onload event handler, so you can't rely on the browser to tell you when the script is complete. Instead, you'll need to have a callback function that is the executed at the very end of the source file.

Example 1

Here's a simple example to illustrate dynamic script loading. The page in this example contains a single button which, when clicked, loads a string ("Hello world!") from an external JavaScript file. This string is passed to a callback function (named callback()), which displays it in an alert. The HTML for this page is as follows:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"


<html xmlns="http://www.w3.org/1999/xhtml">


    <title>Example 1</title>

    <script type="text/javascript">//<![CDATA[

        function makeRequest() {

          var oScript = document.createElement("script");

          oScript.src = "example1.js";



        function callback(sText) {

          alert("Loaded from file: " + sText);






    <input type="button" value="Click Me" onclick="makeRequest()" />



The JavaScript file example1.js contains a single line:

callback("Hello world!");

When the button is clicked, the makeRequest() function is called, initiating the dynamic script loading. Since the newly loaded script is in context of the page, it can access and call the callback() function, which can do use the returned value as it pleases. This example works in any DOM-compliant browsers (Internet Explorer 5.0+, Safari, Firefox, and Opera 7.0+), try it for yourself or download the examples.

More Complex Communication

Sometimes you'll want to load a static JavaScript file from the server, as in the previous example, but sometimes you'll want to return data based on some sort of information. This introduces a level of complexity to dynamic script loading beyond the previous example.

First, you need a way to pass data to the server. This can be accomplished by attaching query string arguments to the JavaScript file URL. Of course, JavaScript files can't access query string information about themselves, so you'll need to use some sort of server-side logic to handle the request and output the correct JavaScript. Here's a function to help with the process:

function makeRequest(sUrl, oParams) {

  for (sName in oParams) {

    if (sUrl.indexOf("?") > -1) {

      sUrl += "&";

    } else {

      sUrl += "?";


    sUrl += encodeURIComponent(sName) + "=" + encodeURIComponent(oParams[sName]);


  var oScript = document.createElement("script");

  oScript.src = sUrl;



This function expects to be passed a URL for a JavaScript file and an object containing query string arguments. The query string is constructed inside of the function by iterating over the properties of this object. Then, the familiar dynamic script loading technique is used. This function can be called as follows:

var oParams = {

  "param1": "value1",

  "param2": "value2"


makeRequest("/path/to/myjs.php", oParams)

You can read the full post here.

It is always interesting to look at different ways to do things, while a different technique may not be useful in your application it is good to know that they exist for occasions when that become useful (for instance if you want to load data cross domain you can't use the XMLHttpRequest object).

CSS Gradient Text Effect


Over at Web Designer Wall they have posted a good tutorial on creating a gradient header using CSS. The technique is based on an empty span tag a PNG and the position:absolute CSS property (the technique is 100% CSS, no JavaScript or Flash). Compatible tested browsers include Firefox, Opera, Safari and Internet Explorer.

Below is an excerpt from the tutorial:

How does this work?

The trick is very simple. Basically we are just adding a 1px gradient PNG (with alpha transparency) over the text.


The HTML markups

<h1><span></span>CSS Gradient Text</h1>


The key point here is: h1 { position: relative } and h1 span { position: absolute }

h1 {
  font: bold 330%/100% "Lucida Grande";
  position: relative;
  color: #464646;
h1 span {
  background: url(gradient.png) repeat-x;
  position: absolute;
  display: block;
  width: 100%;
  height: 31px;

That’s it! You are done. Click here to view my demo page.

Make it work on IE6

Since IE6 doesn’t render PNG-24 properly, the following hack is required in order to display the transparent PNG (add anywhere in between the <head> tag):

<!--[if lt IE 7]>

h1 span {
  background: none;
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='gradient.png', sizingMethod='scale');


This is why we hate IE 6!

jQuery prepend version (for semantic lovers)

If you don’t want to have the empty <span> tag in the heading, you can use Javascript to prepend the <span> tag. Here is a sample using jQuery prepend method:

<script type="text/javascript" src="jquery.js"></script>

<script type="text/javascript">

  //prepend span tag to H1


You can view the demo here or download it here. To read the full tutorial click here.

If you make any cool headers using this technique I would love to hear about them. You can either leave them in the comments or blog about them at this blog once you create a free account.

Find the Stories Digg Doesn't want You to Find


Ajaxonomy's Digg Bury Recorder has added a new feature, you can now see the top buried stories. Our hope with this new feature is that you might find interesting stories that you may not otherwise know about.

You can also search for the top buried stories for a particular subject. So, if you want to see the top buried Ron Paul stories, just search for Ron Paul and you will get quite a few results. Another couple of searches to try are iPhone and SEO.

The Top Buried stories are based on data from Ajaxonomy's Bury Recorder (some have started referring to it as ABR). ABR gets the bury data from all upcoming and popular stories, however once the story is fully buried (or auto buried which would possibly show no buries) it will not record any buries from the story as it has been fully buried. This means if a story is fully buried the last recorded bury is the bury that pushed it over the edge.

We hope that this list will be a welcome addition to the ABR. If you have any suggestions or questions about the ABR please leave a comment or if you think it would make a good blog post then sign up for a free account on this blog and write a story about it.

The below links will take you to the Ajaxonomy's Bury Recorder new feature and the application.
Digg's Top Buried Stories
Ajaxonomy's Bury Recorder

Adobe AIR Update for Flash CS3 Professional Beta 3 Released on Labs


If you are developing AIR applications then this will be good news for you. Adobe has released an update for Flash CS3 Professional so that it can now open .air files. This coincides with the release of Adobe AIR beta 3.

You can download the Adobe AIR beta 3 release here

You can read the full story here.

Google unveils new, slicker, faster iPhone-specific interface


Over at last100.com they have posted information on the new Google interface for the iPhone. The interface looks very slick and is apparently very fast (not being a lucky iPhone owner I can't test it out, but if any body wants to send me one let me know).

Below is an excerpt from the story.

Vic Gundotra, a vice president of engineering at Google, told CNet that — as a result of lots of people getting iPhones for Christmas presents — the number of queries on Google search from iPhones surpassed the number of queries from Symbian-based phones for the first time.

Think about it. Symbian is the market leader, used on phones from Nokia (the world’s No. 1 handset manufacturer), Motorola, Samsung, and Sony Ericsson, among others. The iPhone’s user base is comparatively teeny-tiny since the phone’s introduction last June.

Of course the “Christmas crossover”, as Google calls it, lasted only a few days, but as CNet rightfully notes,“It shows the impact the iPhone is having on the telecommunications industry and provides a glimpse into its future market potential on the Web.”

“It’s about usage, not just units,” Gundotra said in an interview with CNet. “The data proves that people are using the browser on the iPhone.”

igoogleBy providing a quicker, slicker user interface, more customization, iGoogle gadget integration, and more speed for all apps, Google is acknowledging the iPhone’s rosy future. iGoogle on the iPhone can be reached by pointing the phone’s browser at google.com/ig/i.

The standard mobile version of Google, made available just over a month ago, is still available at google.com/m, but it’s more limited and is available only in the U.S. It brought together a suite of applications like search, Gmail, Calendar, and Reader into one easy-to-use interface.

With Google for the iPhone, users will get an improved UI optimized for the touch screen, customization of default tabs (easy access to favorite applications), faster Gmail (email automatically show up, no refreshing needed), a speedier Calendar (including a new month view), and iGoogle.

You can see the new interface by pointing you iPhone (or computer browser) to http://www.google.com/ig/i.

You can read the full post by clicking here

Game Development using the Yahoo! User Interface

As with many people that get into programming, I started programming because I wanted to make video games (in-fact I have had a few games published about 10 years ago). Now that I am in the web development industry, I from time to time like to look at the developments in Video Game development as it pertains to the web.

The Yahoo! User Interface is a great library for development of JavaScript based applications, including Ajax applications. The library has quite a few methods to help with animation that can be very useful in developing games. Today, I'm not going to go into much detail on using the library to make a game (this will be in a later post), however, I do want to show you how well these games can look.

Check out the below games that where made using the Yahoo! User Interface.

I was amazed at how close these games are to their Flash counterparts. Of course the advantage to using JavaScript over flash is that no plug-in is required to play the game.

You can read more about the Yahoo! User Interface here.

If you've seen any other cool games built using the Yahoo! User Interface I would love to hear about it. If you sign up for a free account you can blog about it on this blog or you can leave them in the comments.

Syndicate content