外观
布局
元素使用 flexbox 布局其子元素,如同 CSS,或者使用网格,单位为与设备无关的像素(DIP):
go
ui.Row(c).Gap(8).Padding(12).Children(func() {
ui.Icon(c, folder)
ui.Text(c, "Documents").Grow(1)
ui.Text(c, "12 items").TextColor(c.Theme().TextMuted)
})容器
ui.Column自上而下堆叠子元素,并把它们拉伸到自己的宽度;ui.Box也是一个列。ui.Row从左到右排列子元素,并使其垂直居中。Reverse则朝反方向布局,从右或从下开始,如同 CSS 的row-reverse和column-reverse。ui.Spacer占据其所在行或列的剩余空间,把兄弟元素推开;ui.Divider在其行或列上画一条细线。Dividers(width, color)在行、列或列表的每两个子元素之间画一条线,位于二者间隙的正中且不会加宽间隙:请给元素设置不小于线宽的Gap。ui.Grid以列和行布局其子元素:参见网格。可滚动的容器是滚动视图,列表只构建可见的行。
尺寸
Width、Height和Size设定尺寸;WidthPercent和HeightPercent取父元素的一定比例;MinWidth、MaxWidth、MinHeight和MaxHeight加以限制,它们的Percent形式按父元素的比例限制;Fill、FillWidth和FillHeight占满父元素整个内容盒。Grow(1)让元素沿父元素的主轴方向占据剩余空间,如同flex: 1:填满窗口剩余部分的列表,或把其后的元素推到底的Spacer。Shrink、Basis和BasisPercent的用法与 CSS 相同。AspectRatio保持元素的比例。
间距
Gap 设置子元素之间的间距,GapX 和 GapY 分别设置水平和垂直间距;Padding 和 Margin 接受一个、两个或四个值,如同 CSS;PaddingX、PaddingY、MarginX 和 MarginY 设置两侧。值为 ui.Auto 的外边距会占据该侧的剩余空间,如同 CSS:Margin(0, ui.Auto) 让元素在列中水平居中,Margin(0, 0, 0, ui.Auto) 把行中的子元素及其后的元素推向右侧。
PaddingStart 和 PaddingEnd、MarginStart 和 MarginEnd、BorderStartWidth 和 BorderEndWidth 分别设置线条起始的一侧和另一侧:即左和右;对于从右到左布局的元素则是右和左,如同 CSS 的逻辑属性。MarginStart(ui.Auto) 无论方向如何,都把行中的子元素推向其末端。
对齐
Justify 沿主轴方向排列子元素(Start、Center、End、SpaceBetween、SpaceAround、SpaceEvenly),AlignItems 沿交叉方向对齐它们(Start、Center、End、Stretch、Baseline),AlignSelf 对齐单个子元素;Center 在两个方向上都居中。Start 是行的左侧和列的顶部;对于从右到左布局的元素则是右侧,行也从那里开始排列。Wrap 让一行折到多行,WrapReverse 使这些行向上堆叠,AlignContent 排列这些行(如同 Justify 排列子元素,或 Stretch)。
Baseline 让行中各子元素文本的首行对齐,就像大号价格旁边的小号单位,行的高度以容纳对齐所需为准。盒子的基线是其第一个子元素的基线(在行中,是第一个按基线对齐的子元素的基线);没有文本的子元素以其底边对齐,如同 CSS:
go
ui.Row(c).AlignItems(ui.Baseline).Gap(4).Children(func() {
ui.Text(c, "$42").FontSize(40)
ui.Text(c, "/month").TextColor(t.TextMuted)
})定位
Absolute 让元素脱离文档流,用 Top、Right、Bottom 和 Left 在父元素中定位,单位为 DIP,或用 TopPercent 等按百分比;自动外边距会使其在所定位的两边之间居中。与 CSS 一样,这些值从父元素边框内侧量起,与其内边距无关:在边框宽 1 DIP 的盒子中,Top(0) 位于盒子上边缘下方 1 DIP 处。Start 和 End(以及 StartPercent、EndPercent)从线条起始的一侧和另一侧定位,在从右到左布局中它们分别是右和左。对于在文档流中的元素,Top 等属性让它从布局放置的位置移动,而不影响兄弟元素,如同 CSS 的相对定位:例如把徽标稍微抬高到文本之上。
go
ui.Box(c).Size(40, 40).Children(func() {
ui.Icon(c, bell).FontSize(24)
ui.Badge(c, "3").Absolute().Top(-4).Right(-6)
})Attach(at, self) 同样让元素脱离文档流,并把元素上的一个点(self)放到父元素盒子上的一个点(at):可以是角、边的中点或中心,如 ui.AnchorTopRight 或 ui.AnchorCenter;也可以是线条起始或结束一侧的点,如 ui.AnchorTopEnd,在从右到左布局中它位于左侧。元素保持自身大小,Top、Right、Bottom 和 Left 在此基础上继续移动它:
go
ui.Box(c).Children(func() {
ui.Avatar(c, "Ada Lovelace", nil)
// 无论头像多大,都居中于其右上角。
ui.Badge(c, "3").Attach(ui.AnchorTopRight, ui.AnchorCenter)
})
ui.Box(c).Fill().Children(func() {
ui.PrimaryButton(c, "New").Attach(ui.AnchorBottomRight, ui.AnchorBottomRight).Right(16).Bottom(16)
})裁剪与可见性
Clip把子元素裁剪到自己的圆角盒子内,即边框之内,边框绘制在它们之上;ClipX和ClipY只裁剪左右两侧或上下两侧。Invisible隐藏元素及其子元素,它们仍占着位置,但不绘制任何内容,也不接收指针和焦点,如同 CSS 的visibility: hidden。Hidden(true)隐藏它们并收回其占位,如同 CSS 的display: none:兄弟元素合拢,不留间隙,辅助技术也不会读取它。与不构建该元素不同,它保留内部内容的状态——滚动偏移、正在编辑的文本、动画——以便Hidden(false)重新显示时恢复。隐藏时焦点会离开它,附着在它上面的元素(AttachTo)也随之隐藏。goui.Column(c).Hidden(!app.showDetails).Children(func() { ui.TextArea(c, &app.notes) })Debug勾画出元素及其内部一切,连同它们的内边距与外边距,以便看清布局为何如此。检查器会显示每个元素的盒子及其成因。借助过渡,元素可以平滑地移动、缩放和变色。