Click here to monitor SSC
  • Av rating:
  • Total votes: 20
  • Total comments: 5
Phil Factor

Making HTML tables easier on the eye- CSS Structural Pseudo-classes

11 August 2011

We asked Phil why his PowerShell tabular reports looked so nice. 'CSS structural pseudo-classes' he muttered mystically. Later on, without any further warning, he popped up with this article that explains for anyone who has missed them, how to go about doing intricate formatting of an HTML file, the contents of which you cannot alter.

It is a common predicament: You have an HTML fragment with a table, list or dictionary  in it, generated from some data, and you have to render it in such a way that the data is easy to read, and the information presented in such a way as to prevent misunderstandings: However, you can't alter the HTML source in order to add CSS classes to individual elements. We'll take a couple of practical examples to show how you can solve this sort of problem.

The flurry of browser upgrades has had the result that a lot of useful CSS2 and CSS3 has been recently implemented. As well as helping the creation of the more esoteric mobile-applications and games, it is the extended ways of addressing individual DOM elements that is making the basic layout of text and tables a lot easier. This article aims to illustrate practical ways of doing this

With CSS3, you can more easily apply styles to elements of the DOM based on their location within the DOM. This solves many problems with the basic layout of text.  You may be faced with the requirement that the first paragraph in a DIV section may be formatted differently, you may want to tuck a bulleted list in under the paragraph that precedes it.  You may want code to have minimum paragraph spacing when it is preceded by another code paragraph. In the old days, you would need some work to do by hand in order to to tidy up text to make it conform to even the most rudimentary typesetting conventions.

CSS previously gave you some addressing methods that could be used. You could apply styles based on the ID of the DOM Element, or could apply it to all the children of a particular element, or element class, or to all the children of a particular TagType (e.g. A, DIV, P ). CSS2 and CSS3 give you a lot more besides. You can apply a style to the 'N'th child, or to every other child, whether they be even or odd in the sequence. ( 2, 4, 6, 8, 10 or 1, 3, 5, 7, 9¦) This is just the start. You can match the first element and no others, or the first few. You can specify this in inverse order, from the last element. If you want to disregard the parentage of the elements that you wish to attach a style to, then you can do so, and just specify elements by their sequence irrespective of their place in the hierarchy. At last, all the current browsers support this. Even Internet Explorer 9 will do it! The full list of these CSS addressing methods is contained in Simple-Talk's  XPath, CSS, DOM, Selenium. Rosetta Stone and Cookbook. wallchart here, together with the equivalent XPath and javascript  syntax.

To illustrate how this simplifies perfectly conventional formatting, we'll take a very simple example. You have a list and you'd like to enhance it so the background colour on alternating rows is different.

  1. Solomon Grundy,
  2. Born on a Monday,
  3. Christened on Tuesday,
  4. Married on Wednesday,
  5. Took ill on Thursday,
  6. Grew worse on Friday,
  7. Died on Saturday,
  8. Buried on Sunday.
  9. This is the end of Solomon Grundy.
  1. Solomon Grundy,
  2. Born on a Monday,
  3. Christened on Tuesday,
  4. Married on Wednesday,
  5. Took ill on Thursday,
  6. Grew worse on Friday,
  7. Died on Saturday,
  8. Buried on Sunday.
  9. This is the end of Solomon Grundy.

What do you mean, they look the same? We're talking about CSS3, so you will need an up to date version of any of the browsers. Even Internet Explorer should show the stripes in the right-hand list unless IE has gone quietly into 'compatibility mode'. (look for the grey border around the browser window). See here for a fix. Hopefully, with an up-to-date browser, you'll see how we're using the CSS3 syntax for applying different styles to alternating elements

Both the CSS and the HTML are very simple.  The CSS has something that looks a lot like a CSS2 pseudo-class, and in fact extends the idea. It is called a structural pseudo-class.

<style type="text/css">

ol.stripedlist{

list-style:none;

}

ol.stripedlist li:nth-child(2n-1){

background-color: #fafad2;

}

</style>

And the HTML  has no formatting beyond a couple of DIVs to position the two lists side by side.

<div style="float:left; width:300px">

<ol><li>Solomon Grundy,</li>

