BookmarkSubscribeRSS Feed
Fluorite | Level 6

Hi - So I've successfully been able to use a CSS file stored on the SAS server to modify and create a standard CSS file for our company. The problem I'm seeing is that I seem to have to use "class" names to modify the style instead of what I want to do of just referring to a "tag" name generically. Has anyone else been able to simply reference "tag" names in their external css file and have the style take place on the Stored Process Web Server UI created?


As info, for a simple reference to a SAS CSS tip sheet this is what I've been referencing:


Also I've read up on this page the Base SAS involving ODS and CSS:


Here is a simple version of my code:


data _null_;  
file _webout;  
	put '<HTML>';
	put '<BODY>'; 
	put '<HEADER class="pageheader">';
	put '<TABLE>';
	put '<tr>';
	put '<td>';
	put '<img class="logo" src="" alt="image">';
	put '</td>';
	put '<td>';
	put '<div class="divcenter">Report</div>';
	put '</td>';
	put '</tr>';
	put '</TABLE>';
	put '</HEADER>';
	put '<select> /
		  '<option value="company1">company1</option>' /
		  '<option value="company2">company2</option>' /
		  '<option value="company3">company3</option>' /
		  '<option value="company4">company4</option>' /
	put '</BODY>';
	put '</HTML>';

run; PROC SQL; CREATE TABLE lib.company_data AS Select Distinct COMPANY_NBR From COMPANY ; QUIT; /*the output delivery of data streaming to file=_webout*/ ods html5 file=_webout cssstyle="/sasdata/IT/app/company_sas.css"; Proc Print lib.company_data noobs; run; ods html5 close;

Here is a simple portion of my css in which I want to style the "select" tag:


select {
	border: 1px groove lightgray;
	border-right-width: 3px;
	border-bottom-width: 3px;
	height: 25px;

I don't see any update in the select tag styling writing the css by the "tag" name. Alternatively, I specify a "class" for the "select" tag and then in my css I just call that class like so:


.select {
	border: 1px groove lightgray;
	border-right-width: 3px;
	border-bottom-width: 3px;
	height: 25px;

Why does referencing defined classes work but the "tag" css selector does not work?


I created the stored process using SAS Enterprise Guide v7.11

Lapis Lazuli | Level 10




Off the top of my head, tag css selectors work with an element's `id` attribute, whereas class selectors work with the `class`. 


I'd have to have a look at your generated html to debug it any further - this seems like something you should analyse using Chrome DevTools or similar.


FWIW it's been a while since we've done this, but I think that where we've overridden ODS CSS (using this same method), we've only used class selectors. 



Fluorite | Level 6

Right id works with #id and class works with .class... that's basic CSS and I have been able to specify the class name in my CSS and see the styling changes... but then in my HTML I have to create a class on every tag that the CSS applies to. That functionality is perfectly okay and should work that way (id to id and class to class) but what if I want all form td tags to style a certain way? I need to add a class to the form and a class to the td tag within the form possibly. So many class-based styles...


In my case this is an enterprise CSS file in which there are multiple SAS users creating Stored Process Web Applications. We want a standard style to apply to the web pages and if all users have to know the class names they need to manually apply to each tag in each case you don't have a good standard.


Do you see the maintenance problem here? I want to apply global styles by tag CSS selectors. Why does it not work to only specify the tag name in the external CSS file and have the style applied to all tags on the page matching the CSS selector?

Lapis Lazuli | Level 10



I now think I understand what you're talking about, and remember hitting the same thing a few years ago - that the CSS injected with the CSSSTYLE option had some ODS-specific expectations/limitations as it processed it before outputting. If your requirement is for  web-only output, the following alternative way of injecting CSS into your ODS will work better as it just loads it explicitly into the page source and lets the browser interpret it natively:




ods html5 file=_webout stylesheet=(URL="/ht/test.css");
* where /ht/test.css is a URI on your webserver ;



Keep in mind that this displaces the original CSS that would have been injected as a <style> tag at the top of your ODS output, so you'll want to grab that from an original report and use it as a template that you then modify. However this basic stylesheet= option should give you expected behaviour precisely as it replaces that <style> segment with a <link href="/ht/test.css" rel="stylesheet"/> element in the head.


I've just done some testing to make sure I'm right on this, including an example for your selection methods question. First, the standard SAS output:



ods html5 file=_webout;
	Proc Print data=sashelp.class;    
ods html5 close;


obviously produces this:standardods.jpg


I created the following CSS file and saved it under /pub/ht/test.css, which is exposed via the web as /ht/test.css:




Injecting the CSS into the ODS with your cssstyle method produces this:




Again this is because ODS I guess tries to 'translate' the generic CSS into ODS-compatible CSS, picking out the properties it knows about. If I view the page source it actually comes out as the following:



td, th { text-align: left; padding: 3px 6px; vertical-align: top }

/* other bits */

.table { background-color: #f0f0f0; border: 0 solid #dddddd; border-collapse: separate; border-spacing: 0; font-family: "Open Sans"; font-size: small; font-style: normal; font-weight: normal; }

Using this method, the td, tm bit gets ignored and ODS does its own thing (like you say). This seems to be the case with a lot of other boilerplate CSS that is generated inside that <style> tag. However, with the .table selector it actually does do stuff; it tries to convert as much of it as possible and inject it, but still only includes the properties it knows about, as per above. 



Now, using the third method, stylesheet=(URL="/ht/test.css"), the output looks like this:




This is because the CSS is being interpreted by the browser directly, and I assume is the behaviour you were after / expecting. As long as you're not looking for your CSS to be portable across non-web versions of the STP reports (ie. in Enterprise Guide), then this should do the trick. It seems that neither method tries to override existing CSS properties, instead just displacing the entire style spec with whatever you give it. The cssstyle option, for example, generates a .toc tag for the title that is hidden (display:none), whereas the stylesheet= option just displaces all CSS that ODS would have generated. This is why you'll need to also make sure your enterprise-wide SAS CSS file covers all of the styling that would have been included by the original ODS generated style tag.


Hope that answers your question.





Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.

If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website. 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Get the $99 certification deal.jpg



Back in the Classroom!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 2 in conversation