123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- ---
- title: Introduction to Cascading Style Sheets
- order: 2
- layout: page
- ---
-
- [[themes.css]]
- = Introduction to Cascading Style Sheets
-
- ((("CSS", "introduction", id="term.themes.css", range="startofrange")))
-
- Cascading Style Sheets or CSS is the basic technique to separate the appearance
- of a web page from the content represented in HTML. In this section, we give an
- introduction to CSS and look how they are relevant to software development with
- Vaadin.
-
- As we can only give a short intruction in this book, we encourage you to refer
- to the rich literature on CSS and the many resources available in the web. You
- can find the authoratitative specifications of CSS standards from the
- link:http://www.w3.org/Style/CSS/[W3C
- website]
- ifdef::web[]
- and other literature, references, and tutorials from the
- link:http://www.dmoz.org/Computers/Data_Formats/Style_Sheets/CSS/[Open Directory
- Project page on CSS], as well as from other
- sources
- endif::web[]
- .
-
- [[themes.css.basics]]
- == Applying CSS to HTML
-
- Let us consider the following HTML document that contains various markup
- elements for formatting text. Vaadin UIs work in essentially similar documents,
- even though they use somewhat different elements to draw the user interface.
-
- [subs="normal"]
- ----
- <html>
- <head>
- <title>My Page</title>
- <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 HTML elements that will be styled later by matching CSS rules are emphasized
- above.
-
- The [elementname]#link# element in the HTML header defines the CSS stylesheet.
- The definition is automatically generated by Vaadin in the HTML page
- that loads the UI of the application. A stylesheet can also be embedded in the
- HTML document itself, as is done when optimizing their loading in Vaadin
- TouchKit, for example.
-
-
- [[themes.css.basics]]
- == Basic CSS Rules
-
- A stylesheet contains a set of __rules__ that can match the HTML elements in the
- page. 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 that matches certain elements in the simple HTML
- document given in the previous section:
-
- [source, css]
- ----
- p, td {
- color: blue;
- }
-
- td {
- background: yellow;
- font-weight: bold;
- }
- ----
-
- The [literal]#++p++# and [literal]#++td++# are element type selectors that match
- with [elementname]#p# and [elementname]#td# elements in HTML, respectively.
- The first rule matches with both elements, while the second matches only with
- [elementname]#td# elements.
- Let us assume that you have saved the above style sheet with the name [filename]#mystylesheet.css# and consider the following HTML file located in the same folder.
-
- [[figure.themes.basic.1]]
- .Simple Styling by Element Type
- image::img/themes-css-match-1.png[]
-
- [[themes.css.basics.inheritance]]
- === Style Inheritance in CSS
-
- CSS has __inheritance__ where contained elements inherit the properties of their
- parent elements. For example, let us change the above example and define it
- instead as follows:
-
- [source, css]
- ----
- table {
- color: blue;
- background: yellow;
- }
- ----
-
- All elements contained in the [elementname]#table# element would have the same properties.
- For example, the text in the contained [elementname]#td# elements would be in blue color.
-
-
- [[themes.css.basics.element-types]]
- === HTML Element Types
-
- HTML has a number of element types, each of which accepts a specific set of
- properties. The [elementname]#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 [elementname]#div# elements
- extensively to draw the UI, especially in layout components.
-
- ((("Google Web Toolkit", "themeing")))
- Matching elements by their type as shown above is, however, rarely if ever used
- in style sheets for Vaadin applications. We used it above, because it is the
- normal way in regular HTML documents that use the various HTML elements for
- formatting text, but it is not applicable in Vaadin UIs that consist mostly of
- [elementname]#div# elements. Instead, you need to match by element class, as
- described next.
-
-
-
- [[themes.css.matching-by-class]]
- == Matching by Element Class
-
- Matching HTML elements by the __class__ attribute is the most common form of
- matching in Vaadin stylesheets. It is also possible to match with the
- __identifier__ of a unique HTML element.
-
- The class of an HTML element is defined with the [parameter]#class# attribute as
- follows:
-
- [subs="normal"]
- ----
- <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.
-
-
- [source, css]
- ----
- p.normal {color: red;}
- p.another {color: blue;}
- td.normal {background: pink;}
- td.another {background: yellow;}
- ----
-
- The page would look as shown below:
-
- .Matching HTML Element Type and Class
- image::img/themes-css-match-class-2.png[]
-
- We can also match solely by the class by using the universal selector
- [literal]#++*++# for the element name, for example [literal]#++*.normal++#. The
- universal selector can also be left out altogether so that we use just the class
- name following the period, for example [literal]#++.normal++#.
-
-
- [source, css]
- ----
- .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.themes.match.class>>. This
- example illustrates a technique to make style sheets compatible regardless of
- the exact HTML element used in drawing a component.
-
- [[figure.themes.match.class]]
- .Matching Only HTML Element Class
- image::img/themes-css-match-class-3.png[]
-
- To ensure future compatibility, we recommend that you use only matching based on
- the classes and __do not__ match for specific HTML element types in CSS rules,
- because Vaadin may change the exact HTML implementation how components are drawn
- in the future.
- For example, Vaadin earlier used [elementname]#div# element to draw [classname]#Button# components, but later it was changed to use the special-purpose [elementname]#button# element in HTML.
- Because of using the [literal]#++v-button++# style class in the CSS rules for the button, styling it has changed only very little.
-
-
- [[themes.css.matching-by-descendants]]
- == Matching by Descendant Relationship
-
- CSS allows matching HTML by their containment relationship. For example,
- consider the following HTML fragment:
-
- [subs="normal"]
- ----
- <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 [literal]#++.mytext++# alone would match both the [elementname]#p# and [elementname]#td# elements.
- If we want to match only the table cell, we could use the following selector:
-
- [source, css]
- ----
- .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 "
- [literal]#++.v-panel .v-button++#" would match all elements with class
- [literal]#++.v-button++# somewhere inside an element with class
- [literal]#++.v-panel++#.
-
-
- [[themes.css.cascading]]
- == Importance of Cascading
-
- CSS or Cascading Stylesheets are, as the name implies, about __cascading__
- stylesheets, which means applying the stylesheet rules according to their
- origin, importance, scope, specifity, and order.
-
- For exact rules for cascading in CSS, see the section
- link:http://www.w3.org/TR/css3-cascade/#cascading[Cascading] in the CSS
- specification.
-
- [[themes.css.cascading.importance]]
- === Importance
-
- Declarations in CSS rules can be made override declarations with otherwise
- higher priority by annotating them as [literal]#++!important++#. For example, an
- inline style setting made in the [literal]#++style++# attribute of an HTML
- element has a higher specificity than any rule in a CSS stylesheet.
-
-
- [source, css]
- ----
- <div class="v-button" style="height: 20px;">...
- ----
-
- You can override the higher specificity with the [literal]#++!important++#
- annotation as follows:
-
-
- [source, css]
- ----
- .v-button {height: 30px !important;}
- ----
-
-
- [[themes.css.cascading.specificity]]
- === Specificity
-
- A rule that specifies an element with selectors more closely overrides ones that
- specify it less specifically. With respect to the element class selectors most
- commonly used in Vaadin themes, the specificity is determined by the number of
- class selectors in the selector.
-
-
- [source, css]
- ----
- .v-button {}
- .v-verticallayout .v-button {}
- .v-app .v-verticallayout .v-button {}
- ----
-
- In the above example, the last rule would have the highest specificity and would
- match.
-
- As noted earlier, style declarations given in the style attribute of a HTML
- element have higher specificity than declarations in a CSS rule, except if the
- [literal]#++!important++# annotation is given.
-
- See the CSS3 link:http://www.w3.org/TR/selectors/#specificity[selectors module
- specification] for details regarding how the specificity is computed.
-
-
- [[themes.css.cascading.order]]
- === Order
-
- CSS rules given later have higher priority than ones given earlier. For example,
- in the following, the latter rule overrides the former and the color will be
- black:
-
-
- [source, css]
- ----
- .v-button {color: white}
- .v-button {color: black}
- ----
-
- As specificity has a higher cascading priority than order, you could make the
- first rule have higher priority by adding specificity as follows:
-
-
- [source, css]
- ----
- .v-app .v-button {color: white}
- .v-button {color: black}
- ----
-
- The order is important to notice in certain cases, because Vaadin does not
- guarantee the order in which CSS stylesheets are loaded in the browser, which
- can in fact be random and result in very unexpected behavior. This is not
- relevant for Sass stylesheets, which are compiled to a single stylesheet. For
- plain CSS stylesheets, such as add-on or TouchKit stylesheets, the order can be
- relevant.
-
-
-
- [[themes.css.hierarchy]]
- == Style Class Hierarchy of a Vaadin UI
-
- Let us give a real case in a Vaadin UI by considering a simple Vaadin UI with a
- label and a button inside a vertical layout:
-
-
- [source, java]
- ----
- // UI has v-ui style class
- @Theme("mytheme")
- public class HelloWorld extends UI {
- @Override
- protected void init(VaadinRequest request) {
- // VerticalLayout has v-verticallayout style
- VerticalLayout content = new VerticalLayout();
- setContent(content);
-
- // Label has v-label style
- content.addComponent(new Label("Hello World!"));
-
- // Button has v-button style
- content.addComponent(new Button("Push Me!",
- new Button.ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- Notification.show("Pushed!");
- }
- }));
- }
- }
- ----
-
- The UI will look by default as shown in <<figure.themes.css.hierarchy.initial>>.
- By using a HTML inspector such as Firebug, you can view the HTML tree and the
- element classes and applied styles for each element.
-
- [[figure.themes.css.hierarchy.initial]]
- .An Unthemed Vaadin UI
- image::img/example-ui-default.png[]
-
- Now, let us look at the HTML element class structure of the UI, as we can see it
- in the HTML inspector:
-
- [subs="normal"]
- ----
- <body class="**v-generated-body v-ff v-ff20 v-ff200 v-gecko v-lin**"
- scroll="auto">
- <div id="bookexamplesvaadin7helloworld-447164942"
- class="**v-app mytheme**">
- <div class="**v-ui v-scrollable**"
- tabindex="1" style="height: 100%; width: 100%;">
- <div class="**v-loading-indicator first**"
- style="position: absolute; display: none;"></div>
- <div class="**v-verticallayout v-layout v-vertical v-widget v-has-width**"
- style="width: 100%;">
- <div class="**v-slot**">
- <div class="**v-label v-widget v-has-width**"
- style="width: 100%;">Hello World!</div>
- </div>
- <div class="**v-slot**">
- <div class="**v-button v-widget**"
- tabindex="0" role="button">
- <span class="**v-button-wrap**">
- <span class="**v-button-caption**">Push Me!</span>
- </span>
- </div>
- </div>
- </div>
- </div>
- </div>
- ...
- <body>
- ----
- Now, consider the following theme where we set the colors and margins of various
- elements. The theme is actually a Sass theme.
-
-
- [source, css]
- ----
- @import "../valo/valo.scss";
-
- @mixin mytheme {
- @include valo;
-
- /* White background for the entire UI */
- .v-ui {
- background: white;
- }
-
- /* All labels have white text on black background */
- .v-label {
- background: black;
- color: white;
- font-size: 24pt;
- line-height: 24pt;
- padding: 5px;
- }
-
- /* All buttons have blue caption and some margin */
- .v-button {
- margin: 10px;
-
- /* A nested selector to increase specificity */
- .v-button-caption {
- color: blue;
- }
- }
- }
- ----
-
- The look has changed as shown in <<figure.themes.css.hierarchy.themed>>.
-
- [[figure.themes.css.hierarchy.themed]]
- .Themed Vaadin UI
- image::img/example-ui-themed.png[]
-
- 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 [classname]#Link# component,
- [literal]#++over++# class is added to the component. Most of such styling is a
- feature of Google Web Toolkit.
-
-
- [[themes.css.compatibility]]
- == Notes on Compatibility
-
- ((("CSS", "compatibility")))
- ((("compatibility")))
- CSS is a standard continuously under development. It was first proposed in 1994.
- The specification of CSS is maintained by the CSS Working Group of World Wide
- Web Consortium (W3C). Versioned with backward-compatible "levels", CSS Level 1
- was published in 1996, Level 2 in 1998, and the ongoing development of CSS Level
- 3 started in 1998. CSS3 is divided into a number of separate modules, each
- developed and progressing separately, and many of the modules are already Level
- 4.
-
- 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 your own themes.
- Compatibility issues are detailed in various CSS handbooks.
-
-
- (((range="endofrange", startref="term.themes.css")))
|