FOCUS AREAS

SAS Output Delivery System (ODS) documentation

Base SAS

Cascading Style Sheets and ODS


Introduction to CSS

While browser manufacturers were creating new, proprietary, nonstandard tags, the World Wide Web Consortium (W3C) went to work developing a standard that keeps HTML universal while allowing designers more control over the presentation of their pages. The result of this effort is the cascading style sheet (CSS). The W3C has released two recommendations so far, CSS level 1 and level 2 (CSS1 and CSS2), and is currently working on level 3.

A CSS is a simple mechanism for adding styles such as fonts, colors, margins, etc., to an HTML file. When a browser encounters an element for which a style is provided, the browser renders that element according to the CSS rather than using the default.

Why Use a CSS?

The advantages of using a CSS include the following:

The downside to using cascading style sheets is that no browser supports them completely. IE5 supports most of CSS1 and CSS2, with Netscape falling far behind. A very helpful Web site, http://www.webreview.com/style/css1/charts/mastergrid.shtml, shows which parts of CSS are supported by different browsers. The URL for the World Wide Web Consortium is http://www.w3.org/TR/REC-CSS2/.

CSS Terminology

This document does not cover any specifics about the syntax of a CSS. However, the following terms are important.

external CSS
a separate CSS file

embedded CSS
an internal part of the HTML file, contained in a <style> block, usually in the <head> section

inline CSS
a part of the HTML file, contained in a STYLE="" attribute in an HTML tag.

The STYLESHEET Defaults

When you specify the STYLESHEET option, by default the CSS classes are the same as the style elements in PROC TEMPLATE. See the body file's default CSS, whose classes mimic the style elements in styles.default. The following table matches the PROC TEMPLATE style elements to the CSS properties and shows how they affect the HTML output. See also SAS Note 24065 about viewing the style settings in your template.

Class selectorTagWhat It Is Responsible For
.ContentTitle <SPAN> The title in the Table of Contents
.NoteContent<TD> The line statement with PROC REPORT
.Output<TABLE> Attributes on the table tag
.Graph <IMG> The images or graphs
.ProcTitle<TD> The procedure name on the body file
.Data<TD> The cell values
TD<TD> All numeric or right-justified data
.Table<TABLE> The table
.ContentFolder<UL> Overall items in the table of contents
.Byline<TD> The BY values
.PagesProcLabel<LI> The procedure name in the table of pages
.Header<TD> The column headers
.ContentProcLabel<LI>The procedure name when the ODS PROCLABEL statement has been used
.PagesTitle<SPAN> The title on the table of pages
.PagesProcName<LI> The procedure name on the table of pages
.ContentItem<A><DT><LI> The leaf or item in the table of contents; this is the hyperlink that you click
.Body<BODY> The body file, which renders such things as the background color and the margins
.DataEmphasis<TD> The summary line with PROC REPORT
.ContentProcName<LI> The procedure name in the table of contents
.PagesItem<A><DT><LI> The leaf or node in the table of contents; this is the link that you click
.RowHeader<TD> The row headers
.SystemTitle<TD> The SAS System titles
.SystemFooter<TD> The SAS footnotes

The STYLE= Option

ODS HTML takes style attributes from the default template STYLES.DEFAULT unless you specify a different style template with the STYLE= option. The following example code specifies a template STYLES.TEST that had been previously generated by PROC TEMPLATE.

   ods html file='temp.html' style=styles.test;

Choose Your CSS: Embedded, External, Existing, Inline, or No Thanks

No STYLESHEET Means No CSS

The following example code does not contain the STYLESHEET option.

   ods html file='temp.html';
   proc print data=sashelp.class;
   run;
   ods html close;

