diff options
author | elmot <elmot@vaadin.com> | 2015-09-25 16:40:44 +0300 |
---|---|---|
committer | elmot <elmot@vaadin.com> | 2015-09-25 16:40:44 +0300 |
commit | a1b265c318dbda4a213cec930785b81e4c0f7d2b (patch) | |
tree | b149daf5a4f50b4f6446c906047cf86495fe0433 /documentation/themes/themes-css.asciidoc | |
parent | b9743a48a1bd0394f19c54ee938c6395a80f3cd8 (diff) | |
download | vaadin-framework-a1b265c318dbda4a213cec930785b81e4c0f7d2b.tar.gz vaadin-framework-a1b265c318dbda4a213cec930785b81e4c0f7d2b.zip |
Framework documentation IN
Change-Id: I767477c1fc3745f9e1f58075fe30c9ac8da63581
Diffstat (limited to 'documentation/themes/themes-css.asciidoc')
-rw-r--r-- | documentation/themes/themes-css.asciidoc | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/documentation/themes/themes-css.asciidoc b/documentation/themes/themes-css.asciidoc new file mode 100644 index 0000000000..45229303dc --- /dev/null +++ b/documentation/themes/themes-css.asciidoc @@ -0,0 +1,506 @@ +--- +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 [literal]#++<link>++# element in the HTML header defines the used 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 [literal]#++<p>++# and [literal]#++<td>++# elements in HTML, respectively. +The first rule matches with both elements, while the second matches only with +[literal]#++<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 [literal]#++<table>++# element would have the same +properties. For example, the text in the contained [literal]#++<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 [literal]#++<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 [literal]#++<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 +[literal]#++<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 [literal]#++<div>++# element to +draw [classname]#Button# components, but later it was changed to use the +special-purpose [literal]#++<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 +[literal]#++<p>++# and [literal]#++<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"))) + + |