Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

WidgetStylingUsingOnlyCSS.asciidoc 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. ---
  2. title: Widget Styling Using Only CSS
  3. order: 52
  4. layout: page
  5. ---
  6. [[widget-styling-using-only-css]]
  7. Widget styling using only CSS
  8. -----------------------------
  9. The preferred way of styling your widget is to only use static CSS
  10. included in the theme's styles.css file. For information on how to
  11. create custom themes, please refer to
  12. https://vaadin.com/book/-/page/themes.creating.html. Your component can
  13. be styled using the CSS class names that are defined to the widget using
  14. `setStyleName`.
  15. Normal styling of components works in the same way as any styling using
  16. CSS, but there are some special features to pay attention to when Vaadin
  17. 7 is used.
  18. [[some-sizing-theory]]
  19. Some sizing theory
  20. ~~~~~~~~~~~~~~~~~~
  21. All Vaadin 7 components get the CSS class v-widget which sets the
  22. box-sizing to border-box. This causes borders and paddings to be
  23. considered when the browser calculates the component's size. This means
  24. that e.g. a component with padding: 5px and width: 100% inside a 200px
  25. wide slot will fill the slot without any overflow because the inner
  26. width of the component will be calculated to 190px by the browser.
  27. The Vaadin 7 server side API allows setting the size of the component in
  28. three different ways:
  29. * Undefined size, set e.g. using `setWidth(null)`, means that the
  30. component's size should have it's default size that might vary depending
  31. on its content.
  32. * Relative size, set e.g. using `setWidth("100%")` means that the
  33. component's size is determined by the size and settings of the
  34. component's parent.
  35. * Fixed size, set e.g. using `setWidth("250px")` or `setWidth("10em")` means
  36. that the component's size is fixed, so that the parent doesn't affect
  37. the size and neither does the component's content.
  38. The three different ways of setting the size means that a component
  39. should both support having its own natural size and filling the
  40. allocated space depending on how the size is set. This usually means
  41. that the main area of the component should adjust based on the settings.
  42. [[a-simple-sample]]
  43. A simple sample
  44. ~~~~~~~~~~~~~~~
  45. Consider e.g. a simple date picker component with a text field where a
  46. date can be entered and where the currently selected is displayed and a
  47. button that is used to open a calendar view where a date can be picked
  48. using the mouse.
  49. [source,java]
  50. ....
  51. public class MyPickerWidget extends ComplexPanel {
  52. public static final String CLASSNAME = "mypicker";
  53. private final TextBox textBox = new TextBox();
  54. private final PushButton button = new PushButton("...");
  55. public MyPickerWidget() {
  56. setElement(Document.get().createDivElement());
  57. setStylePrimaryName(CLASSNAME);
  58. textBox.setStylePrimaryName(CLASSNAME + "-field");
  59. button.setStylePrimaryName(CLASSNAME + "-button");
  60. add(textBox, getElement());
  61. add(button, getElement());
  62. button.addClickHandler(new ClickHandler() {
  63. public void onClick(ClickEvent event) {
  64. Window.alert("Calendar picker not yet supported!");
  65. }
  66. });
  67. }
  68. }
  69. ....
  70. We then add this basic styling to the theme CSS file
  71. [source,scss]
  72. ....
  73. .mypicker {
  74. white-space: nowrap;
  75. }
  76. .mypicker-button {
  77. display: inline-block;
  78. border: 1px solid black;
  79. padding: 3px;
  80. width: 15px;
  81. text-align: center;
  82. }
  83. ....
  84. `display: inline-block` makes the button continue on the same line as the
  85. text field, placing it to the right of the field. We also add
  86. `white-space: nowrap` to the main div element to ensure the button is not
  87. wrapped to the next row. Finally, there is some padding and a border to
  88. make the button look more like a real button.
  89. [[using-available-space]]
  90. Using available space
  91. ^^^^^^^^^^^^^^^^^^^^^
  92. This simple layout works well as long as the component's has it's
  93. default undefined width. Changing the width from the server does however
  94. not have any visible effect because only the size of the main div is
  95. changed. If the component is made smaller, the contents goes beyond the
  96. size of the element (this can be verified by adding `overflow: hidden;` to
  97. `.mypicker`) and if it gets larger the extra space is just left as empty
  98. space to the right of the button.
  99. The first step towards making the size adjust is to make the text field
  100. adjust to the main div element's width whenever the width is something
  101. else then than undefined. In these situations, Vaadin 7 adds a
  102. `v-has-width` class to the component's main element (`v-has-height` added
  103. when the height is not undefined).
  104. [source,scss]
  105. ....
  106. .mypicker.v-has-width > .mypicker-field {
  107. width: 100%;
  108. }
  109. ....
  110. With this additional CSS, the text field directly inside a picker that
  111. has a defined width gets full width.
  112. [[making-room-for-the-button-again]]
  113. Making room for the button again
  114. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  115. We're however not done yet. Setting the width of the text field to 100%
  116. makes it as wide as the main div is, which means that the button goes
  117. outside the main div. This can be verified using the DOM inspector in
  118. your browser or by setting `overflow: hidden` to the style for `mypicker`.
  119. To reserve space for the button, we can add some padding to the right
  120. edge of the main div element. This does however cause the padding space
  121. to remain unused if the component size is undefined. To compensate for
  122. this, negative margin can be added to the right edge of the button,
  123. effectively reducing its occupied size to 0px.
  124. Finally, we need to use `box-sizing: border-box` to make the field's
  125. borders and paddings be included in the 100% width.
  126. The full CSS for the sample component:
  127. [source,scss]
  128. ....
  129. .mypicker {
  130. white-space: nowrap;
  131. padding-right: 23px;
  132. }
  133. .mypicker-button {
  134. display: inline-block;
  135. border: 1px solid black;
  136. padding: 3px;
  137. width: 15px;
  138. text-align: center;
  139. margin-right: -23px;
  140. }
  141. .mypicker.v-has-width > .mypicker-field {
  142. width: 100%;
  143. }
  144. .mypicker-field {
  145. -moz-box-sizing: border-box;
  146. -webkit-boz-sizing: border-box;
  147. box-sizing: border-box;
  148. }
  149. ....