Style attributes such as fonts, colors, and alignment that are specified by the style template (either the default template or one that you've created with PROC TEMPLATE) are included in the output file via traditional HTML attributes and tags. That is, the formatting and data are stored together. For example, you might see <font> tags or a valign="top" attribute in the HTML code. No CSS is generated.

Generating an Embedded CSS

The following code uses the STYLESHEET option but does not specify an output name for the CSS.
   ods html file='temp.html' stylesheet;

A CSS is generated and is embedded in the HTML file within a <style> block in the <head> section.

You can also use the HEADTEXT= option to add a <style> block to your HTML file. In the following example code, the new style definition affects the font size of all content tagged by <td>. Recall that ODS puts most of the output in <td> tags, so everything is affected here except the PREHTML= text, because it is tagged by <p>.

   ods html file='temp.html'
       headtext='<style> td {font-size=1%}</style>'
       style=styles.minimal;

   proc print data=sashelp.class
        style(table)={prehtml="<p>this is a test</p>}";
   run;

   ods html close;

Generating an External CSS

The following code uses the STYLESHEET= option, specifying an output name for the CSS.

   ods html file='temp.html' stylesheet="temp.css";

A CSS is generated and is output in a separate, external file. In this example, the external file is named temp.css.

Using an Existing CSS

The following code uses the STYLESHEET= option, specifying the name of an existing CSS in the URL= suboption.

   ods html file='temp.html' stylesheet=(URL="mycss.css");

A CSS is not generated. See SAS Note 23628 for some important details.

Caution: Be sure to use the URL= suboption. Specifying your existing CSS with the STYLESHEET= option rather than with the URL= suboption overwrites your CSS with the default.

Adding an Inline Property

See the topic The HTMLSTYLE= Attribute for information about adding inline CSS properties.

Order of Precedence

When you specify an existing CSS in the URL= suboption, its style properties override everything in the specified or default style template. The only style properties that have higher precedence are those specified in the HTMLSTYLE= attribute of PROC TEMPLATE, because they are inline styles.

If you are generating an embedded or external CSS, then style definitions that you specify locally in a PROC TEMPLATE override those taken from the default CSS.

Here is an example. The below code creates a stylesheet named temp.css with the defaults. Then PROC TEMPLATE creates a style template named styles.test that changes the foreground of the cell values to red. However, because the ODS HTML statement specfies an existing CSS style sheet, the styles.test template is ignored. If we remove the URL=, which means that we are now creating a CSS on the fly, then this information would get passed to the CSS style sheet and the cell values would be red.

   ods stylesheet="temp.css";

   proc template;
     define style styles.test;
       parent=styles.default;
       style data from data /
             foreground=red;
     end;
   run;

   ods html file='temp.html' stylesheet=(url="temp.css") style=styles.test;

   proc print data=sashelp.class;
   run;

   ods html close;

Modifying the CSS

Whether or not you are using the STYLESHEET= or STYLE= options, you can still modify the style properties dynamically. You can issue a PROC TEMPLATE with the STYLE statement and any of the attributes HTMLCLASS=, HTMLID=, or HTMLSTYLE= to modify the classes that are taken from a template or from an existing CSS. No changes are made to the template or to an existing CSS.

The HTMLCLASS= Attribute

Use the HTMLCLASS= attribute in order to specify a CSS class or selector other than the default. The following changes are made to the HTML and CSS files:

HTMLCLASS= is helpful when you are using an existing CSS, because matching your CSS selectors with the correct style elements can be tricky. See SAS Note 23628 for an example of this usage.

You can also use HTMLCLASS= when you are not using an existing CSS. For example, you might want to specify a single class for multiple style elements and thus be able to make a global formatting change very easily. The following example code assigns the Data class to the table headers. Then if you choose to change the style definition for Data, you change the headers as well.

   style Header from Header /
      htmlclass='Data';

The following example code produces a more obvious effect. For the style element ContentItem, the Table class is applied. Because the Table class includes the property BORDER, a border is placed around the table of contents entries in the output. View output.

proc template;
   define style styles.test;
      parent=styles.default;
          style contentitem from contentitem /
                htmlclass='Table';
      end;
run;

ods html body='bod.html'
         contents='cont.html'
         frame='frame.html'
         stylesheet
         style=styles.test;

proc print data=sasuser.class;
run;

ods html close;

The HTMLID= Attribute

The HTMLID attribute allows you to create a unique identifier for each style element. This is used mainly by JavaScript.

The HTMLSTYLE= Attribute

Use the HTMLSTYLE= attribute to define a style locally in a tag (that is, an inline style) instead of embedded in a <style> block or externally in a CSS file. This attribute is misspelled in the Version 8 documentation for ODS. The correct spelling contains no underscore.

The following example code inserts style="color:red" as an inline style in the TD tags:

   proc template;
     define style styles.test;
       parent=styles.default;
       style data from data /
             htmlstyle="color:red";
     end;
   run;

Advanced Topics

Specifying Dimensions, Orientation, and Margins with the @page Rule

According to the W3C's CSS2 page model, a document is formatted within a rectangular area called the page box. The page box consists of a page area and a margin area. The @page rule can specify dimensions, orientation (landscape or portrait), and margins of the page box. Most popular browsers do not yet support the @page rule, but when they do, here's how you'll be able to use it.

The dimensions of the page box are set by the SIZE property. The size of the page box can be fixed or scalable. A scalable page size, which fits the available paper size, allows the most optimal use of the printed page. For further information, see the section Paged Media of the CSS2 Specification.

Values for the SIZE property are as follows:

length
specifies a literal measure.
AUTO
sets the page box to the size and the orientation of the target sheet.
LANDSCAPE
overrides the orientation, and the longer sides are horizontal.
PORTRAIT
overrides the orientation, and the shorter sides are portrait.
INHERIT
takes the same value as the parent.

Here are some examples of usage. The first example sets the page box size to 8.5 X 11 inches with a 2cm margin on all sides between the page box edge and the page area.

   @page {size:8.5in; margin: 2cm }
   @page {size:landscape; margin:5%}
   @page {size:auto;margin:5%}

Using the @media Rule for a Different Layout in Print than in the Browser

The @media rule is more accepted by popular browsers than the @page rule is. Among the @media rule's properties are PRINT and SCREEN. Using the @media rule with the PRINT or SCREEN property allows you apply a different layout for the printed output than for the onscreen viewable output. One application of this rule is for printing a wide page without truncation. When you view a wide page online, you can scroll right and left. However, when you print the wide page, there is no way to scroll and the page is truncated. With the @media rule, you can specify a smaller font size for printing so that a wide table fits on a page, and you can keep a normal size for viewing online in the browser. Below is an example of using the @Media rule just for the printed version of the output. To see the difference without actually printing the output, run the following code, then change the PRINT to SCREEN and run it again.

    ods html body='temp.html'
    headtext='<style type="text/css">@media print {font {font-size:66%}
              body{background:white}
              table {background:black}}</style>';

    proc print data=sashelp.class;
    run;

    ods html close;
 

Creating Page Breaks In HTML

As of Netscape 6 and IE 4, the CSS properties page-break-after and page-break-before provide page breaks for HTML files. In the HTML destination of ODS, the page-break-after:always definition is the default after each table or graph, and it is specified by the PAGEBREAKHTML= attribute in the style element Body. When you view an HTML output file in a browser, you see a horizontal rule marking each page break. When you print the file, a new page starts after every table or graph.

Remember, however, that the World Wide Web was conceived to be viewed onscreen, and that's still true today. Printed documents vary greatly from browser to browser. If you want more control over page breaks, or if you need to be compatible with browsers that do not support the page break properties, consider using a paper-based file format like Adobe Acrobat PDF. In ODS, the PDF destination is experimental in Release 8.1 and production in Release 8.2. (PostScript and PCL output are available beginning with Version 7.)

The following code, part of the styles.default style template, implements the page break.

"pagebreakline"=%nrstr(<p> style="page-break-after:always" </p>);

 style html
   "Common HTML text used in the default style" /
   'expandAll' = "<SPAN onClick=""if(msie4==1)expandAll()"">"
   'posthtml flyover line' = "</SPAN><HR size=3>"
   'prehtml flyover line' = "<SPAN><HR size=3>"
   'prehtml flyover bullet' = %nrstr("<SPAN><b>·</b>")
   'posthtml flyover' = "</SPAN>"
   'prehtml flyover' = "<SPAN>"
   'break' = "<br>"
   'Line' = "<HR size=3>"
   'PageBreakLine' =
  %nrstr("<p style=""page-break-after: always;""> </p><HR size=3>" );

Helpful URLs

http://www.webreview.com/style/css1/charts/mastergrid.shtml

http://www.w3.org/TR/REC-CSS2/