Table of Contents
Cascading Style Sheets (CSS) enable web designers to enhance the power of HTML tags. In old-fashioned HTML, an <H1> tag would make displayed text a little bigger and bolder, but font style, color, and size were left to the browser. With CSS, the web designer can use the <H1> tag to specify those font attributes.
CSS support within OpenLaszlo helps designers who are not fluent with the LZX scripting language maintain the appearance of Laszlo applications.
If an OpenLaszlo application is to be deployed more than once -- but with different colors, sizes, or resources in each deployment, for instance -- the designer can alter those attributes within a stylesheet.
This is the simplest example of an OpenLaszlo view:
To generate that view with a cascading stylesheet:
Example 19.2. Simplest view with CSS
<canvas> <stylesheet> #gView { height: "100"; width: "100"; bgcolor: "0x663399"; } </stylesheet> <view id="gView" height="$style{'height'}" width="$style{'width'}" bgcolor="$style{'bgcolor'}"/> </canvas>
The $style
constraint tells the OpenLaszlo runtime to style an attribute according to the stylesheet
. More than one stylesheet can be used in an LZX document; the application of a stylesheet is determined by selectors.
The stylesheet is a collection of rules that apply to the LZX document. Each rule applies to one aspect of the document, and consists of two parts: selector and declaration.
The selector comes before the curly brace, the declaration after. In the
example above, an LZX element with id="myView"
and
bgcolor="$style{'bgcolor'}
within its declaration will get a blue
background color.
CSS support for OpenLaszlo enables four types of selectors:
Attribute
Element
ID
Descendant
The attribute selector applies when it corresponds to a node's attribute
(for instance, name
or width
):
Example 19.5. Attribute selector
<canvas height="150" width="200"> <stylesheet> [name="PurpleView"] { width: "100"; height: "100"; bgcolor: "0x9900FF" } [width="200"] { bgcolor: "0x0000FF"; } </stylesheet> <simplelayout axis="x" spacing="10"/> <class name="myPurpleView"> <view name="PurpleView" height="$style{'height'}" width="$style{'width'}" bgcolor="$style{'bgcolor'}"/> </class> <class name="myWiderView"> <view name="hoo" height="100" width="200" bgcolor="$style{'bgcolor'}"/> </class> <myPurpleView/> <myWiderView/> </canvas>
The class myPurpleView
contains a view whose name
corresponds to the
stylesheet selector [name="PurpleView"]
, so each of its $style
rules is
applied. The class myWiderView
contains a view whose width
fires the
$style
that applies to its background color.
The element selector applies when it matches the name of the node itself:
Example 19.7. Element selector
<canvas height="200" width="200"> <stylesheet> view { nicebgcolor: "0x0000FF"; micebgcolor: "0xCCCCCC"; } </stylesheet> <view height="100" width="100" bgcolor="$style{'nicebgcolor'}"/> <view height="75" width="75" bgcolor="0xFFFFFF"/> <view height="50" width="50" bgcolor="$style{'micebgcolor'}"/> </canvas>
ID selectors are identified by # in the stylesheet. The selector applies when it matches a node's ID:
Example 19.9. ID selector
<canvas height="200" width="200"> <stylesheet> #red { width: 100; height: 100; bgcolor: "0xFF3333"; } #blue { width: 150; height: 150; bgcolor: "0x3333FF"; } </stylesheet> <simplelayout axis="x" spacing="5" /> <class name="gBox" width="$style{'width'}" height="$style{'height'}" bgcolor="$style{'bgcolor'}" /> <gBox id="red" /> <gBox id="blue" /> </canvas>
Example 19.10. Descendant example
fee fi { property: "car"; } fee fi foo { property: "cart"; } fee fi foo fum { property: "cartman"; }
A selector in an ancestor/descendant hierarchy applies when its ancestors do. In the snippet above, the "fee" selector depends on no ancestors, so it would always fire on an LzNode identified by "fee". The "fum" selector, on the other hand, would only fire if the LzNode had three ancestors "fee", "fi", and "foo".
Example 19.11. Descendant selector
<canvas width="400" height="400"> <stylesheet> styledbox { stylebgcolor: "0xCCCCCC"; styleinnercolor: "0xFF0000"; } styledbox styledbox2 { stylebgcolor: "0x999999"; styleinnercolor: "0x0000FF"; } styledbox styledbox2 styledbox3 { stylebgcolor: "0x666666"; styleinnercolor: "0x00FF00"; } </stylesheet> <class name="styledbox" height="100" width="100" bgcolor="$style{'stylebgcolor'}"> <view name="snow" x="10" y="10" height="10" width="10" bgcolor="$style{'styleinnercolor'}"/> </class> <class name="styledbox2" height="100" width="100" bgcolor="$style{'stylebgcolor'}"> <view name="braxton" x="10" y="10" height="10" width="10" bgcolor="$style{'styleinnercolor'}"/> </class> <class name="styledbox3" height="100" width="100" bgcolor="$style{'stylebgcolor'}"> <view name="jackson" x="10" y="10" height="10" width="10" bgcolor="$style{'styleinnercolor'}"/> </class> <styledbox id="comet" x="200" y="0"> <styledbox2 id="shock" x="-100" y="100"> <styledbox3 id="storm" x="-100" y="100"/> </styledbox2> </styledbox> <styledbox2/> <styledbox3/> </canvas>
In the example above, the instances of styledbox2
and styledbox3
at the
end of the script don't appear on the canvas at all, because there's no
stylesheet information for styledbox2
unless it descends from styledbox
,
and no stylesheet information for styledbox3
unless it descends from
stylebox
and stylebox2
.
Warning | |
---|---|
Don't include an underscore in selector names, because the LZX file will not compile. |
Warning | |
---|---|
The difference between an attribute selector and a descendant selector is as little as a spacebar. The attribute selector
|
The advantage of using stylesheets shows in a slightly more difficult OpenLaszlo application. If a designer wanted to reuse a template, no knowledge of OpenLaszlo's LZX language is necessary -- in this example, s/he just has to change the color hexcode(s) and the name(s) of the resource(s) in the stylesheet:
Example 19.12. Nested view
<canvas height="350" width="700"> <stylesheet> #sun { bgcolor: "0x16355E"; face: "../resources/smiley.gif"; } #monarchs { bgcolor: "0xB2B9CB"; face: "../resources/sourface.png"; } </stylesheet> <simplelayout axis="x" spacing="10"/> <class name="bouncebox"> <view name="outer" x="0" y="0" width="200" height="200" bgcolor="$style{'bgcolor'}"> <view name="inner" x="50" y="50" bgcolor="0xFFFFFF" width="${immediateparent.width-100}" height="${immediateparent.height-100}" /> <view name="gBounce" source="$style{'face'}" x="50" y="50"> <animatorgroup name="myAnimatorGroup" start="true" process="sequential" > <animator attribute="y" from="50" to="150" duration="1000" motion="linear"/> <animator attribute="y" from="50" to="100" duration="1000" repeat="Infinity" motion="easeout"/> </animatorgroup> </view> </view> </class> <bouncebox id="monarchs" /> <bouncebox id="sun" /> </canvas>
For styling a view created dynamically with new
, it's easiest to define a class, then new
instances of the class:
Example 19.13. Styled views created dynamically
<canvas debug="true"> <stylesheet> mookie { height : 25; width : 25; bgcolor : #0000FF; } blaylock { title : "Blaylock"; bgcolor : #FF0000; } wilson { height : 25; width : 200; fgcolor : #FF00FF; text : "Wilson"; } </stylesheet> <class name="mookie" x="200" height="$style{'height'}" width="$style{'width'}" bgcolor="$style{'bgcolor'}"/> <class name="blaylock"> <window title="$style{'title'}" x="250" height="100" width="150" bgcolor="$style{'bgcolor'}"/> </class> <class name="wilson" > <text text="$style{'text'}" x="400" height="$style{'height'}" width="$style{'width'}" fgcolor="$style{'fgcolor'}"/> </class> <button text="Dynamically create Mookie"> <method event="onclick"> canvas.mookieView=new mookie(canvas, {}); </method> </button> <button text="Dynamically create Blaylock" y="50"> <method event="onclick"> canvas.blaylockWindow=new blaylock(canvas, {}); </method> </button> <button text="Dynamically create Wilson" y="100"> <method event="onclick"> canvas.wilsonText=new wilson(canvas, {}); </method> </button> </canvas>
An instance of an LzNode -- most likely a view, or some other OpenLaszlo element -- can trigger more than one selector in the stylesheet. In such cases, CSS gives precedence according to rules of specificity. In general, the more specific the selector, the higher its precedence. For instance, the ID of a view is more specific (can only apply to one view) than view itself (applies to every view).
Within OpenLaszlo's CSS support, the order of specificity is (in ascending order):
Element
Attribute
ID
This example uses all three selectors:
Example 19.14. Specificity
<canvas width="350" height="150"> <stylesheet> view { height: "50"; width: "50"; bgcolor: "0xFF0000"; } [name='blue'] { height: "50"; width: "50"; bgcolor: "0x0000FF"; } #green { height: "50"; width: "50"; bgcolor: "0x006600"; } </stylesheet> <simplelayout axis="x" spacing="25"/> <view id="red" name="red" width="$style{'width'}" height="$style{'height'}" bgcolor="$style{'bgcolor'}"/> <view id="blue" name="blue" width="$style{'width'}" height="$style{'height'}" bgcolor="$style{'bgcolor'}" /> <view id="green" name="green" width="$style{'width'}" height="$style{'height'}" bgcolor="$style{'bgcolor'}" /> </canvas>
The first view -- red
-- fires the element selector, because its ID is
not "green", and its name is not "blue". It is an instance of a "view"
element, which triggers the element selector. The second view -- blue
-- fires the name selector; its ID is not "green", but the next selector in
order of priority is attribute, which name='blue'
matches. The third
view -- green
-- hits the highest-priority selector; id='green'
matches
the ID selector #green
, and looks up that stylesheet.
Warning | |
---|---|
Style selectors: Under w3's CSS specificity rules, the highest-priority selector is "style='foo'", which directly looks up the foo stylesheet. The OpenLaszlo implementation does not support "style='foo'" because that expression cannot be used as a Laszlo property or attribute. |
In some cases, more than one selector of the same type will be
triggered. In this example, the view short
fires two selectors:
[height="50"]
and [width="100"]
. Neither selector takes precedence
because they are both attribute selectors, so a tiebreaker has to be
invoked. The selector closest to the bottom of the stylesheet prevails.
Example 19.15. Lexical order
<canvas height="200" width="345"> <stylesheet> [height="50"] { height: "50"; width: "100"; bgcolor: "0xFF0000"; } [width="100"] { height: "50"; width: "100"; bgcolor: "0x0000FF"; } </stylesheet> <simplelayout axis="y" spacing="10"/> <view name="short" width="100" height="50" bgcolor="$style{'bgcolor'}"/> <view y="75"> <text text="If I'm red, the first stylesheet was triggered."/> </view> <view y="100"> <text text="If I'm blue, the second stylesheet was triggered."/> </view> </canvas>
A stylesheet can be imported by using
when the stylesheet is in its typical format:
Example 19.17. Imported stylesheet example
<!--begin foo.css--> #gPhilip { width: 300; height: 200; bgcolor: "0x8F008F"; } <!--end--> <!--The LZX file--> <canvas> <stylesheet src="foo.css" /> <view id="gPhilip" width="$style{'width'}" height="$style{'height'}" bgcolor="$style{'bgcolor'}"/> </canvas>
Copyright © 2002-2007 Laszlo Systems, Inc. All Rights Reserved. Unauthorized use, duplication or distribution is strictly prohibited. This is the proprietary information of Laszlo Systems, Inc. Use is subject to license terms.