SwifWeb

MIT License Swift 5.7 Swift.Stream

这个库为你提供强大的自动布局功能,它完全基于 CSS3 ❤️

它将帮助你轻松地用你喜欢的 Swift 语言构建出色的响应式 Web 应用程序 ❤️

加入我们的聊天

discord

安装

将软件包添加到你的 SwifWeb 应用程序的 Package.swift

在 dependencies 部分

 dependencies: [
    .package(url: "https://github.com/swifweb/autolayout", from: "1.0.4")
]

在 target 部分

targets: [
    .executableTarget(name: "App", dependencies: [
        .product(name: "Web", package: "web"),
        .product(name: "Autolayout", package: "autolayout")
    ]
]

使用方法

现在你可以声明式地内联编写代码,而无需在样式表中构建复杂的 @media 规则。在底层,自动布局会处理复杂的优先级覆盖问题。

import Autolayout

// amazingly laconic and powerful
Div()
    .position(.relative)
    .position(.absolute, breakpoints: .xs, .s) // it will override relative with absolute for extra-small and small screens
    .height(100.px)
    .top()
    .backgroundColor(.brown)
    .widthToParent() // which is width: 100%
    .width(100.px, breakpoints: .xs, .s) // it will override 100% to 100px for extra-small and small screens
    .edges(h: 0.px) // which is left: 0px, right: 0px
    .centerX(breakpoints: .xs, .s) // it will disable right, and will set left: 50%, translate-x: -50% for extra-small and small screens
    .opacity(0.8, breakpoints: .xs, .s) // it will set opacity: 0.8 for extra-small and small screens

通过简单地声明下面列出的方法,即可在任何视图中使用它。但首先阅读有关断点的信息。

断点 (Breakpoints)

通常,我们必须在样式表中声明 @media 规则,这需要花费大量时间。

使用自动布局,你可以声明一次断点 (也就是 @media 规则),并将其用作别名。

这里为你预定义了一些断点

.xs or .extraSmall        // <576px
.s or .small              // ≥576px and <768px
.m or .medium             // ≥768px and <992px
.l or .large              // ≥992px and <1200px
.xl or .extraLarge        // ≥1200px and <1400px
.xxl or .extraExtraLarge  // ≥1400px

或者你可以声明自己的断点(请注意它们有多长)

extension MediaRule.MediaType {
    static var extraSmall: MediaRule.MediaType { .init(.all.maxWidth(575.px), label: "xs") }
    static var small: MediaRule.MediaType { .init(.all.minWidth(576.px).maxWidth(767.px), label: "s") }
    static var medium: MediaRule.MediaType { .init(.all.minWidth(768.px).maxWidth(991.px), label: "m") }
}

使用 label: "xs" 在源代码中美化你的断点,否则它将只使用整个规则文本

断点可以添加到任何自动布局方法的末尾。它在底层使用了 CSS3 @media 规则的全部功能。

.top(100.px, breakpoints: .extraSmall, .small, .medium)

或者你可以在经典的样式表中使用断点

@DOM override var body: DOM.Content {
    Stylesheet {
        Rule(Body.pointer)
            .margin(all: 0.px)
            .padding(all: 0.px)
        MediaRule(.xs, .s) { // will be applied only for extra-small and small screens
            Rule(Body.pointer)
                .backgroundColor(0x9bc4e2)
        }
        MediaRule(.m, .l, .xl) { // will be applied only for medium, large, and extra-large screens
            Rule(Body.pointer)
                .backgroundColor(0xffd700)
        }
    }
    // ...other elements...
}

方法

覆盖 (Overriding)

你可以为同一属性声明不同的值,但使用不同的断点

// will be applied in any case
.width(600.px)

// will override any other values when screen width is extra-small or small
.width(200.px, breakpoints: .xs, .s)

// will override any other values when screen width is medium or large
.width(400.px, breakpoints: .m, .l)

该库将处理覆盖优先级。

定位 (Positioning)

top, right, bottom, left, center, width, height 方法与元素及其父元素的 position 属性相关。

设置全局位置

如果你想全局设置这些属性(到窗口边界),请使用

.position(.absolute) // or .fixed, .sticky

设置相对位置

如果你想相对于其父元素设置这些属性,请使用

.position(.relative)

并且不要忘记它的父元素也应该有

.position(.relative)

或者它的父元素的父元素,等等

潜在的困惑

请不要忘记

.position(.static) // or if position haven't been set at all

只有 widthheight 属性有效,其他属性在这种情况下无法工作

每个方法也可以与 @State 值一起使用

Top (顶部)

指定 top 位置到具有相对位置的第一个父元素

Top to top (顶部对顶部)

// will set top to 0px
.top()

// will set top to 100px
.top(100.px)

// will set top to 50px
.top(100.px, multiplier: 0.5)

// will set top to 0px only for extra-small, small and medium screens
.top(breakpoints: .xs, .s, .m)

// will set top to 50px only for extra-small, small and medium screens
.top(50.px, breakpoints: .xs, .s, .m)

// will set top to 25px only for extra-small, small and medium screens
.top(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Top to center (顶部对中心)

只需添加 side: .center 作为第二个参数,top 边将粘附到具有相对位置的第一个父元素的 center

// will set top to 0px from the center
.top(side: .center)

// will set top to 100px from the center
.top(100.px, side: .center)

// will set top to 50px from the center
.top(100.px, side: .center, multiplier: 0.5)

// will set top to 0px from the center only for extra-small, small and medium screens
.top(side: .center, breakpoints: .xs, .s, .m)

// will set top to 50px from the center only for extra-small, small and medium screens
.top(50.px, side: .center, breakpoints: .xs, .s, .m)

// will set top to 25px from the center only for extra-small, small and medium screens
.top(50.px, side: .center, multiplier: 0.5, breakpoints: .xs, .s, .m)

Top to bottom (顶部对底部)

只需添加 side: .bottom 作为第二个参数,top 边将粘附到具有相对位置的第一个父元素的 bottom

// will set top to 0px from the bottom
.top(side: .bottom)

// will set top to 100px from the bottom
.top(100.px, side: .bottom)

// will set top to 50px from the bottom
.top(100.px, side: .bottom, multiplier: 0.5)

// will set top to 0px from the bottom only for extra-small, small and medium screens
.top(side: .bottom, breakpoints: .xs, .s, .m)

// will set top to 50px from the bottom only for extra-small, small and medium screens
.top(50.px, side: .bottom, breakpoints: .xs, .s, .m)

// will set top to 25px from the bottom only for extra-small, small and medium screens
.top(50.px, side: .bottom, multiplier: 0.5, breakpoints: .xs, .s, .m)

Bottom (底部)

指定 bottom 位置到具有相对位置的第一个父元素

Bottom to bottom (底部对底部)

// will set bottom to 0px
.bottom()

// will set bottom to 100px
.bottom(100.px)

// will set bottom to 50px
.bottom(100.px, multiplier: 0.5)

// will set bottom to 0px only for extra-small, small and medium screens
.bottom(breakpoints: .xs, .s, .m)

// will set bottom to 50px only for extra-small, small and medium screens
.bottom(50.px, breakpoints: .xs, .s, .m)

// will set bottom to 25px only for extra-small, small and medium screens
.bottom(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Bottom to center (底部对中心)

只需添加 side: .center 作为第二个参数,bottom 边将粘附到具有相对位置的第一个父元素的 center

// will set bottom to 0px from the center
.bottom(side: .center)

// will set bottom to 100px from the center
.bottom(100.px, side: .center)

// will set bottom to 50px from the center
.bottom(100.px, side: .center, multiplier: 0.5)

// will set bottom to 0px from the center only for extra-small, small and medium screens
.bottom(side: .center, breakpoints: .xs, .s, .m)

// will set bottom to 50px from the center only for extra-small, small and medium screens
.bottom(50.px, side: .center, breakpoints: .xs, .s, .m)

// will set bottom to 25px from the center only for extra-small, small and medium screens
.bottom(50.px, side: .center, multiplier: 0.5, breakpoints: .xs, .s, .m)

Bottom to top (底部对顶部)

只需添加 side: .top 作为第二个参数,bottom 边将粘附到具有相对位置的第一个父元素的 top

// will set bottom to 0px from the top
.bottom(side: .top)

// will set bottom to 100px from the top
.bottom(100.px, side: .top)

// will set bottom to 50px from the top
.bottom(100.px, side: .top, multiplier: 0.5)

// will set bottom to 0px from the top only for extra-small, small and medium screens
.bottom(side: .top, breakpoints: .xs, .s, .m)

// will set bottom to 50px from the top only for extra-small, small and medium screens
.bottom(50.px, side: .top, breakpoints: .xs, .s, .m)

// will set bottom to 25px from the top only for extra-small, small and medium screens
.bottom(50.px, side: .top, multiplier: 0.5, breakpoints: .xs, .s, .m)

Left (左侧)

指定 left 位置到具有相对位置的第一个父元素

Left to left (左侧对左侧)

// will set left to 0px
.left()

// will set left to 100px
.left(100.px)

// will set left to 50px
.left(100.px, multiplier: 0.5)

// will set left to 0px only for extra-small, small and medium screens
.left(breakpoints: .xs, .s, .m)

// will set left to 50px only for extra-small, small and medium screens
.left(50.px, breakpoints: .xs, .s, .m)

// will set left to 25px only for extra-small, small and medium screens
.left(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Left to center (左侧对中心)

只需添加 side: .center 作为第二个参数,left 边将粘附到具有相对位置的第一个父元素的 center

// will set left to 0px from the center
.left(side: .center)

// will set left to 100px from the center
.left(100.px, side: .center)

// will set left to 50px from the center
.left(100.px, side: .center, multiplier: 0.5)

// will set left to 0px from the center only for extra-small, small and medium screens
.left(side: .center, breakpoints: .xs, .s, .m)

// will set left to 50px from the center only for extra-small, small and medium screens
.left(50.px, side: .center, breakpoints: .xs, .s, .m)

// will set left to 25px from the center only for extra-small, small and medium screens
.left(50.px, side: .center, multiplier: 0.5, breakpoints: .xs, .s, .m)

Left to right (左侧对右侧)

只需添加 side: .right 作为第二个参数,left 边将粘附到具有相对位置的第一个父元素的 right

// will set left to 0px from the right
.left(side: .right)

// will set left to 100px from the right
.left(100.px, side: .right)

// will set left to 50px from the right
.left(100.px, side: .right, multiplier: 0.5)

// will set left to 0px from the right only for extra-small, small and medium screens
.left(side: .right, breakpoints: .xs, .s, .m)

// will set left to 50px from the right only for extra-small, small and medium screens
.left(50.px, side: .right, breakpoints: .xs, .s, .m)

// will set left to 25px from the right only for extra-small, small and medium screens
.left(50.px, side: .right, multiplier: 0.5, breakpoints: .xs, .s, .m)

Right (右侧)

指定 right 位置到具有相对位置的第一个父元素

Right to right (右侧对右侧)

// will set right to 0px
.right()

// will set right to 100px
.right(100.px)

// will set right to 50px
.right(100.px, multiplier: 0.5)

// will set right to 0px only for extra-small, small and medium screens
.right(breakpoints: .xs, .s, .m)

// will set right to 50px only for extra-small, small and medium screens
.right(50.px, breakpoints: .xs, .s, .m)

// will set right to 25px only for extra-small, small and medium screens
.right(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Right to center (右侧对中心)

只需添加 side: .center 作为第二个参数,right 边将粘附到具有相对位置的第一个父元素的 center

// will set right to 0px from the center
.right(side: .center)

// will set right to 100px from the center
.right(100.px, side: .center)

// will set right to 50px from the center
.right(100.px, side: .center, multiplier: 0.5)

// will set right to 0px from the center only for extra-small, small and medium screens
.right(side: .center, breakpoints: .xs, .s, .m)

// will set right to 50px from the center only for extra-small, small and medium screens
.right(50.px, side: .center, breakpoints: .xs, .s, .m)

// will set right to 25px from the center only for extra-small, small and medium screens
.right(50.px, side: .center, multiplier: 0.5, breakpoints: .xs, .s, .m)

Right to left (右侧对左侧)

只需添加 side: .left 作为第二个参数,right 边将粘附到具有相对位置的第一个父元素的 left

// will set right to 0px from the left
.right(side: .left)

// will set right to 100px from the left
.right(100.px, side: .left)

// will set right to 50px from the left
.right(100.px, side: .left, multiplier: 0.5)

// will set right to 0px from the left only for extra-small, small and medium screens
.right(side: .left, breakpoints: .xs, .s, .m)

// will set right to 50px from the left only for extra-small, small and medium screens
.right(50.px, side: .left, breakpoints: .xs, .s, .m)

// will set right to 25px from the left only for extra-small, small and medium screens
.right(50.px, side: .left, multiplier: 0.5, breakpoints: .xs, .s, .m)

Edges (边距)

所有边距的便捷设置器:top, right, bottom, left

所有边距

// Will set top, right, bottom, and left to 0px
.edges()

// Will set top, right, bottom, and left to 10px
.edges(10.px)

// Will set top, right, bottom, and left to 5px only for extra-small, small and medium screens
.edges(5.px, breakpoints: .xs, .s, .m)

水平边距

// Will set left and right to 0px
.edges(h: 0.px)

// Will set left and right to 10px
.edges(h: 10.px)

// Will set left and right to 5px only for extra-small, small and medium screens
.edges(h: 5.px, breakpoints: .xs, .s, .m)

垂直边距

// Will set top and bottom to 0px
.edges(v: 0.px)

// Will set top and bottom to 10px
.edges(v: 10.px)

// Will set top and bottom to 5px only for extra-small, small and medium screens
.edges(v: 5.px, breakpoints: .xs, .s, .m)

水平和垂直边距

// Will set left and right to 0px, and top and bottom to 0px
.edges(h: 0.px, v: 0.px)

// Will set left and right to 0px, and top and bottom to 10px
.edges(h: 0.px, v: 10.px)

// Will set left and right to 2px, and top and bottom to 4px only for extra-small, small and medium screens
.edges(h: 2.px, v: 4.px, breakpoints: .xs, .s, .m)

Center X (水平中心)

指定水平中心位置到具有相对位置的第一个父元素

Center to center (中心对中心)

// will set centerX to 0px
.centerX()

// will set centerX to 100px
.centerX(100.px)

// will set centerX to 50px
.centerX(100.px, multiplier: 0.5)

// will set centerX to 0px only for extra-small, small and medium screens
.centerX(breakpoints: .xs, .s, .m)

// will set centerX to 50px only for extra-small, small and medium screens
.centerX(50.px, breakpoints: .xs, .s, .m)

// will set centerX to 25px only for extra-small, small and medium screens
.centerX(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Center to left (中心对左侧)

只需添加 side: .left 作为第二个参数,centerX 边将粘附到具有相对位置的第一个父元素的 left

// will set centerX to 0px of the left
.centerX(side: .left)

// will set centerX to 100px of the left
.centerX(100.px, side: .left)

// will set centerX to 50px of the left
.centerX(100.px, side: .left, multiplier: 0.5)

// will set centerX to 0px of the left only for extra-small, small and medium screens
.centerX(side: .left, breakpoints: .xs, .s, .m)

// will set centerX to 50px of the left only for extra-small, small and medium screens
.centerX(50.px, side: .left, breakpoints: .xs, .s, .m)

// will set centerX to 25px of the left only for extra-small, small and medium screens
.centerX(50.px, side: .left, multiplier: 0.5, breakpoints: .xs, .s, .m)

Center to right (中心对右侧)

只需添加 side: .right 作为第二个参数,centerX 边将粘附到具有相对位置的第一个父元素的 right

// will set centerX to 0px of the right
.centerX(side: .right)

// will set centerX to 100px of the right
.centerX(100.px, side: .right)

// will set centerX to 50px of the right
.centerX(100.px, side: .right, multiplier: 0.5)

// will set centerX to 0px of the right only for extra-small, small and medium screens
.centerX(side: .right, breakpoints: .xs, .s, .m)

// will set centerX to 50px of the right only for extra-small, small and medium screens
.centerX(50.px, side: .right, breakpoints: .xs, .s, .m)

// will set centerX to 25px of the right only for extra-small, small and medium screens
.centerX(50.px, side: .right, multiplier: 0.5, breakpoints: .xs, .s, .m)

Center Y (垂直中心)

指定垂直中心位置到具有相对位置的第一个父元素

Center to center (中心对中心)

// will set centerY to 0px
.centerY()

// will set centerY to 100px
.centerY(100.px)

// will set centerY to 50px
.centerY(100.px, multiplier: 0.5)

// will set centerY to 0px only for extra-small, small and medium screens
.centerY(breakpoints: .xs, .s, .m)

// will set centerY to 50px only for extra-small, small and medium screens
.centerY(50.px, breakpoints: .xs, .s, .m)

// will set centerY to 25px only for extra-small, small and medium screens
.centerY(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Center to top (中心对顶部)

只需添加 side: .top 作为第二个参数,centerY 边将粘附到具有相对位置的第一个父元素的 top

// will set centerY to 0px of the top
.centerY(side: .top)

// will set centerY to 100px of the top
.centerY(100.px, side: .top)

// will set centerY to 50px of the top
.centerY(100.px, side: .top, multiplier: 0.5)

// will set centerY to 0px of the top only for extra-small, small and medium screens
.centerY(side: .top, breakpoints: .xs, .s, .m)

// will set centerY to 50px of the top only for extra-small, small and medium screens
.centerY(50.px, side: .top, breakpoints: .xs, .s, .m)

// will set centerY to 25px of the top only for extra-small, small and medium screens
.centerY(50.px, side: .top, multiplier: 0.5, breakpoints: .xs, .s, .m)

Center to bottom (中心对底部)

只需添加 side: .bottom 作为第二个参数,centerY 边将粘附到具有相对位置的第一个父元素的 bottom

// will set centerY to 0px of the bottom
.centerY(side: .bottom)

// will set centerY to 100px of the bottom
.centerY(100.px, side: .bottom)

// will set centerY to 50px of the bottom
.centerY(100.px, side: .bottom, multiplier: 0.5)

// will set centerY to 0px of the bottom only for extra-small, small and medium screens
.centerY(side: .bottom, breakpoints: .xs, .s, .m)

// will set centerY to 50px of the bottom only for extra-small, small and medium screens
.centerY(50.px, side: .bottom, breakpoints: .xs, .s, .m)

// will set centerY to 25px of the bottom only for extra-small, small and medium screens
.centerY(50.px, side: .bottom, multiplier: 0.5, breakpoints: .xs, .s, .m)

Center X+Y (水平和垂直中心)

指定垂直和水平中心位置到具有相对位置的第一个父元素

// will set centerX and centerY to 0px
.center()

// will set centerX and centerY to 100px
.center(100.px)

// will set centerX and centerY to 50px
.center(100.px, multiplier: 0.5)

// will set centerX and centerY to 0px only for extra-small, small and medium screens
.center(breakpoints: .xs, .s, .m)

// will set centerX and centerY to 50px only for extra-small, small and medium screens
.center(50.px, breakpoints: .xs, .s, .m)

// will set centerX and centerY to 25px only for extra-small, small and medium screens
.center(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Width (宽度)

设置元素的宽度

// will set width to 0px
.width()

// will set width to 100px
.width(100.px)

// will set width to 100%
.width(100.percent)

// will set width to 50px
.width(100.px, multiplier: 0.5)

// will set width to 0px only for extra-small, small and medium screens
.width(breakpoints: .xs, .s, .m)

// will set width to 50px only for extra-small, small and medium screens
.width(50.px, breakpoints: .xs, .s, .m)

// will set width to 25px only for extra-small, small and medium screens
.width(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Width to parent (宽度填充父元素)

设置元素的宽度以适合具有相对位置的第一个父元素

// will set width to 100% of first parent element with relative position
.widthToParent()

// will set width to 100% of first parent element with relative position only for extra-small, small and medium screens
.widthToParent(breakpoints: .xs, .s, .m)

// will set width to 100% + 100px of first parent element with relative position
.widthToParent(extra: 100.px)

// will set width to 100% + 100px of first parent element with relative position
// only for extra-small, small and medium screens
.widthToParent(extra: 100.px, breakpoints: .xs, .s, .m)

// will set width to (100% + 100px) * 0.5 of first parent element with relative position
.widthToParent(extra: 100.px, multiplier: 0.5)

// will set width to (100% + 100px) * 0.5 of first parent element with relative position
// only for extra-small, small and medium screens
.widthToParent(extra: 100.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

// will set width to 50% of first parent element with relative position
.widthToParent(multiplier: 0.5)

// will set width to 50% of first parent element with relative position
// only for extra-small, small and medium screens
.widthToParent(multiplier: 0.5, breakpoints: .xs, .s, .m)

Height (高度)

设置元素的高度

// will set height to 0px
.height()

// will set height to 100px
.height(100.px)

// will set height to 100%
.height(100.percent)

// will set height to 50px
.height(100.px, multiplier: 0.5)

// will set height to 0px only for extra-small, small and medium screens
.height(breakpoints: .xs, .s, .m)

// will set height to 50px only for extra-small, small and medium screens
.height(50.px, breakpoints: .xs, .s, .m)

// will set height to 25px only for extra-small, small and medium screens
.height(50.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

Height to parent (高度填充父元素)

设置元素的高度以适合具有相对位置的第一个父元素

// will set height to 100% of first parent element with relative position
.heightToParent()

// will set height to 100% of first parent element with relative position only for extra-small, small and medium screens
.heightToParent(breakpoints: .xs, .s, .m)

// will set height to 100% + 100px of first parent element with relative position
.heightToParent(extra: 100.px)

// will set height to 100% + 100px of first parent element with relative position
// only for extra-small, small and medium screens
.heightToParent(extra: 100.px, breakpoints: .xs, .s, .m)

// will set height to (100% + 100px) * 0.5 of first parent element with relative position
.heightToParent(extra: 100.px, multiplier: 0.5)

// will set height to (100% + 100px) * 0.5 of first parent element with relative position
// only for extra-small, small and medium screens
.heightToParent(extra: 100.px, multiplier: 0.5, breakpoints: .xs, .s, .m)

// will set height to 50% of first parent element with relative position
.heightToParent(multiplier: 0.5)

// will set height to 50% of first parent element with relative position
// only for extra-small, small and medium screens
.heightToParent(multiplier: 0.5, breakpoints: .xs, .s, .m)

Position (位置)

指定用于元素的定位方法类型 static, relative, absolute 或 fixed

// will set position to absolute
.position(.absolute)

// will set position to absolute only for extra-small, small and medium screens
.position(.absolute, breakpoints: .xs, .s, .m)

Display (显示)

指定应如何显示某个 HTML 元素

// will set display to block
.display(.block)

// will set display to block only for extra-small, small and medium screens
.display(.block, breakpoints: .xs, .s, .m)

Visibility (可见性)

指定元素是否可见

// will set visibility to visible
.visibility(.visible)

// will set visibility to hidden only for extra-small, small and medium screens
.visibility(.hidden, breakpoints: .xs, .s, .m)

Opacity (透明度)

设置元素的透明度级别

// will set opacity to 0.8
.opacity(0.8)

// will set opacity to 0.5 only for extra-small, small and medium screens
.opacity(0.5, breakpoints: .xs, .s, .m)

Live preview (实时预览)

要使其与实时预览一起工作,你需要指定所有样式或精确的自动布局样式

包括所有应用程序样式

class Welcome_Preview: WebPreview {
    override class var title: String { "Initial page" } // optional
    override class var width: UInt { 440 } // optional
    override class var height: UInt { 480 } // optional

    @Preview override class var content: Preview.Content {
        // add styles if needed
        AppStyles.all
        // add here as many elements as needed
        WelcomeViewController()
    }
}

包括精确的应用程序样式,包括自动布局样式

class Welcome_Preview: WebPreview {
    override class var title: String { "Initial page" } // optional
    override class var width: UInt { 440 } // optional
    override class var height: UInt { 480 } // optional

    @Preview override class var content: Preview.Content {
        // add styles if needed
        AppStyles.id(.mainStyle)
        AppStyles.id(.autolayoutStyles)
        // add here as many elements as needed
        WelcomeViewController()
    }
}