Cascading Style Sheets or CSS is a technique to separate the appearance of a web page from the content represented in HTML or XHTML. Let us give a short introduction to Cascading Style Sheets and look how they are relevant to software development with Vaadin.
A style sheet is a file that contains a set of rules. Each rule consists of one or more selectors, separated with commas, and a declaration block enclosed in curly braces. A declaration block contains a list of property statements. Each property has a label and a value, separated with a colon. A property statement ends with a semicolon.
Let us look at an example:
p, td { color: blue; } td { background: yellow; font-weight: bold; }
In the example above, p
and td
are
element type selectors that match with <p>
and
<td>
elements in HTML, respectively. The first
rule matches with both elements, while the second matches only with
<td>
elements. Let us assume that you have saved
the above style sheet with the name mystylesheet.css
and
consider the following HTML file located in the same folder.
<html> <head> <link rel="stylesheet" type="text/css" href="mystylesheet.css"/> </head> <body> <p>This is a paragraph</p> <p>This is another paragraph</p> <table> <tr> <td>This is a table cell</td> <td>This is another table cell</td> </tr> </table> </body> </html>
The <link>
element defines the style sheet to
use. The HTML elements that match the above rules are emphasized. When the
page is displayed in the browser, it will look as shown in the figure
below.
CSS has an inheritance mechanism where contained elements inherit the properties of their parent elements. For example, let us change the above example and define it instead as follows:
table { color: blue; background: yellow; }
All elements contained in the <table>
element
would have the same properties. For example, the text in the contained
<td>
elements would be in blue color.
Each HTML element type accepts a certain set of properties. The
<div>
elements are generic elements that can be
used to create almost any layout and formatting that can be created with a
specific HTML element type. Vaadin uses
<div>
elements extensively, especially for
layouts.
Matching elements by their type is, however, rarely if ever used in style sheets for Vaadin components or Google Web Toolkit widgets.
Matching HTML elements by the class attribute of the elements is the most relevant form of matching with Vaadin. It is also possible to match with the identifier of a HTML element.
The class of an HTML element is defined with the
class
attribute as follows:
<html> <body> <p class="normal">This is the first paragraph</p> <p class="another">This is the second paragraph</p> <table> <tr> <td class="normal">This is a table cell</td> <td class="another">This is another table cell</td> </tr> </table> </body> </html>
The class attributes of HTML elements can be matched in CSS rules with a selector notation where the class name is written after a period following the element name. This gives us full control of matching elements by their type and class.
p.normal {color: red;} p.another {color: blue;} td.normal {background: pink;} td.another {background: yellow;}
The page would look as shown below:
We can also match solely by the class by using the universal selector
*
for the element name, for example
*.normal
. The universal selector can also be left out
altogether so that we use just the class name following the period, for
example .normal
.
.normal { color: red; } .another { blackground: yellow; }
In this case, the rule will match with all elements of the same class regardless of the element type. The result is shown in Figure 8.4, “Matching Only HTML Element Class”. This example illustrates a technique to make style sheets compatible regardless of the exact HTML element used in drawing a component.
To assure compatibility, we recommend that you use only matching based on
the element classes and do not match for specific
HTML element types in CSS rules, because either Vaadin or GWT
may use different HTML elements to render some components in the
future. For example, IT Mill Toolkit Release 4 used
<div>
elements extensively for layout
components. However, IT Mill Toolkit Release 5 and Vaadin use GWT to render the components, and GWT
uses the <table>
element to implement most
layouts. Similarly, IT Mill Toolkit Release 4 used <div>
element
also for buttons, but in Release 5, GWT uses the
<button>
element. Vaadin has little control over
how GWT renders its components, so we can not guarantee compatibility in
different versions of GWT. However, both <div>
and <table>
as well as
<tr>
and <td>
elements
accept most of the same properties, so matching only the class hierarchy
of the elements should be compatible in most cases.
CSS allows matching HTML by their containment relationship. For example, consider the following HTML fragment:
<body> <p class="mytext">Here is some text inside a paragraph element</p> <table class="mytable"> <tr> <td class="mytext">Here is text inside a table and inside a td element.</td> </tr> </table> </body>
Matching by the class name .mytext
alone would match
both the <p>
and <td>
elements. If we want to match only the table cell, we could use the following selector:
.mytable .mytext {color: blue;}
To match, a class listed in a rule does not have to be an immediate
descendant of the previous class, but just a descendant. For example, the
selector ".v-panel .v-button
" would match all elements
with class .v-button
somewhere inside an element with
class .v-panel
.
Let us give an example with a real case. Consider the following Vaadin component.
public class LoginBox extends CustomComponent { Panel panel = new Panel("Log In"); public LoginBox () { setCompositionRoot(panel); panel.addComponent(new TextField("Username:")); panel.addComponent(new TextField("Password:")); panel.addComponent(new Button("Login")); } }
The component will look by default as shown in the following figure.
Now, let us look at the HTML structure of the component. The following listing assumes that the application contains only the above component in the main window of the application.
<body> <div id="v-app"> <div> <div class="v-orderedlayout"> <div> <div class="v-panel"> <div class="v-panel-caption">Log In</div> <div class="v-panel-content"> <div class="v-orderedlayout"> <div> <div> <div class="v-caption"> <span>Username:</span> </div> </div> <input type="text" class="v-textfield"/> </div> <div> <div> <div class="v-caption"> <span>Password:</span> </div> </div> <input type="password" class="v-textfield"/> </div> <div> <button type="button" class="v-button">Login</button> </div> </div> </div> <div class="v-panel-deco"/> </div> </div> </div> </div> </div> </body>
Now, consider the following theme where we set the backgrounds of various elements.
.v-panel .v-panel-caption { background: #80ff80; /* pale green */ } .v-panel .v-panel-content { background: yellow; } .v-panel .v-textfield { background: #e0e0ff; /* pale blue */ } .v-panel .v-button { background: pink; }
The coloring has changed as shown in the following figure.
An element can have multiple classes separated with a space. With multiple
classes, a CSS rule matches an element if any of the classes match. This
feature is used in many Vaadin components to allow matching based
on the state of the component. For example, when the mouse is over a
Link
component, over
class is
added to the component. Most of such styling is a feature of Google Web
Toolkit.
CSS was first proposed in 1994. The specification of CSS is maintained by the CSS Working Group of World Wide Web Consortium (W3C). Its versions are specified as levels that build upon the earlier version. CSS Level 1 was published in 1996, Level 2 in 1998. Development of CSS Level 3 was started in 1998 and is still under way.
While the support for CSS has been universal in all graphical web browsers since at least 1995, the support has been very incomplete at times and there still exists an unfortunate number of incompatibilities between browsers. While we have tried to take these incompatibilities into account in the built-in themes in Vaadin, you need to consider them while developing custom themes.
Compatibility issues are detailed in various CSS handbooks.