<li>Born on a Monday,</li>

<li>Christened on Tuesday,</li>

<li>Married on Wednesday,</li>

<li>Took ill on Thursday,</li>

<li>Grew worse on Friday,</li>

<li>Died on Saturday,</li>

<li>Buried on Sunday.</li>

<li>This is the end of Solomon Grundy.</li>

</ol>

</div>

<div style="width:300px">

<ol class="stripedlist">

<li>Solomon Grundy,</li>

<li>Born on a Monday,</li>

<li>Christened on Tuesday,</li>

<li>Married on Wednesday,</li>

<li>Took ill on Thursday,</li>

<li>Grew worse on Friday,</li>

<li>Died on Saturday,</li>

<li>Buried on Sunday.</li>

<li>This is the end of Solomon Grundy.</li>

</ol>

</div>

For a simple example like this, it is easier, and more backward-compatible, to simply assign a class to alternating elements to achieve the effect. However, you often can't do this, and where you are receiving an XHTML fragment from a source that knows only about the data rather than your requirements to make it easy on the eye, then it obviates the task of altering XHTML, which can get messy.

When content is generated from a database, it is very quick to supply it to the application as an XHTML fragment, using the XML extensions to SQL syntax. The actual data structure you use depends on the structure of the data. Most commonly, it will be a table, but I've used lists, Dictionary lists, and nested DIVs as well as tables. Here is a quick example of a table generated from AdventureWorks.

DECLARE @query NVARCHAR(MAX)

SET @query = '<table>

    <caption>AdventureWorks Employees</caption>

    <tr><th>Employee Name</th><th>Phone</th><th>Email</th></tr>'

+ REPLACE(CAST((SELECT TOP 20 --purely for demonstration purposes

      td =   COALESCE(Title + ' ','')

             + COALESCE(firstname + ' ','')

             + COALESCE(Middlename+' ','')

             + Lastname, '',

      td = Phone,'',

      td = EmailAddress

      FROM

       person.contact

      FOR XML PATH('tr'),TYPE) AS NVARCHAR(MAX)),

      '</tr><tr>','</tr>

        <tr>') + '</table>

    '

SELECT  @Query 

Tables are much easier to read if one can apply subtle shades to the backgrounds or borders to delineate columns and rows. You can even do rather nice 'warp and weft' effects to make it easier for the eye to follow down a column or along a row. Additionally, any Excel user will know how important the column and row headers are to help people understand data in tables. If you generate an XHTML table from SQL Server, you don't get an option to apply different classes to different columns or rows. Why should you need to do so, when the way that a table is displayed is none of the business of the database.

We can leave the HTML structure as it is without assigning any classes. We just create a style sheet. Here is an example. I'm using bitmaps instead of flat background colors just because I prefer the slightly livelier effect.

/* do the basic style for the entire table */

table {

   border-collapse: collapse;

   border: 1px solid #3399FF;

   font: 10pt Verdana, Geneva, Arial, Helvetica, sans-serif;

   color: black;

}

/*attach the styles to the caption of the table */

table caption {

   font-weight: bold;

   background-image: url(fieldBack.bmp);

}

/*give every cell the same style of border */

table td, table th, table caption { border: 1px solid #eaeaea; }

/* make the first column (not header) blue */

table td:nth-child(1){ color: #00016c; }

/* apply styles to the third column only */

table td:nth-child(3){ font-variant: small-caps; }

/* apply styles to the odd headers */

table th:nth-child(odd) { background-image: url(headingback.bmp); }

/* apply styles to the even headers */

table tr th:nth-child(even) { background-image: url(headingCrossingback.bmp); }

     /* apply styles to the even rows */

table tr:nth-child(even) { background-image: url(fieldBack.bmp); }

/* apply styles to the odd colums of even rows */

table tr:nth-child(even) td:nth-child(odd){ background-image: url(fieldBackAlt.bmp); }

     /* apply styles to the odd rows */

table tr:nth-child(odd){ background-image: url(fieldBack.bmp); }

/* apply styles to the even colums of odd rows */

table tr:nth-child(odd) td:nth-child(even){ background-image: url(fieldBackAlt.bmp); }

 

And the HTML source of the table (truncated) looks like this

<table>

  <caption>AdventureWorks Customers</caption>

<tr><th>Employee Name</th><th>Phone</th><th>Email</th></tr>

<tr><td>Mr. Gustavo Achong</td><td>398-555-0132</td>

        <td>gustavo0@adventure-works.com</td></tr>

<tr><td>Ms. Catherine R.Abel</td>

        <td>747-555-0171</td><td>catherine0@adventure-works.com</td></tr>

<tr><td>Ms. Kim Abercrombie</td>

        <td>334-555-0137</td><td>kim2@adventure-works.com</td></tr>

<tr><td>Sr. Humberto Acevedo</td>

        <td>599-555-0127</td><td>humberto0@adventure-works.com</td></tr>

     <!-- and so on .....  -->

</table>

..and it should look a bit fancier...

AdventureWorks Customers
Employee Name Phone Email
Mr. Gustavo Achong 398-555-0132 gustavo0@adventure-works.com
Ms. Catherine R.Abel 747-555-0171 catherine0@adventure-works.com
Ms. Kim Abercrombie 334-555-0137 kim2@adventure-works.com
Sr. Humberto Acevedo 599-555-0127 humberto0@adventure-works.com
Sra. Pilar Ackerman 1 (11) 500 555-0132 pilar1@adventure-works.com
Ms. Frances B.Adams 991-555-0183 frances0@adventure-works.com
Ms. Margaret J.Smith 959-555-0151 margaret0@adventure-works.com
Ms. Carla J.Adams 107-555-0138 carla0@adventure-works.com
Mr. Jay Adams 158-555-0142 jay1@adventure-works.com
Mr. Ronald L.Adina 453-555-0165 ronald0@adventure-works.com
Mr. Samuel N.Agcaoili 554-555-0110 samuel0@adventure-works.com
Mr. James T.Aguilar 1 (11) 500 555-0198 james2@adventure-works.com
Mr. Robert E.Ahlering 678-555-0175 robert1@adventure-works.com
Mr. François Ferrier 571-555-0128 françois1@adventure-works.com
Ms. Kim Akers 440-555-0166 kim3@adventure-works.com
Ms. Lili J.Alameda 1 (11) 500 555-0150 lili0@adventure-works.com
Ms. Amy E.Alberts 727-555-0115 amy1@adventure-works.com
Ms. Anna A.Albright 197-555-0143 anna0@adventure-works.com
Mr. Milton J.Albury 492-555-0189 milton0@adventure-works.com

I've done all this with just the nth-child CSS Selector. However, there are others that can be used to select particular elements of 'naked' structures.  The Rosetta Stone and Cribsheet gives a much fuller list of selectors, pseudo-classes and pseudo-elements, particularly of attribute addressing (which doesn't help us as our tables haven't got attributes). Before you use them, check on the Quirks Mode site for compatibility with current browsers, and check on The W3.ORG site for the details, and plenty of examples of their use

CSS2 and CSS3  structural  pseudo-class and pseudo-element Selectors
Selector Function Example What Example does
* selector Selects all elements * {font: 9pt Arial, Helvetica, sans-serif;} Makes all elements have the specified font
> selector Selects direct children of an element div.listing > p{ margin: 0;
   font: 11pt "Courier New",Courier,monospace; }
Assign style to all paragraphs directly within div.listing
+ selector Selects the following sibling of an element h2 + p {margin-bottom: 10pt} make first paragraph after n H2 heading with a bottom margin of 10pt
[attr] selector Selects an element with a certain attribute or attribute value p[align=right] {float: right;border:
1px solid silver; text-align: left;
padding: 15px; width:300px; }
float any text with the attribute 'align="right"' to the right  in a box 300px wide
:before and :after  Insert content before or after an element p.quote:before { content: open-quote; }

p.quote:after { content: close-quote; }
put a quote before and after the start of any paragraph whose class is 'quote'\
:first-child and :last-child Select first and last children of an element table td:first-child{ font-variant: small-caps; }
table td:last-child{ font-variant: small-caps; }
make the first and last column  of the table render in small-caps.
:first-line and :first-letter : Select the first line or the first letter of an element p.start:first-letter
  { line-height: 100%; float: left;
     font-size: 280%; }
p.start:first-line { font-variant: small-caps; }

makes a large first letter, floated to the left, and puts the fist line in small-caps
~ selector Selects the general next sibling(s) of an element h3 ~ p
  {margin-left:40em}
give every paragraph following an H3 a margin of 40em
:first-of-type The first sibling element of its type  td:first-of-type { font-weight: bold; }
makes the first column in a table bold
:last-child the last sibling   td:last-child { font-variant: small-caps; } makes the last column text smallcaps
:last-of-type The last  sibling element of its type  td:last-of-type
  { font-variant: small-caps; }
makes the last column text smallcaps
:only-of-type The only child of its type  td:only-of-type {font-weight: normal; font-variant: normal;} make the font normal if there is only one column
:contains('text')  now withdrawn for some reason!
:empty Empty elements (without content) td:empty { background: silver; }
give a cell a silver background if it contains no text
:nth-child(an+b))  Selects elements according to a formula specifying that the  element has an+b-1 siblings before it in the document tree  tr:nth-child(odd) {background-color:gray;}
p:nth-child(4n+1) { color: navy; }
p:nth-child(4n+2) { color: green; }
 p:nth-child(4n+3) { color: maroon; }
p:nth-child(4n+4) { color: purple; }
make the odd rows of a table have a gray background
the next four examples alternate between four colours
:nth-last-child(an+b)) Selects elements according to a formula specifying that the  element has an+b-1 siblings after it in the document tree  tr:nth-last-child(-n+2) 
  {background-color:gray;}
The last two rows in the table should have a gray background
:nth-of-type (an+b))  Selects elements according to a formula specifying that the  element has an+b-1 siblings before it with the same name in the document tree  img:nth-of-type(2n+1) { float: right; }
img:nth-of-type(2n) { float: left; }
float alternating images in the same document level, left and right
:nth-last-of-type(an+b)) Selects elements according to a formula specifying that the  element has an+b-1 siblings after it with the same name in the document tree

 tr:nth-of-type(n+2):nth-last-of-type(n+2)
    {background-color:silver;}
