Using CSS to absolute position an object relative to the inside of a center aligned container.

I wrote this article about 2 years ago. Our creative department at work ran into this problem last week, so I’ve decided to republish the article in blog format. The title is a mouth full, but I think it sets up the tutorial appropriately. 🙂 Enjoy.

Introduction

Horizontally centered websites have long been extremely popular. However, positioning an element using “position:absolute” in a center aligned website can be tricky. This tutorial walks you through the process using only CSS, and without the use of tables or complicated image splicing.

Why would you want to use absolute positioned elements in a center aligned layout? Such a technique allows you to place an image or navigational button on top of your current design. I use this technique on gnourg.com.

Unfortunately, an element that is absolute positioned in a center aligned container does not maintain its position relative to its container. Instead the absolute positioned element maintains its position relative to the window. This has the potential to blow the sites intended layout.

-Click here to view an example of the problem.
Hint: resize the window’s width.

Fortunately there is a solution to this problem.

Setting up our scenario

We use an image as our element to absolute position. But before we can position our image, we must create our center aligned container.

To center our website we create a div wrapper that contains all of the elements in the website, including our absolute positioned image. The CSS for our div wrapper appears as follows:

#wrapper {
   margin: 1px auto;
   padding: 0;
   border: 2px solid black;
   width: 580px;
   height: 300px;
}

Placed in our HTML, including all of the proper definitions, it looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Absolute positioning tutorial.</title>
<meta http-equiv="Content-Type" content="text/html;
   charset=ISO-8859-1" />
<style>
#wrapper {
   margin: 1px auto;
   padding: 0;
   border: 2px solid black;
   width: 580px;
   height: 300px;
}
</style>
</head>
<body>
<div id="wrapper">

</div>
</body>
</html>

Putting in the image

Our goal is to absolute position our image 200 pixels from the left border of our div wrapper and 30 pixels from the top border of our div wrapper. It will hover over any content beneath it.

We start off by simply placing the image in our div wrapper as follows:

<body>
<div id="wrapper">
<img src="sample.gif" height="50" width="100" alt="our img" />
This text is sample content that we want to start in the upper
left hand corner of our site, behind any absolute positioned
elements.
</div>
</body>

It is important that we place our image tag first inside the div wrapper, before any of the page’s other content.

Now we absolute position our image so that it does not take up space on our page. This should place our image in the upper left hand corner of our div wrapper, on top of our content. The CSS for this looks as follows:

<body>
<div id="wrapper">
<img src="sample.gif" style="position:absolute" height="50"
   width="100" alt="our img" />
This text is sample content that we want to start in the upper
left hand corner of our site, behind any absolute positioned
elements.
</div>
</body>

Final position

Now that our image takes up no space, and because it is placed before any of our page’s other content, it sits nicely in the top
left hand corner. From here we move our image by putting it in a div box and using relative positioning. It looks
like the following:

<body>
<div id="wrapper">
<div style="position:relative;top:30px;left:200px">
<img src="sample.gif" style="position:absolute" height="50"
   width="100" alt="our img" />
</div>
This text is sample content that we want to start in the upper
left hand corner of our site, behind any absolute positioned
elements.
</div>
</body>

Eureka, we have our absolute positioned object positioned relative to the inside of our center aligned website.

-Click here to view the final product.
Don’t forget to try resizing the window’s width.

This method has been tested in IE 5, IE 6, Netscape 6, and Mozilla 1.6. If you have any questions, corrections, or additions please drop me a comment.

Tutorial on how to open and read an email using C# and POP3

For a recent project I found a great tutorial on how to read and manipulate emails using POP3 on Developer Fusion.

Two things you should note when trying this code.

1) POP3 protocol won’t actually delete the email until you call the QUIT command. If your application fails before you call the Disconnect() method, no emails will be deleted.

2) I was unable to view the content of my emails without making a modification to the Response() method. Apparently the buffersize used in the tutorial was not sufficient for the emails I was viewing. The new method I used is posted on the tutorial’s feedback forum by “ddoctor.” It is as follows:

private string Response()
{
   System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();

   long buffersize = 1024;
   byte[] serverbuff = new byte[buffersize];
   NetworkStream stream = GetStream();
   int count = 0;
   while (true)
   {
      byte[] buff = new byte[2];
      int bytes = stream.Read(buff, 0, 1 );
      if (bytes == 1)
      {
         // if serverbuffer is full, double its capacity
         if (count == buffersize)
         {
            byte[] temp = new byte[buffersize * 2];

            int i = 0;
            while (i < buffersize)
            {
               temp = serverbuff;
               i++;
            }
            buffersize *= 2;
            serverbuff = temp;
         }

         serverbuff[count] = buff[0];
         count++;

         if (buff[0] == '\n')
         {
            break;
         }
      }
      else
      {
         break;
      };
   };
}

