Recently, I had a need to specify style sheets for different media types: one for All media types (i.e. media=””) and a one with print specific styles (i.e. media=”print”). By definition style sheets cascade so, for my purposes I needed to place the print style sheet after the all style sheets.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.resources>
<xp:styleSheet
href="/all.css"></xp:styleSheet>
<xp:styleSheet
href="/grid.css"></xp:styleSheet>
<xp:styleSheet
href="/quirks.css"></xp:styleSheet>
<xp:styleSheet
href="/overrides.css"></xp:styleSheet>
<xp:styleSheet
media="print"
href="/print-only.css"></xp:styleSheet>
</xp:this.resources>
</xp:view>
All I needed to do was to apply the template to the application on the test server, quickly test it and then deploy it – or so I thought.
When I looked at the code in Firebug, I saw that the print-only.css style sheet was listed before the runtime optimised all style sheets, thus breaking the cascade as I had defined it.
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/print-only.css" media="print">
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/xsp/.ibmmodres/.css/all.css&grid.css&quirks.css&overrides.css">
</head>
After a bit of investigation, it seems that the runtime optimisation of style sheets was paying attention to the media value and rightly excluding the print-only style sheet from the aggregated style sheets. This had caused the link for the optimised style sheets to be written after the print-only style sheet.
The Solution.
In my case, only one of the style sheets included in the optimised sheets had styles that were overruled by the print-only style sheet so, for that sheet I specified the media value as “all” and rebuilt the application and all was well.
This xpage snippet
<xp:styleSheet
href="/quirks.css"></xp:styleSheet>
<xp:styleSheet
media="all"
href="/overrides.css"></xp:styleSheet>
<xp:styleSheet
media="print"
href="/print-only.css">
gives
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/overrides.css" media="all">
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/print-only.css" media="print">
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/xsp/.ibmmodres/.css/all.css&grid.css&quirks.css">
</head>
Whilst this is a solution, it does mean that I now have three http requests for style sheets where fewer would be better. I then went a little further and thought that if I specified media=”all” for all of the other style sheets, the optimisation would aggregate all of the “all” sheets together as one, but this doesn’t seem to be the case. When I did that, I got:
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/all.css" media="all">
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/grid.css" media="all">
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/quirks.css" media="all">
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/overrides.css" media="all">
<link rel="stylesheet" type="text/css" href="/RobsWorldDemo.nsf/print-only.css" media="print">
</head>
This effectively means that if a media type is specified, then that style sheet is excluded from runtime optimisation. If anyone can explain more on this, I would be happy to hear from you.