分组元素定位
迄今为止, 我们知道怎么在一个分组里面将元素进行水平或垂直定位。我们通常需要在分组内对元素的定位和尺寸进行更多的控制。为此,我们首先需要知道一个分组是怎么工作的。
一个元素的定位由他所属容器的布局样式决定。例如,在水平分组中的一个按钮在前面的按钮的右边。一个元素的尺寸由两个因素决定:元素期望的大小和用户指定的大小。元素期望的大小由该元素所包含的内容决定。例如,一个按钮的宽度由按钮上所显示文本的长度决定。
一般来说元素的大小仅够容纳它的内容。一些元素,像文本输入框会使用一个默认的尺寸。分组会分配足够的尺寸去将元素放在它里面。一个包括三个按钮的水平分组将会包含比三个按钮更多的宽度,插入一些填充。
在图片中,开始两个按钮为它们的文本提供了合适的尺寸。第三个按钮比较长因为它包含更多的内容。分组的宽度包含按钮间的填充空间和按钮的宽度总和。按钮的高度采用能够放置它的文本的合适尺寸。
宽度和高度属性
在窗口中你可能需要对元素的尺寸进行更多的控制。有更多的特性允许你去控制元素的尺寸。有一个快捷的方法可以通过在元素中简单添加
和 width
属性,更像你在HTML中的 height
img
标签的用法。下面展示了一个例子:
<button label="确认" width="100" height="40"/>
然而,不推荐这样做。这么做适用性不好且可能与某些主题不匹配。一个更好的方法是使用样式表属性,它可以像中HTML中的样式表一样工作。可以使用下面的CSS属性。
- width
- 指定元素的宽度。
- height
- 指定元素的高度。
随便设置这两属性中的一个,元素将会创建它的宽度和高度。如果你只指定一个尺寸属性,另一个需要被算出。这些样式表属性的尺寸可以指定一个数字后面跟着一个单位。
可伸缩元素
非伸缩元素可以很简单快捷地计算尺寸。它们的宽度和高度可以直接被指定,如果没有指定尺寸,元素的默认尺寸就是刚好能放下它的内容的大小。对于可伸缩元素,计算需要一点窍门。
可伸缩元素有一个可以设置为大于0的属性
。被用来设置在可伸缩性元素中可以扩展和收缩的有用填充空间。它们的默认尺寸可以像非伸缩元素一样被计算。下面的例子做了这个的演示:flex
<window orient="horizontal" xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <hbox> <button label="Yes" flex="1"/> <button label="No"/> <button label="I really don't know one way or the other"/> </hbox> </window>
这个窗口会像之前的图片所显示的一样。前面两个按钮将一个合适尺寸作为默认宽度,第三个按钮将会比较大因为它有一个较长的标签。第一个按钮被建成是可伸缩的,并且将所有的三元素放在一个分组里面。分组的宽度被设置成全部三个元素的总宽度(图片的宽度大约是430像素)。
如果你增加窗口的宽度,元素会被检查清楚它们是否是可伸缩的,然后被分配到填充的空白空间。按钮只是可伸缩元素,但它不会增加宽度。这是因为按钮所在的分组不是可伸缩的。一个非伸缩元素在空间有效时也不会改变尺寸,所以按钮不会比其他情况下变得更宽。因此,按钮不会变得更宽。
这个解决方案也用于创建可伸缩性的分组。于是,当你创建一个更宽的窗口时,因此分组会伸长以便填充多余的空间。因为分组比较大,更多的空余空间可以被放在它里面,放在它里面的可伸缩按钮可以填充有效空间而得到扩展。这会被许多内嵌的分组重复处理。
设置最小和最大尺寸
你可以允许一个元素能够扩展但限制它的尺寸不能比一个确定的尺寸更大。或者,你可设置一个最小尺寸。你可以通过以下四个属性来达到这个目的:
这个值的单位是像素。你也可以使用相应的CSS属性:min-width
, min-height
, max-width
和 max-height
。
这些属性只可以用于可伸缩元素。例如,设置一个最大高度,一个可伸缩的按钮将只能扩展到一个 确定的最大高度。你可以更改窗口的尺寸超过这个值但按钮会在指定的尺寸停止扩展。分组中的按钮将会一直扩展到你设置的分组最大高度时止。
如果两个按钮都具有相等的弹性值,普通情况下它们两个会共享相同的多余空间。如果一个按钮有一个最大宽度,第二个将会一直扩展直到用光所有的空间为止。
如果一个分组有一个最大宽度或高度,子分组不会扩展超出它的最大尺寸。如果一个分组有一个最小宽度或高度,它的子分组不能缩小到比它的最小尺寸更小。
设置宽度和高度的例子
<button label="1" style="width: 100px;"/> <button label="2" style="width: 100em; height: 10px;"/> <button label="3" flex="1" style="min-width: 50px;"/> <button label="4" flex="1" style="min-height: 2ex; max-width: 100px"/> <textbox flex="1" style="max-width: 10em;"/> <description style="max-width: 50px">This is some boring but simple wrapping text.</description>
- 例1
- 第一个按钮将显示成宽度为100像素的(px 的意思是像素)。你必须增加单位否则宽度将被忽略。
- 例2
- 第二个按钮将显示成高度为10像素和宽度为100em(em是当前字体一个字符的尺寸)。
- 例3
- 第三个按钮是可伸缩的所以它可以基于包含它的分组的尺寸进行扩展。然而,按钮不能收缩到比50像素更小。其它可伸缩组件像定位格可以吸收保留空间,而不管弹性比率。
- 例4
- 第四个按钮是可伸缩的并且不能有一个比2ex(ex是当前字体中的字母x的高度)小的高度或比100像素更大的宽度。
- 例5
- 文本输入框是可伸缩的但不能扩展超过10em。你会经常去使用em单位作为指定文本内容它们的尺寸。这个单位用于文本输入框因此字体可以更改并且文本输入框可以一直有个合适的尺寸,如果字体非常大时也一样。
- 例6
元素包含50像素的最大宽度。在50像素后,文本会自动被截到下一行。description
我们的文件查找对话框
让我们将这些样式增加到文件查找对话框。我们将会创建它因此文本输入框可以在输入窗口中改变尺寸。
<textbox id="find-text" flex="1" style="min-width: 15em;"/>
在这里,文本输入框被做成可伸缩的。这样,它可以在用户改变对话框的尺寸时进行扩展。这可以用于如果用户想要输入一个很长的文本字符串时。通常地,设置了一个最小宽度为15em则输入框会一直显示为至少15个字符的宽度。如果用户更改对话框的尺寸到很小,文本输入框不会缩小超过15个字符长度。在窗口里面的输入框将会被画出来,并超出窗口的范围。注解:在图片中文本输入框被扩展为充满窗口的尺寸。Box Packing
Let's say you have a box with two child elements, both of which are not flexible, but the box is flexible. For example:
<box flex="1"> <button label="Happy"/> <button label="Sad"/> </box>
If you resize the window, the box will stretch to fit the window size. The buttons are not flexible, so they will not change their widths. The result is extra space that will appear on the right side of the window, inside the box. You may wish, however, for the extra space to appear on the left side instead, so that the buttons stay right aligned in the window.
You could accomplish this by placing a
inside the box, but that gets messy when you have to do it numerous times. A better way is to use an additional attribute spacer
on the pack
. This attribute indicates how to box
the child elements inside the box. For horizontally oriented boxes, it controls the horizonal positioning of the children. For vertically oriented boxes, it controls the vertical positioning of the children. You can use the following values:pack
- start
- This positions elements at the left edge for horizontal boxes and at the top edge for vertical boxes. This is the default value.
- center
- This centers the child elements in the box.
- end
- This positions elements at the right edge for horizontal boxes and at the bottom edge for vertical boxes.
The
attribute applies to the box containing the elements to be packed, not to the elements themselves.pack
We can change the earlier example to center the elements as follows:
<box flex="1" pack="center"> <button label="Happy"/> <button label="Sad"/> </box>
Now, when the window is resized, the buttons center themselves horizontally. Compare this behavior to that of the previous example.
Box Alignment
If you resize the window in the Happy-Sad example above horizontally, the box will grow in width. If you resize the window vertically however, you will note that the buttons grow in height. This is because the flexibility is assumed by default in the other direction.
You can control this behavior with the
attribute. For horizontal boxes, it controls the position of the children vertically. For vertical boxes, it controls the position of the children horizontally. The possible values are similar to those for align
.pack
- start
- This aligns elements along the top edge for horizontal boxes and along the left edge for vertical boxes.
- center
- This centers the child elements in the box.
- end
- This aligns elements along the bottom edge for horizontal boxes and along the right edge for vertical boxes.
- baseline
- This aligns the elements so that the text lines up. This is only useful for horizontal boxes.
- stretch
- This value, the default, causes the elements to grow to fit the size of the box, much like a flexible element, but in the opposite direction.
As with the
attribute, the pack
attribute applies to the box containing the elements to be aligned, not to the elements themselves.align
For example, the first box below will have its children stretch, because that is the default. The second box has an
attribute, so its children will be placed centered.align
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <window id="yesno" title="Question" orient="horizontal" xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <hbox> <button label="Yes"/> <button label="No"/> </hbox> <hbox align="center"> <button label="Maybe"/> <button label="Perhaps"/> </hbox> </window>
You can also use the style properties -moz-box-pack
and -moz-box-align
instead of specifying attributes.
Cropping Text and Buttons
You could potentially create a button element that contains a label that is larger than the maximum width of the button. Of course, a solution would be to increase the size of the button. However, buttons (and other elements with a label) have a special attribute called crop
that allows you to specify how the text may be cropped if it is too big.
If the text is cropped, an ellipsis (...) will appear on the button where the text was taken out. Four possible values are valid:
- left
- The text is cropped on its left side
- right
- The text is cropped on its right side
- center
- The text is cropped in the middle.
- none
- The text is not cropped. This is the default value.
This attribute is really only useful when a dialog has been designed to be useful at any size. The crop
attribute can also be used with other elements that use the label
attribute for labels. The following shows this attribute in use:
<button label="Push Me Please!" crop="right" flex="1"/>
Notice how the text on the button has had the right side of it cropped after the window is made smaller.
Next, a summary and some additional details of the box model are described.