A Haunting SQL Statement

An interesting thing happened to me yesterday. A coworker came up to me and asked, “Did you write this SQL statement?” After looking at it I realized it was a statement I had written about a year ago. In this statement, I had come up with a clever way of creating what is essentially a SQL identity column. The first thought that came to my mind was “What an idiot! I could have just added an identity column to the table!” But what my coworker noticed, that I did not, is that this statement has powerful implications.

alter table temp_your_table
add Reference_Number int

declare @intCounter int
set @intCounter = 1000
update temp_your_table
SET @intCounter = Reference_Number = @intCounter + 1

The neat thing about this statement is that it can be used, instead of a loop, to mathematically manipulate a column. For example you could add a column of Fibonacci numbers! I’m not sure why a person would need a column of Fibonacci numbers, but it’s empowering to know that you could. 😉 There are probably several other neat applications that could be done with this approach.

Truth be told, things like this happen when a college grad with limited SQL knowledge, but an abundance of C++ education, begins learning SQL.

** UPDATE **
** 5/16/2006 **

Well I found a great use for the SQL statement above. For a recent project I needed to create a region specific drop down list of languages. If a user is visiting our Spanish site their drop down list needs to include the Spanish spellings of our language options in alphabetical order, BUT with Español on top of the list. Likewise, if the user is visiting our Portuguese site they need to see the list of languages with the Portuguese spelling, but with Portuguese on top.

To do this I sorted my list of languages in alphabetical order into a temp table with an “OrderNumber” column. Then I updated the “OrderNumber” column with an incrementing integer starting with 1. Next I updated my temp table, setting the “OrderNumber” of the default language to 0. Finally, I return the temp table ordered on my “OrderNumber” column. The whole procedure looks like the following. (I highlighted the “Haunted SQL Statement” from above in red.):

CREATE procedure GetLocalLanguageNameList @LanguageCode varchar(8) as

set nocount on

-- Find the ID of the Language the Page is Requesting
declare @LocalLanguageId as int
set @LocalLanguageId = (select LanguageId from Language where LanguageCode = @LanguageCode)

-- Get a list of alternative languages in the native tongue of the user
-- Add OrderNumber so we can use it to put the original Page Language ontop
-- Sore the alternative languages in alphabetical order
select l.LanguageCode, lln.LanguageName, 0 as OrderNumber
into #tempLangs
from dbo.LocalLanguageName lln
 join dbo.Language l on lln.LanguageId = l.LanguageId
where lln.LocalLanguageId = @LocalLanguageId
order by lln.LanguageName

-- Number our languages in alphabetical order
declare @intCounter int
set @intCounter = 1
update #tempLangs
SET @intCounter = OrderNumber = @intCounter + 1

-- Update the placement of the current pages language to the front of our list
update #tempLangs
set OrderNumber = 0
where LanguageCode = @LanguageCode

-- Display the list in our final order
select LanguageCode, LanguageName
from #tempLangs
order by OrderNumber

What's the difference between SQL's Truncate Table and Delete From Table?

Thought I’d add a small nugget of SQL knowledge I recently acquired to the blog; the difference between truncate table and delete from table. Both are ways to remove all the rows from a table, but which one should you use?

First off, a quick SQL language lesson. SQL statements are divided into two categories: the Data Definition Language (DDL) and the Data Manipulation Language (DML). DDL statements are used create and manipulate data structures. DML statements are used to modify data in those structures. DDL statements take place immediately. DML statements take place in memory first until they are committed to the database.

Truncate table is a DDL statement. Delete from table is a DML statement. This means that you must have ALTER permissions on the table if you want to use truncate.

The differences breakdown:

Truncate Table Delete From Table
Data Definition Language (DDL) Statement Data Manipulation Language (DML) Statement
Truncate table writes to the log file only once. Delete from writes to the log for every row.
Truncate table uses a table lock. Delete from locks each row.
Truncate table resets the identity counter. Delete from does not reset the identity counter.
You can’t truncate a table that is referenced by foreign keys. You can use delete from on a table with foreign keys.
Truncate doesn’t activate triggers. Delete from will activate triggers.

If you know any more differences drop me a comment.

Localhost doesn't work? Can't debug your .Net web app? This may be your answer.

