I'm looking at the style htmlBLUE. When I study the STYLE and CLASS keywords in its parent styles, both and Statistical and Default, I find definitions using both keywords, STYLE and CLASS, with the same style-element-name, and style attribute specifications with identical identifiers.
I'm curious to know the reason, because in the context of STYLE color and CLASS color it seems that they are defining the same thing, yet the parent styles have different entries for each of these keywords. What, if any, is inherited? Are they the same, and therefore each overwrite one another?
Hi: (long post warning)
Using link1 and link2 are not good examples because if you're using the browser, the link colors are only visible until you click on the link and then typically, the color changes to the browser default for a visited link. Let's pick something else. How about PROCTITLEFG, as shown below:
PROCTITLEFG controls the color of "The FREQ Procedure", "The MEANS Procedure", "The GLM Procedure".
Let's call STYLES.DEFAULT the "grandparent" template of HTMLBLUE and STYLES.STATISTICAL the "parent" of HTMLBLUE (because HTMLBLUE inherits directly from STATISTICAL in a PARENT statement and STATISTICAL inherits from DEFAULT in a PARENT statement).
This paper by Kevin Smith https://support.sas.com/resources/papers/proceedings/proceedings/sugi31/053-31.pdf has the best explanation (pages 4/5) of the difference between STYLE with FROM and CLASS. (The best because Kevin worked on the upgrade of the template inner workings with SAS 9.2 and he had the best knowledge of how it worked.)
Essentially,
define STYLE xxx from _self_ /
is the same as
define CLASS xxx/
CLASS COLORS in HTMLBLUE is changing the COLORS style element in the parent template STATISTICAL (the parent template) and because the change was done in a CLASS statement only the attributes listed are changing, the rest are from STATISTICAL.
I tend to use DEFINE CLASS because I always want to overwrite or change the style attributes from the parent template. The lesson I had drilled into me when I was learning templates was to always use CLASS or pick the right FROM. Let's start with examples of using STYLE with FROM vs CLASS just changing PROCTITLEFG and this time, I'll use HTMLBLUE as the parent for each of my new templates..
Example 1:
Example 2:
Example 3:
What happens if I just use STYLE without a FROM? This is where inheritance gets wonky. All of my above templates had either an explicit or an implied FROM to control inheritance. Let's look at Example 4:
So, OK, PROCTITLEFG is fine, it is the right color. But why is the title black? I didn't use STYLE with a FROM or a CLASS statement. So none of the overrides in HTMLBLUE were used. Instead, it was as though the ONLY change I wanted to make in my new template was for PROCTITLEFG and all the rest of the color values came from STATISTICAL, which has black for the SystemTitle.
So now, lets go back to using CLASS and see what happens to SystemTitle and what color it is in the final output if I only change the size but not the color -- what color will it be???
Now, SystemTitle gets the HTMLBLUE color because all the HTMLBLUE colors are intact because I used CLASS. When the TITLE statement is getting style added, the color is used from HTMLBLUE, not STATISTICAL.
The template documentation used to have a long discussion on FROM and inheritance. I find that if I stick with CLASS, then inheritance works as I expect.
Hope this helps,
Cynthia
Basically anything not explicitly listed is inherited from the parent. The application of values is the "most recently defined", i.e. if in the current definition then that is used, if defined in the parent then that value is used, if not defined in the parent but in the parent's parent then the "grandparent" property is used.
If a later style has a definition then that is one used (unless replaced in a child)
I could make a child of Styles.Htmlblue that changes a single value of the Class colors such as
class colors/ 'link2'= pink;
and any of the other colors not listed inherit from the parent(s).
ok,
SO in your context
if your parent has a STYLE and a CLASS definition, each called colors, each containing 'link2' but the two 'link2' values are different.
proc template;
/*…*/
class colors/ /*…*/ 'link2'= orange /*…*/ ;
style colors/ /*…*/ 'link2'= blue /*…*/ ;
end;
run;
now your style that inherits from the above style
proc template;
/*…*/
class colors from colors / 'link2'= red ;
style colors from colors / 'link2'= pink;
end;
run;
what is benefit of using CLASS and/or STYLE?
Let me be more descriptive...
...in your context
if your parent has a STYLE and a CLASS definition, each called colors, each containing 'link2' but the two 'link2' values are different.
proc template;
define style Styles.Uno;
class colors/ /*...*/ 'link2'= orange /*...*/ ;
end;
run;
proc template;
define style Styles.Dos;
parent = styles.Uno;
style colors/ /*…*/ 'link2'= blue /*…*/ ;
end;
run;
now your style that inherits from the style "Dos"
proc template;
define style Styles.Tres;
parent = styles.Dos;
class colors from colors / 'link2'= red ;
style colors from colors / 'link2'= pink;
end;
run;
"What does it mean?" What is benefit of using CLASS and/or STYLE in Uno, Dos, or Tres?
Hi: (long post warning)
Using link1 and link2 are not good examples because if you're using the browser, the link colors are only visible until you click on the link and then typically, the color changes to the browser default for a visited link. Let's pick something else. How about PROCTITLEFG, as shown below:
PROCTITLEFG controls the color of "The FREQ Procedure", "The MEANS Procedure", "The GLM Procedure".
Let's call STYLES.DEFAULT the "grandparent" template of HTMLBLUE and STYLES.STATISTICAL the "parent" of HTMLBLUE (because HTMLBLUE inherits directly from STATISTICAL in a PARENT statement and STATISTICAL inherits from DEFAULT in a PARENT statement).
This paper by Kevin Smith https://support.sas.com/resources/papers/proceedings/proceedings/sugi31/053-31.pdf has the best explanation (pages 4/5) of the difference between STYLE with FROM and CLASS. (The best because Kevin worked on the upgrade of the template inner workings with SAS 9.2 and he had the best knowledge of how it worked.)
Essentially,
define STYLE xxx from _self_ /
is the same as
define CLASS xxx/
CLASS COLORS in HTMLBLUE is changing the COLORS style element in the parent template STATISTICAL (the parent template) and because the change was done in a CLASS statement only the attributes listed are changing, the rest are from STATISTICAL.
I tend to use DEFINE CLASS because I always want to overwrite or change the style attributes from the parent template. The lesson I had drilled into me when I was learning templates was to always use CLASS or pick the right FROM. Let's start with examples of using STYLE with FROM vs CLASS just changing PROCTITLEFG and this time, I'll use HTMLBLUE as the parent for each of my new templates..
Example 1:
Example 2:
Example 3:
What happens if I just use STYLE without a FROM? This is where inheritance gets wonky. All of my above templates had either an explicit or an implied FROM to control inheritance. Let's look at Example 4:
So, OK, PROCTITLEFG is fine, it is the right color. But why is the title black? I didn't use STYLE with a FROM or a CLASS statement. So none of the overrides in HTMLBLUE were used. Instead, it was as though the ONLY change I wanted to make in my new template was for PROCTITLEFG and all the rest of the color values came from STATISTICAL, which has black for the SystemTitle.
So now, lets go back to using CLASS and see what happens to SystemTitle and what color it is in the final output if I only change the size but not the color -- what color will it be???
Now, SystemTitle gets the HTMLBLUE color because all the HTMLBLUE colors are intact because I used CLASS. When the TITLE statement is getting style added, the color is used from HTMLBLUE, not STATISTICAL.
The template documentation used to have a long discussion on FROM and inheritance. I find that if I stick with CLASS, then inheritance works as I expect.
Hope this helps,
Cynthia
Good demonstration, the forth piece of code gave me that 'a-ha' moment. Of course -- thank you for the work on the post; the graphics look great. (and are way more than I expected.)
Hi:
I'm glad it was useful. In my opinion, this is the ONLY way to understand and test template changes when you have a lot to do. It is tedious, I know, to change one thing, get it working and then make sure that it didn't break anything else and then repeat over and over.
However, in the long run, I find that my frustration level goes way down if I stick to that method. I've been doing it so long it's just an unwritten rule for me. My other "unwritten" rule is either ALWAYS use STYLE with a from _self_ or use a CLASS statement so that the from _self_ is implied. Using STYLE without FROM, in my use cases, rarely gives me what I want.
Hope this helps,
Cynthia
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: