216-Color Safe Web Palette

In the early days of the Internet, some computers had video capabilities that were limited to 256-color palettes. Since HTML's 24-bit RGB palette supports 16,777,216 colors, someone very smart figured out an algorithm that reduced the full 24-bit color palette into a much smaller 216-color palette that computers with limited color support could utilize.

Today most operating systems don't have a problem with full 24-bit or 32-bit color palettes, but I tend to stick to the 216-color palette in most circumstances just because it's pretty easy to do the math in my head. When you think about the hexadecimal 00-33-66-99-CC-FF progression, it's pretty easy to figure out which colors you need. That said, every once in a while I need to see the subtle differences between colors that are close to each other. With that in mind, it's pretty handy to keep a color palette around, and the following table lists the original 216-color safe web palette that all browsers should support.

FF99FF FF99CC FF9999 FF9966 FF9933 FF9900
FF66FF FF66CC FF6699 FF6666 FF6633 FF6600
FF33FF FF33CC FF3399 FF3366 FF3333 FF3300
FF00FF FF00CC FF0099 FF0066 FF0033 FF0000
CC99FF CC99CC CC9999 CC9966 CC9933 CC9900
CC66FF CC66CC CC6699 CC6666 CC6633 CC6600
CC33FF CC33CC CC3399 CC3366 CC3333 CC3300
CC00FF CC00CC CC0099 CC0066 CC0033 CC0000
99FFFF 99FFCC 99FF99 99FF66 99FF33 99FF00
99CCFF 99CCCC 99CC99 99CC66 99CC33 99CC00
9999FF 9999CC 999999 999966 999933 999900
9966FF 9966CC 996699 996666 996633 996600
9933FF 9933CC 993399 993366 993333 993300
9900FF 9900CC 990099 990066 990033 990000
66FFFF 66FFCC 66FF99 66FF66 66FF33 66FF00
66CCFF 66CCCC 66CC99 66CC66 66CC33 66CC00
6699FF 6699CC 669999 669966 669933 669900
6666FF 6666CC 666699 666666 666633 666600
6633FF 6633CC 663399 663366 663333 663300
6600FF 6600CC 660099 660066 660033 660000
33FFFF 33FFCC 33FF99 33FF66 33FF33 33FF00
33CCFF 33CCCC 33CC99 33CC66 33CC33 33CC00
3399FF 3399CC 339999 339966 339933 339900
3366FF 3366CC 336699 336666 336633 336600
3333FF 3333CC 333399 333366 333333 333300
3300FF 3300CC 330099 330066 330033 330000
00FFFF 00FFCC 00FF99 00FF66 00FF33 00FF00
00CCFF 00CCCC 00CC99 00CC66 00CC33 00CC00
0099FF 0099CC 009999 009966 009933 009900
0066FF 0066CC 006699 006666 006633 006600
0033FF 0033CC 003399 003366 003333 003300
0000FF 0000CC 000099 000066 000033 000000

Update #1

I should also mention that sometime back in 1998 I wrote a classic ASP page that automatically generates the HTML for the table that I listed, and here's the code for that:

Response.Write "<center><table border=""1"" cellspacing=0 cellpadding=5 style=""color: #000000; border-collapse: collapse; border: 1px solid #000000; padding: 5px; background-color: #FFFFFF"">" & vbCrLf

Const intFactor = 51