make the odd rows of a table(Make the first and last row have a background of silver
       

Let's take a different example. Here is a PowerShell script. It is getting information about the SQL Server-related services that are running on a list of servers that I've supplied just to check that they are running OK. Whatever. The point is that I've once more got stuck with a table result that looks pretty difficult to format nicely.

# get the SQL Server service details from the list of servers and format them into an HTML table

Get-WmiObject -ComputerName 'PhilFtest.factorFactory.com','ltPhilF'    `

     -property '__Server,Caption, Description, Name, Status, Started, StartMode'   `

     -class Win32_Service `

     -filter "(NOT Name Like 'MSSQLServerADHelper%') AND (Name Like 'MSSQL%' OR Name Like 'SQLServer%')" `

| ConvertTo-HTML  -Property '__Server','Caption', 'Description', 'Name','Status', 'Started', 'StartMode' -fragment

You'll get an output somewhat like this (I've kept it short for demo purposes)

<table>

<colgroup>

<col/>

<col/>

<col/>

<col/>

<col/>

<col/>

<col/>

</colgroup>

<tr><th>__Server</th><th>Caption</th><th>Description</th> <th>Name</th><th>Status</th><th>Started</th><th>StartMode</th></tr>

<tr><td>PHILFTEST</td><td>MSSQL$SQL2000</td><td></td><td>MSSQL$SQL2000</td> <td>OK</td><td>True</td><td>Auto</td></tr>

<tr><td>PHILFTEST</td><td>SQL Server (SQL2005)</td><td>Provides storage, processing and controlled access of data and rapid transaction processing.</td><td>MSSQL$SQL2005</td><td>OK</td><td>True</td

><td>Auto</td></tr>

<tr><td>PHILFTEST</td><td>SQL Server (SQL2008)</td><td>Provides storage, processing and controlled access of data, and rapid transaction processing.</td><td>MSSQL$SQL2008</td><td>OK</td><td>True</t

d><td>Auto</td></tr>

