You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

themes-responsive.asciidoc 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. ---
  2. title: Responsive Themes
  3. order: 10
  4. layout: page
  5. ---
  6. [[themes.responsive]]
  7. = Responsive Themes
  8. ((("[classname]#responsive# extension", id="term.themes.responsive", range="startofrange")))
  9. ((("CSS selections")))
  10. ((("extension")))
  11. Vaadin includes support for responsive design which enables size range
  12. conditions in CSS selectors, allowing conditional CSS rules that respond to size
  13. changes in the browser window on the client-side.
  14. ifdef::web[]
  15. See the link:https://vaadin.com/blog/-/blogs/3126636[Vaadin Blog article on
  16. Responsive design] for some additional
  17. information.
  18. endif::web[]
  19. You can use the [classname]#Responsive# extension to extend either a component,
  20. typically a layout, or the entire UI. You specify the component by the static
  21. [methodname]#makeResponsive()# method.
  22. ----
  23. // Have some component with an appropriate style name
  24. VerticalLayout l = new VerticalLayout();
  25. Label c = new Label("Here be text");
  26. l.addStyleName("myresponsive");
  27. l.addComponent(c);
  28. // Enable Responsive CSS selectors for the component
  29. Responsive.makeResponsive(l);
  30. ----
  31. You can now use [literal]#++width-range++# and [literal]#++height-range++#
  32. conditions in CSS selectors as follows:
  33. ----
  34. /* Basic settings for all sizes */
  35. .myresponsive {
  36. padding: 5px;
  37. line-height: 36pt;
  38. }
  39. /* Small size */
  40. .myresponsive[width-range~="0-300px"] {
  41. background: orange;
  42. font-size: 16pt;
  43. }
  44. /* Medium size */
  45. .myresponsive[width-range~="301px-600px"] {
  46. background: azure;
  47. font-size: 24pt;
  48. }
  49. /* Anything bigger */
  50. .myresponsive[width-range~="601px-"] {
  51. background: palegreen;
  52. font-size: 36pt;
  53. }
  54. ----
  55. You can have overlapping size ranges, in which case all the selectors matching
  56. the current size are enabled.
  57. ifdef::web[]
  58. Note that responsive themes currently
  59. link:https://dev.vaadin.com/ticket/16249[do not work together with] stylesheets
  60. or widget sets loaded from a different domain than the Vaadin application. Such
  61. resources must be loaded from the same domain as the application. The problem
  62. occurs only in Firefox. A SecurityError is shown in the debug window. The
  63. limitation concerns stylesheets such as for web fonts served from external
  64. sites, as described in
  65. <<themes-fonts#themes.fonts.webfonts,"Loading
  66. Web Fonts">>.
  67. endif::web[]
  68. ifdef::web[]
  69. [[themes.responsive.wrap]]
  70. == Flexible Wrapping
  71. You can use the [classname]#CssLayout# to have automatic wrap-around when the
  72. components in the layout would go off right side of the layout. Components that
  73. wrap must, however, have either undefined or fixed width, and thereby can not
  74. utilize the full area of the screen. With the [classname]#Responsive# extension,
  75. you can have more flexible wrap-around that gives the component tiles maximum
  76. width.
  77. In the following, we have a text and image box, which are laid out horizontally
  78. with 50-50 sizing if the screen is wide enough, but wrap to a vertical layout if
  79. the screen is narrow.
  80. ----
  81. CssLayout layout = new CssLayout();
  82. layout.setWidth("100%");
  83. layout.addStyleName("flexwrap");
  84. content.addComponent(layout);
  85. // Enable Responsive CSS selectors for the layout
  86. Responsive.makeResponsive(layout);
  87. Label title = new Label("Space is big, really big");
  88. title.addStyleName("title");
  89. layout.addComponent(title);
  90. Label description = new Label("This is a " +
  91. "long description of the image shown " +
  92. "on the right or below, depending on the " +
  93. "screen width. The text here could continue long.");
  94. description.addStyleName("itembox");
  95. description.setSizeUndefined();
  96. layout.addComponent(description);
  97. Image image = new Image(null,
  98. new ThemeResource("img/planets/Earth.jpg"));
  99. image.addStyleName("itembox");
  100. layout.addComponent(image);
  101. ----
  102. The SCSS could be as follows:
  103. ----
  104. /* Various general settings */
  105. .flexwrap {
  106. background: black;
  107. color: white;
  108. .title {
  109. font-weight: bold;
  110. font-size: 20px;
  111. line-height: 30px;
  112. padding: 5px;
  113. }
  114. .itembox {
  115. white-space: normal;
  116. vertical-align: top;
  117. }
  118. .itembox.v-label {padding: 5px}
  119. }
  120. .flexwrap[width-range~="0-499px"] {
  121. .itembox {width: 100%}
  122. }
  123. .flexwrap[width-range~="500px-"] {
  124. .itembox {width: 50%}
  125. }
  126. ----
  127. The layout in the wide mode is shown in <<figure.theme.responsive.flexwrap>>.
  128. [[figure.theme.responsive.flexwrap]]
  129. .Flexible Wrapping
  130. image::img/addon-responsive-flexwrap.png[]
  131. You could also play with the [literal]#++display: block++# vs
  132. [literal]#++display: inline-block++# properties.
  133. Notice that, while the [classname]#Responsive# extension makes it possible to do
  134. various CSS trickery with component sizes, the normal rules for component and
  135. layout sizes apply, as described in
  136. <<layout-settings#layout.settings.size,"Layout
  137. Size">> and elsewhere, and you should always check the size behaviour of the
  138. components. In the above example, we set the label to have undefined width,
  139. which disables word wrap, so we had to re-enable it.
  140. endif::web[]
  141. ifdef::web[]
  142. [[themes.responsive.display]]
  143. == Toggling the Display Property
  144. ((("display (CSS
  145. property)")))
  146. The [literal]#++display++# property allows especially powerful ways to offer
  147. radically different UIs for different screen sizes by enabling and disabling UI
  148. elements as needed. For example, you could disable some parts of the UI when the
  149. space gets too small, but bring forth navigation buttons that, when clicked, add
  150. component styles to switch to the hidden parts.
  151. In the following, we simply show alternative components based on screen width:
  152. ----
  153. CssLayout layout = new CssLayout();
  154. layout.setWidth("100%");
  155. layout.addStyleName("toggledisplay");
  156. content.addComponent(layout);
  157. // Enable Responsive CSS selectors for the layout
  158. Responsive.makeResponsive(layout);
  159. Label enoughspace =
  160. new Label("This space is big, mindbogglingly big");
  161. enoughspace.addStyleName("enoughspace");
  162. layout.addComponent(enoughspace);
  163. Label notenoughspace = new Label("Quite small space");
  164. notenoughspace.addStyleName("notenoughspace");
  165. layout.addComponent(notenoughspace);
  166. ----
  167. The SCSS could be as follows:
  168. ----
  169. /* Common settings */
  170. .toggledisplay {
  171. .enoughspace, .notenoughspace {
  172. color: white;
  173. padding: 5px;
  174. }
  175. .notenoughspace { /* Really small */
  176. background: red;
  177. font-weight: normal;
  178. font-size: 10px;
  179. line-height: 15px;
  180. }
  181. .enoughspace { /* Really big */
  182. background: darkgreen;
  183. font-weight: bold;
  184. font-size: 20px;
  185. line-height: 30px;
  186. }
  187. }
  188. /* Quite little space */
  189. .toggledisplay[width-range~="0-499px"] {
  190. .enoughspace {display: none}
  191. }
  192. /* Plenty of space */
  193. .toggledisplay[width-range~="500px-"] {
  194. .notenoughspace {display: none}
  195. }
  196. ----
  197. endif::web[]
  198. ifdef::web[]
  199. [[themes.responsive.demos]]
  200. == Responsive Demos
  201. You can find a simple responsive demo at
  202. link:http://demo.vaadin.com/responsive/[demo.vaadin.com/responsive]. It
  203. demonstrates the flexible wrapping technique described in
  204. <<themes.responsive.wrap>>.
  205. ((("Parking
  206. demo")))
  207. ((("TouchKit", "Parking
  208. demo")))
  209. link:https://demo.vaadin.com/parking/[The Parking demo for TouchKit] uses a responsive theme to adapt to mobile
  210. devices with different screen sizes and when the screen orientation changes.
  211. endif::web[]
  212. (((range="endofrange", startref="term.themes.responsive")))