For X = 255 to 0 Step -intFactor
For Y = 255 to 0 Step -intFactor
Response.Write "<tr>" & vbCrLf
For Z = 255 to 0 Step -intFactor
If X < 153 And Y < 153 And Z < 153 Then
strFgcolor = "ffffff"
strFgcolor = "000000"
End If
strBgcolor = Right("00" & Hex(X),2)
strBgcolor = strBgcolor & Right("00" & Hex(Y),2)
strBgcolor = strBgcolor & Right("00" & Hex(Z),2)
Response.Write "<td style=""border:1px solid #000000;background-color:#" & strBgcolor & ";color:#" & strFgcolor & """>"
Response.Write "<tt>" & strBgcolor & "</tt>"
Response.Write "</td>"
Response.Write "</tr>" & vbCrLf

Response.Write "</table></center>" & vbCrLf

Update #2

A lot of web programmers started out with classic ASP like I did, but like most of those programmers I eventually moved on to ASP.NET. And with that in mind, here's the C# code to create the table that I listed:

Response.Write("<center><table border=1 cellspacing=0 cellpadding=5 style=\"color: #000000; border-collapse: collapse; border: 1px solid #000000; padding: 5px; background-color: #FFFFFF\">");

const int intFactor = 51;
string strFgcolor = "";
string strBgcolor = "";

for (int X = 255; X > 0; X -= intFactor)
for (int Y = 255; Y > 0; Y -= intFactor)
for (int Z = 255; Z > 0; Z -= intFactor)
if ((X < 153) && (Y < 153) && (Z < 153))
strFgcolor = "ffffff";
strFgcolor = "000000";
strBgcolor = String.Format("{0:X2}{1:X2}{2:X2}", X, Y, Z);
Response.Write("<td style=\"border:1px solid #000000;font-size: 11pt;padding: 2px; background-color:#" + strBgcolor + ";color:#" + strFgcolor + "\">");
Response.Write("<tt>" + strBgcolor + "</tt>");




History of the FrontPage Personal Web Server

A Short History of Windows Personal Web Servers

1994 - Bob Denny makes the first NCSA-based
web server for Windows:
1995 - Vermeer makes the FrontPage 1.0
Personal Web Server:
1995 - Vermeer also licenses FrontPage to FTP
software, which re-brands the Personal Web Server:
1996 - Microsoft releases the FrontPage 1.1
Personal Web Server:
1997 - Microsoft releases the FrontPage 97
Personal Web Server:
1998 - Microsoft releases the FrontPage 98
Personal Web Server:
2000 - Microsoft releases FrontPage 2000 and
ceases making a FrontPage Personal Web Server.

The Early FrontPage History

I have a long history with Microsoft FrontPage, but not many people know where it originally came from. FrontPage started its life as a product from a little startup company from Massachusettes that was named Vermeer Technologies, Inc. To tell the story in detail, I've included Randy Forgaard's foreword from the book Introducing Microsoft FrontPage, by Microsoft Press.

One Thursday afternoon in early April 1994, my wife took an urgent phone call from a man on a carphone. He had gotten my name from my MIT masters thesis adviser, and was calling to offer me a job. Thinking he was one of those pesky headhunters, my wife declined to give him my work phone number, but said he could phone back that evening. He was worried about the time delay, but nonetheless phoned back at 7:00pm and we chatted. The man was Charles H. Ferguson, a renowned computer industry consultant on technology policy and corporate strategy. We met and talked several times over that weekend. His professional references spoke glowingly of him, including a contact in the White House whose only negative remark was that Charles wasn't invited as often to testify in front of Congressional subcommittees anymore because of his impatience with the slow pace of lawmaking. Four days later I quit my job and became co-founder of a software company that within a few months was named Vermeer Technologies, Inc. - after Charles' favorite Dutch painter. As it turns out, Charles' general sense of urgency was extraordinarily justified.

In the beginning, Charles was the idea person, and I was the one charged with filling out the details and helping to refine the goals to tasks that were achievable by a small group of extremely talented engineers in a reasonable timeframe. His central thesis was at once unusually insightful and incredibly ambitious. He had noticed that many companies had spent millions building their own private computer online services - Apple's eWorld, Dow Jones News Retrieval, Bloomberg's Financial Network, etc. Not only were these efforts expensive, but they were incompatible with one another, requiring different client software to interact with each one. They were based on outmoded mainframe-based technology, requiring a computing priesthood to build and maintain them. They were centralized, making it very difficult to access distributed data. Their cost structure was sufficiently high that free services - such as providing online marketing and customer support information - were not economically viable. And finally, such centralized systems were not suitable for private, distributed, internal information dissemination within an organization.

Thus, our goal was to build a standardized, shrink-wrapped infrastructure for online services, architected for interoperability, providing standardized client software and a visual development environment that would allow non-programmers to create and maintain a new online service. The idea was that you could walk into a software store, buy our standard online service server software, buy several copies of our authoring software, and resell the standard online client software to your customers. You could easily create and maintain your online service. Your customers could use the client software to dial-in to your service, and then use that same client software to dial-in to other online services created with our software. The standardized server software would be architected so that online services could communicate with each other easily. Everything was interoperable, the API's and protocols would be documented as open standards, everyone would benefit from the increased convenience and functionality of standardized components, and the whole affair would be dramatically less expensive because the development cost was spread across all customers.

This idea changed dramatically about one month after the company was formed. In May 1994, we got wind that the Internet was starting to be adopted by businesses, and that there was a new infrastructure called the World Wide Web that provided a type of online service functionality on top of the Internet protocols. Mosaic, from the National Center for Supercomputing Applications, had been released 5 months earlier, and provided the first graphical user interface for the Web. Netscape Communications Corp. (then called Mosaic Communications) had just been formed in April (the same time as Vermeer), and would release their famous commercial web browser toward the end of the year.

It occurred to us that the Web provided much of what we were trying to achieve: standardized protocols (HTTP) and API's (CGI), server software that supported those protocols (various web server incarnations from various organizations), client software that supported those protocols (various web browsers), and even a communications infrastructure (the Internet) that was more robust and convenient than we were planning (dial-up to each online service). The big missing piece: a powerful, visual authoring tool for creating, maintaining, and administering whole web sites, including the individual pages that comprise such sites. This became the focus of Vermeer.

We were extraordinarily fortunate to be able to hire the most talented collective group of individuals I have ever met, despite the fact that we yet had no funding (except for direct expenses, covered by Charles), and asked everyone to take no salary for many months. Andy Schulert and Peter Amstein, both seasoned professionals, were our first two engineering hires and became our two technical team leaders. We were joined by many other engineers, plus excellent marketing, sales, administrative, and executive personnel. Every one of them a consummate professional, every one driven and focused to the task at hand. It was - and is - a remarkable experience for us all.

While Vermeer was driving to ship its first product, the Web became an unprecedented success. Whereas there were only an estimated 10,000 web sites in existence when Vermeer was formed, there were approximately 500,000 such sites one year later, both external sites on the Internet, and intranet sites within organizations. By just about any measure - communications traffic, new web sites going up, downloads of web browsers and servers, new Internet subscriptions - the web was growing at 20% per month, the fastest growing phenomenon in economic history. It became imperative that any forward-thinking organization have a high-quality public web site, and internal IS organizations where behooved to seriously explore the use of Web technologies for intranet information transfer and applications.

Vermeer shipped version 1.0 of its product in October 1995, just one week behind schedule. The name of the product, FrontPage, was suggested by Mitch Kapor, the founder of Lotus and On Technology. On the one hand, FrontPage was a great success, winning many industry awards, and praises from customers. On the other hand, during the brief life of Vermeer, web authoring had advanced from a curious backwater to a major focus of some of the largest players in the software industry. Tiny Vermeer, with fewer than 40 employees, suddenly found itself in the hotseat.

At around this time, Chris Peters, a Vice President and 15-year veteran of Microsoft, called us up. They really liked the product. They felt we had just the right idea, to focus on building a whole web, in addition to creating individual pages. They liked the fact that FrontPage looked just like a Microsoft Office application. They were impressed that we seemed to be 9-12 months ahead of the industry. They wanted to know if we were interested in some sort of relationship, anywhere from co-marketing, to technology licensing, to the "full meal deal" as he called it - being acquired.

We took a hard look at Microsoft, and were extremely impressed. Microsoft had recently transformed itself into a highly Internet-focused company. They were extraordinarily good at shipping products. And we realized that our efforts would be multiplied a thousand-fold by joining Microsoft. So we did.

Almost all of the Vermeer folk joined Microsoft, with virtually the entire engineering team moving to Microsoft headquarters in Redmond, Washington. We have just shipped Microsoft FrontPage 1.1. It has been a heady experience, and with the backing of Microsoft's extensive resources, we hope to be even more effective and customer-driven with future versions of FrontPage. Vermeer was formed just two years ago, and the adventure has just begun.

Our mission with FrontPage has remained the same, and if anything has become even more so as part of Microsoft: web authoring for everyone. Microsoft has Internet Studio and other products for advanced web development, but if you are a non-technical professional charged with creating or updating Internet or intranet web content, FrontPage was designed for you. We hope you will find it productive, instructive, and enjoyable.

Randy Forgaard
Senior Program Manager, Web Authoring Product Unit
Microsoft Corporation
May 1996

IIS: Notes on Server-Side Includes (SSI) syntax

A few years ago I put together a bunch about using Server-Side-Include (SSI) files with IIS 4. These notes eventually became Microsoft KB article Q203064, and I updated that information a couple of years later to incorporate IIS 5. This information is no longer available from Microsoft's support website, so I thought that it would make a good blog post.


This article details some features that are available in the Microsoft implementation of Server-Side Include (SSI) files for Internet Information Server (IIS) and provides general syntax and examples for SSI directives.


  • Microsoft Internet Information Services 5.0
  • Microsoft Internet Information Server 4.0


SSI files are most commonly used with IIS to allow content authors to include the contents of one file inside another file, allowing the easy creation of script libraries or page headers and footers.

SSI files, like Active Server Pages (ASP) and Internet Data Connector (IDC) files, are script-mapped by file extension to a preprocessor dynamic-link library (DLL). In the case of SSI, the handler is Ssiinc.dll. SSI files are usually named with .stm file extensions, although extensions of .shtm and .shtml are also supported.

SSI is employed by the use of special preprocessing directives in SSI documents. These directives are parsed by the SSI DLL and processed. All directives are contained in HTML comment tokens and take the following general form:


Supported Directives

The following directives are supported in the IIS implementation of SSI:
  • #config - Configures how variables and commands are displayed.
    • The general syntax for the #config directive is as follows:
      <!-- #CONFIG <ERRMSG/TIMEFMT/SIZEFMT>="<format>" -->
    • The following is an example of a simple page that uses the #config directive:
      <!-- #CONFIG TIMEFMT="%m/%d/%y" -->
      <p>Today's Date = <!--#ECHO VAR = "DATE_LOCAL" --></p>
      <!-- #CONFIG TIMEFMT="%A, %B %d, %Y" -->
      <p>Today's Date = <!--#ECHO VAR = "DATE_LOCAL" --></p>
  • #echo - Inserts the value of various Common Gateway Interface (CGI) system environment variables.
    • The general syntax for the #echo directive is as follows:
      <!--#ECHO VAR = "<CGI_VARIABLE_NAME>"-->
    • The following is an example of a simple page that uses the #echo directive:
      <p>Server Name = <!--#ECHO VAR = "SERVER_NAME"--></p>
      <p>Date = <!--#ECHO VAR = "DATE_LOCAL" --></p>
      <p>Page URL = <!--#ECHO VAR = "URL" --></p>
  • #exec - Executes CGI or Internet Server API (ISAPI) command scripts and inserts output into an HTML document.
    • The general syntax for the #exec directive is as follows:
      <!-- #EXEC <CGI/CMD>="<command>" -->
    • The CMD command for the #exec directive is disabled by default on IIS 5.0. For more information, see the following Microsoft Knowledge Base article:

      233969 SSIEnableCmdDirective is set to FALSE by default

    • The following is an example of a simple page that uses the #exec directive:
      <p>Root Directory of C:</p>
      <pre><!--#EXEC CMD="cmd /c dir c:\ /b"--></pre>
  • #flastmod - Retrieves the last modification time of a specified file.
    • The general syntax for the #flastmod directive is as follows:
      <!--#FLASTMOD <FILE/VIRTUAL> = "filename.ext"-->
    • The following is an example of a simple page that uses the #flastmod and #config directives:
      <!-- #CONFIG TIMEFMT="%m/%d/%y" -->
      <p>Modified Date = <!--#FLASTMOD FILE="filename.ext"--></p>
      <!-- #CONFIG TIMEFMT="%B %d, %Y" -->
      <p>Modified Date = <!--#FLASTMOD FILE="filename.ext"--></p>
  • #fsize - Retrieves the size of a specified file.
    • The general syntax for the #fsize directive is as follows:
      <!--#FSIZE <FILE/VIRTUAL> = "filename.ext"-->
    • The following is an example of a simple page that uses the #fsize and #config directives:
      <!-- #CONFIG SIZEFMT="BYTES" -->
      <p>File Size = <!--#FSIZE FILE="filename.ext"--> bytes</p>
      <!-- #CONFIG SIZEFMT="ABBREV" -->
      <p>File Size = <!--#FSIZE FILE="filename.ext"--> KB</p>
  • #include - Includes the contents of one specified file inside another.
    • The general syntax for the #include directive is as follows:
      <!--#INCLUDE <FILE/VIRTUAL> = "filename.ext"-->
    • The following is an example of a simple page that uses the #include directive:
      <!--#INCLUDE FILE = "header.inc"-->
      <p>Hello World!</p>
      <!--#INCLUDE VIRTUAL = "/includes/footer.inc"-->

More Information on File and Virtual Syntax

SSI directives that use file paths can reference files by using a file or virtual path.
  • The file element is used with files that are relative to the folder of the current document. The following example includes a file in the current folder:
    <!--#include file="myfile.txt"-->
  • The virtual element represents paths that are relative to the base folder of the Web server. The following example includes a file in the /scripts virtual folder:
    <!--#include virtual="/scripts/myfile.txt"-->


For additional information on using SSI with IIS, click the following article numbers to view the articles in the Microsoft Knowledge Base:

  • 169996 To run an ISAPI DLL with #exec, use the CGI statement
  • 166491 Secure batch files return access denied error message
  • 195291 How to disable #exec in Server-Side Include files