<tr><td>LTPHILF</td><td>SQL Full-text Filter Daemon Launcher (MSSQLSERVER)</td><td>Service to launch full-text filter daemon process which will perform document filtering and word breaking for SQL

Server full-text search. Disabling this service will make full-text search features of SQL Server unavailable.</td><td>MSSQLFDLauncher</td><td>OK</td><td>False</td><td>Manual</td></tr>

<tr><td>LTPHILF</td><td>SQL Server (MSSQLSERVER)</td><td>Provides storage, processing and controlled access of data, and rapid transaction processing.</td><td>MSSQLSERVER</td><td>OK</td><td>False</

td><td>Manual</td></tr>

<tr><td>LTPHILF</td><td>SQL Server Agent (MSSQLSERVER)</td><td>Executes jobs, monitors SQL Server, fires alerts, and allows automation of some administrative tasks.</td><td>SQLSERVERAGENT</td><td>O

K</td><td>False</td><td>Manual</td></tr>

</table>

 

...but we can create something rather easier on the eye by defining some styles.

/* do the basic style for the entire table */

table {

       border-collapse: collapse;

       border: 2px solid #853a07;

       color: #452812;

       font: 10pt "Times New Roman", Times, serif;

}

 

/* give some sensible defaults just in case it is an old browser */

table td {

       border: 1px solid #c24704;

       vertical-align: top;

       background: #fdf5f2;

}

 

table th {

       border: 1px solid #fef7ef;

       padding: 8pt 2pt 5pt 2pt;

       color: white;

       font-weight: normal;

       vertical-align: top;

       background: #562507;

}

/* Now emphasise the first column right border */

table td:first-of-type {

       font-weight: bold;

       font-variant: small-caps;

       border-right: 2px solid #c24704;

}

/* and do a warp and weft effect */