For my very first post I’d like to share the solution to a problem I solved a month or two ago, but it was such a pain in the ass I’m certain someone will find this post useful.

When you run the debugger in Microsoft Visual Studio .Net 2003 & 2005 for a website project, by default Visual Studio opens up your site in a new web browser using the localhost path. Unfortunately for me, my localhost path was hosed for, what was then, some unknown reason. So when I clicked the debug button my browser would look for a few minutes for the site, then give me a page not found error. Along with this failure to find the page, while my browser was looking, my CPU utilization was running at 100%!

To get around this problem in Visual Studio 2003 I would simple start the debugger, and then as soon as my browser window opened, I clicked Stop. I then typed in my computers IP address in place of localhost in the address bar, and the browser would then happily find my website. This worked fine in 2003 because it relied on IIS to host my developing web application.

Unfortunately this solution did not work when I migrated to Visual Studio 2005. By default when you debug a web application in 2005, the site is opened in a virtual IIS web server. So my old tricks didn’t work. Now unable to debug my web apps I had to find the solution to my original problem. Why isn’t my localhost working?

I was able to ping my machine name, my IP address, localhost, and even 127.0.0.1. My Host file was untainted and correct. I even tried altering the Host file to make localhost point to my IP address. I could access websites in IIS using every address method EXCEPT localhost!

So I remoted into a development box I knew localhost worked on. I then ran IPCONFIG on that box and my own. Then I tried to make the results of my IPCONFIG identical to the computer that worked.

I noticed my computer had a lot of extra crap in the IPCONFIG that looked something like this:

c:\>ipconfig
Windows IP Configuration
Ethernet adapter Ethernet:
 Connection-specific DNS Suffix  . : wcoast.corp.example.com
 IP Address. . . . . . . . . . . . : 157.54.139.57
 Subnet Mask . . . . . . . . . . . : 255.255.252.0
 IP Address. . . . . . . . . . . . : 3ffe:ffff:8311:f282:1460:5260:c9b1:fda6
 IP Address. . . . . . . . . . . . : 3ffe:ffff:8311:f282:b973:4db8:97e2:e978
 IP Address. . . . . . . . . . . . : 3ffe:ffff:8311:f282:200:39ff:fe0e:fc35
 IP Address. . . . . . . . . . . . : fec0::f282:200:39ff:fe0e:fc35%1
 IP Address. . . . . . . . . . . . : fe80::200:39ff:fe0e:fc35%4
 Default Gateway . . . . . . . . . : 157.54.136.1
                                            fe80::210:ffff:fed6:58c0%4
Tunnel adapter 6to4 Tunneling Pseudo-Interface:
 Connection-specific DNS Suffix  . : wcoast.corp.example.com
 IP Address. . . . . . . . . . . . : 2002:9d3b:8b39::9d3b:8b39
 Default Gateway . . . . . . . . . :
Tunnel adapter Automatic Tunneling Pseudo-Interface:
 Connection-specific DNS Suffix  . : wcoast.corp.example.com
 IP Address. . . . . . . . . . . . : fec0::f70f:0:5efe:157.54.139.57%1
 IP Address. . . . . . . . . . . . : 3ffe:ffff:8311:f70f:0:5efe:157.54.139.57
 IP Address. . . . . . . . . . . . : fe80::5efe:157.54.139.57%2
 Default Gateway . . . . . . . . . : fe80::5efe:157.56.253.8%2

I googled some of the strange IP addresses then I learned about IPv6.

IPv6 is a new IP address protocol that basically gives us more addresses than IPv4. As the internet grows we’re gradually running out of available IP addresses IPv6 is the solution. IPv6 snuck onto my computer at some point during a Windows update. This is all well and good but for some reason it was killing my localhost path! After I uninstalled it, WHALAH! Localhost started working again, and I could properly debug my web apps in Visual Studio 2005.

To remove ipv6 in Windows XP with SP2, Windows XP with SP1, or Windows Server 2003 go to Control Panel -> Network Connections then double click the network card / adaptor you’re using. Under “This connection uses the following items” section you should see “Microsoft IPv6 Developer Edition” or “Microsoft TCP/IP version 6”. Select it and click uninstall.

If that doesn’t work, or you have Windows XP with no service pack installed, try running “netsh interface ipv6 uninstall” or “ipv6 uninstall” in Windows command prompt. Then go patch your OS!

If anyone knows why IPv6 was killing my localhost path, or you know how to have IPv6 installed and keep localhost working, I’d love to hear from you.

Happy debugging.

References:
IPv6 for Microsoft Windows: Frequently Asked Questions