table tr:nth-child(even) td:nth-child(odd){ background: #ffedd9; }

table tr:nth-child(even) td:nth-child(even){ background: #fcf5ef; }

table tr:nth-child(odd) td:nth-child(odd){ background: #ffe0bd; }

table tr:nth-child(odd) td:nth-child(even){ background: #f9e4d4; }

table th:nth-child(even){ background: #703009; }

 

that will give this, once the style has been applied to the table

__Server Caption Description Name Status Started StartMode
PHILFTEST MSSQL$SQL2000 MSSQL$SQL2000 OK True Auto
PHILFTEST SQL Server (SQL2005) Provides storage, processing and controlled access of data and rapid transaction processing. MSSQL$SQL2005 OK True Auto
PHILFTEST SQL Server (SQL2008) Provides storage, processing and controlled access of data, and rapid transaction processing. MSSQL$SQL2008 OK True Auto
LTPHILF SQL Full-text Filter Daemon Launcher (MSSQLSERVER) Service to launch full-text filter daemon process which will perform document filtering and word breaking for SQL Server full-text search. Disabling this service will make full-text search features of SQL Server unavailable. MSSQLFDLauncher OK False Manual
LTPHILF SQL Server (MSSQLSERVER) Provides storage, processing and controlled access of data, and rapid transaction processing. MSSQLSERVER OK False Manual
LTPHILF SQL Server Agent (MSSQLSERVER) Executes jobs, monitors SQL Server, fires alerts, and allows automation of some administrative tasks. SQLSERVERAGENT O K False Manual

Putting it all together

Curiously, after years of happily using Internet Explorer as a simple way of displaying data as part of a scripting process, I initially  fell foul of using Internet Explorer 9 to display HTML5 and CSS 2/CSS3. Here is the script that I currently use to automatically display this, and any other grid of data in PowerShell. The principle is the same for every other scripting language.

#firstly, let's get the in-line stylesheet in place, and the rest of the header for the HTML Document.

# as we want to render just the table we take out margins. (body {margin: 0 0 0 0;})

$head= @'

<title>SQL Server Services</title>

<style type="text/css">

/* do the basic style for the entire table */

     body {margin: 0 0 0 0;}

     table  {

      border-collapse: collapse;

      border: 2px solid #853a07 ;

      font-size: 10pt ;

      color: #452812;

    font-family: "Times New Roman", Times, serif;

    }

       /* give some sensible defaults just in case it is an old browser */

     table td {border: 1px solid #c24704;  vertical-align: top; background-color: #fdf5f2;}

     table th {border: 1px solid #fef7ef; padding: 8pt 2pt 5pt 2pt; color:white; font-weight: normal;  vertical-align: top; background-color: #562507;}

     table td:first-of-type { font-weight:bold; font-variant: small-caps; border-right: 2px solid #c24704;}

     table tr:nth-child(even) td:nth-child(odd){

      background-color: #ffedd9;

    }

     table tr:nth-child(even) td:nth-child(even){

      background-color: #fcf5ef;

    }

     table tr:nth-child(odd) td:nth-child(odd){

      background-color: #ffe0bd;

    }

     table tr:nth-child(odd) td:nth-child(even){

      background-color: #f9e4d4;

    }

     table th:nth-child(even){

      background-color: #703009;

    }

</style>

</head>

'@

# get the SQL Server service details from the list of servers and format them into an HTML document

$content=Get-WmiObject -ComputerName 'PhilFactor.com','ltPhilF'    `

     -property '__Server,Caption, Description, Name, Status, Started, StartMode'   `

     -class Win32_Service `

     -filter "(NOT Name Like 'MSSQLServerADHelper%') AND (Name Like 'MSSQL%' OR Name Like 'SQLServer%')" `

| ConvertTo-HTML  -Property '__Server','Caption', 'Description', 'Name','Status', 'Started', 'StartMode' `

    -head $head

 

$exploder = new-object -comobject "InternetExplorer.Application"

$exploder.visible = $true

$exploder.width=640 # width of the table.

$exploder.menubar = $false # kick out the menu bar

$exploder.toolbar = $false # and the toolbar

$exploder.statusbar = $false # who wants a status bar

$exploder.resizable = $true  # but you may want this

$exploder.AddressBar=$false #

$exploder.navigate2('about:offlineinformation') # because it forces the creation of a document which defaults to

# IE9 standards mode (about:blank is in 'compatibility mode' by default!)

While ($exploder.Busy) {} #wait for the docuent to load

$exploder.document.IHTMLDocument2_write($content) #and put in our content instead

If you can't see CSS2-3/HTML5  views of a page.

If you can't see all those CSS2-3/HTML5  effects in a page in IE8 or IE9, it probably means you're in 'compatibility mode'.  If your browser window has a thin gray border, shucks, you're in Compatibility mode.

The developers of Internet Explorer were faced with a change of direction towards HTML/CSS standards-compliance after years of attempting an ultimately futile policy of creating their own de-facto browser standard. In order to create a browser that could still render websites that were written to the Internet Explorer standard,  with IE8 and IE9, they have had to introduce a notion of 'compatibility mode' which is extraordinarily elaborate and even involves the maintenance of a register of  the 'compatibility' of various websites. The intricacies of this mechanism would wear out the patience of even the keenest reader so I'll say little more other than to say that one can force the browser to stop fleeing standards-mode like a frightened rabbit by ...

  • selecting, from the menu, TOOLS -> Compatibility View Settings, and unchecking 'display intranet sites in compatibility view' (and, if necessary,  'display all websites in compatibility view' ).
  • From the menu, Tools -> Internet Options. Click on  the advanced tab, Look for the browsing section, and in there find 'automatically recover from page layout errors with Compatibility view'. Unclick it.
  • If all else fails... Hit F12 in order to get into the 'developer pane'. Here, you will see the last two menu item 'Browser Mode and 'Document Mode'. Make sure that these are set to IE9.

I know of no way in scripting to force IE9 to read a dynamic page in standards mode, other than by using the HTML5  doctype (<!DOCTYPE HTML>) in the page you write to the instance. In the script above, I've used guile rather than science.

Conclusions

The use of the CSS structural pseudo-class and pseudo-elements hold out the hope that we cen do what we want with the rendering of HTML structures without having to add a lot of classes to the elements, but instead just doing it by specifying their position in the DOM. I have to admit that I miss the suddenly-withdrawn :contains pseudo class which for the first time allows us to specify an element by its content. We hope that wider counsels prevail. For those of us who are having to render such XHTML fragments as tables and lists, generated from PowerShell and SQL, these extensions to CSS are a real boon.

Phil Factor

Author profile:

Phil Factor (real name withheld to protect the guilty), aka Database Mole, has 30 years of experience with database-intensive applications. Despite having once been shouted at by a furious Bill Gates at an exhibition in the early 1980s, he has remained resolutely anonymous throughout his career. See also :

Google + To translate this article...

Search for other articles by Phil Factor

Rate this article:   Avg rating: from a total of 20 votes.


Poor

OK

Good

Great

Must read
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.


Subject: Visualization rocks!
Posted by: msorens (view profile)
Posted on: Monday, August 15, 2011 at 2:58 PM
Message: "I love what you've done with the place!" ... umm, I mean, with the *data*. Data is nice, but data that-tells-its-story-at-a-glance is better. Your recipe is a great general-purpose technique for moving from the former to the latter.

Subject: Table of Pseudo-classes
Posted by: Phil Factor (view profile)
Posted on: Monday, August 22, 2011 at 4:18 AM
Message: I forgot to mention that the table of Pseudo-classes above is formatted using only pseudo-classes. It seemed somehow appropriate!

Subject: How many see this
Posted by: Mike Gale (view profile)
Posted on: Monday, August 22, 2011 at 3:42 PM
Message: It's worth getting a handle on what part of your audience will see this.

My tests indicate that IE8 doesn't do it.

On some web sites you might get 60% IE users of which say 70% are IE8 or earlier. In that case about 40% of your audience won't see the "pure structural-pseudo" styling.

Other web sites are going to be more accommodating.

Subject: Re: How many see this
Posted by: Andrew Clarke (view profile)
Posted on: Tuesday, August 23, 2011 at 5:47 AM
Message: (Ed:)
Exactly two thirds of our visitors on Monday would have been able to see the CSS. As Phil's article was about using the pseudo-classes, it seemed appropriate to make it a live demonstration. If you are interested enough in CSS3 to read the article, it is likely that you will have downloaded a free browser capable of using at least CSS2!
We don't know what you mean by 'Other web sites are going to be more accommodating.' so it is difficult to comment. I agree that we could have had images that could be viewed if you have an old browser, but it is difficult to know where to stop in making compromises. IE6?

Subject: Error
Posted by: Anonymous (not signed in)
Posted on: Wednesday, August 24, 2011 at 10:02 AM
Message: I get an error on the following stmt:
$exploder.document.IHTMLDocument2_write($content)

This the error :
Exception calling "IHTMLDocument2_write" with "1" argument(s): "Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TY
PEMISMATCH))"
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

 

Top Rated

Acceptance Testing with FitNesse: Multiplicities and Comparisons
 FitNesse is one of the most popular tools for unit testing since it is designed with a Wiki-style... Read more...

Acceptance Testing with FitNesse: Symbols, Variables and Code-behind Styles
 Although FitNesse can be used as a generic automated testing tool for both applications and databases,... Read more...

Acceptance Testing with FitNesse: Documentation and Infrastructure
 FitNesse is a popular general-purpose wiki-based framework for writing acceptance tests for software... Read more...

TortoiseSVN and Subversion Cookbook Part 11: Subversion and Oracle
 It is only recently that the tools have existed to make source-control easy for database developers.... Read more...

TortoiseSVN and Subversion Cookbook Part 10: Extending the reach of Subversion
 Subversion provides a good way of source-controlling a database, but many operations are best done from... Read more...

Most Viewed

A Complete URL Rewriting Solution for ASP.NET 2.0
 Ever wondered whether it's possible to create neater URLS, free of bulky Query String parameters?... Read more...

Visual Studio Setup - projects and custom actions
 This article describes the kinds of custom actions that can be used in your Visual Studio setup project. Read more...

.NET Application Architecture: the Data Access Layer
 Find out how to design a robust data access layer for your .NET applications. Read more...

Calling Cross Domain Web Services in AJAX
 The latest craze for mashups involves making cross-domain calls to Web Services from APIs made publicly... Read more...

Web Parts in ASP.NET 2.0
 Most Web Parts implementations allow users to create a single portal page where they can personalize... Read more...

Why Join

Over 400,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.