Laying out elements on the screen is always a challenge for web developers. Nobody remembers how to do it, especially 😁 because it is not as simple as in mobile development, it is different. vertically Every time I switch to web development I miss the autolayout feature, classic CSS layout paradigm literally makes me cry sometimes, so at some point I decided that I have to have some library that can make my web dev life much simpler. I spent few days making one and named it 📏 Autolayout The first idea was to make it work exactly the same way as constraints work on iOS. I was so sure that it was possible, so I started working on it and implemented it. It worked great until I had only a few elements on the screen. However, with a lot of elements, I faced a huge amount of redraws. So, I realized there was an issue and accepted defeat, at least for the time being. Here’s the branch with it. But did I give up? No! It is art for me and I had to build a great solution to keep my code beautiful and easy to maintain! I implemented autolayout in pure CSS! Well not everything. It doesn’t have an ability to stick side or size to another view since CSS doesn’t have mechanisms for that. But it is something on the same level! Just take a look! So How Does It Work? First, you can do basic and complex things declaratively. Second, instead of building complex @media rules, you can now declare them inline. Also takes care of solving complex overriding priority issues behind the scenes. Autolayout Let’s assume you have a Div and you want to set the width to 600px. Div().width(600.px) But now you want to have a different width for different screen sizes. Div().width(600.px) // will be used for extra large screens .width(200.px, breakpoints: .xs, .s) // for extra small and small screens .width(400.px, breakpoints: .m, .l) // for medium and large screens Got the idea? Yeah it‘s cool! But now you probably want to know more about the breakpoints. Breakpoints .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 Yeah, it's a classic pattern that you may have seen before in Bootstrap or other UI frameworks. You also can declare your own (just notice how long they are): 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") } } Use to prettify your breakpoint in the source code. label: "xs" Otherwise it will use just the whole rule text. Breakpoints can be added to the end of any autolayout-method. .top(100.px, breakpoints: .extraSmall, .small, .medium) And you can use breakpoints within the classic stylesheet. Stylesheet { Rule(Body.pointer) .margin(all: 0.px) .padding(all: 0.px) MediaRule(.extraSmall, .small) { // will be applied only for extra-small and small screens Rule(Body.pointer) .backgroundColor(0x9bc4e2) } MediaRule(.medium, .large, .extraLarge) { // will be applied only for medium, large, and extra-large screens Rule(Body.pointer) .backgroundColor(0xffd700) } } What Methods Are Available? Size All of the methods have as a last argument. breakpoints: and are simple, I just added and convenience methods to be able to expand the view to its parent size. width height widthToParent heightToParent Sides Let’s talk about , , , . top right bottom left Please just keep in mind that these methods don’t work with position. static Sticking the view to the certain sides: .top() // will set top to 0px .bottom() // will set bottom to 0px .left() // will set left to 0px .right() // will set right to 0px All of the methods above can be used with a value and reactive value. @State // will set top to 0px only for extra-small, small and medium screens .top(breakpoints: .xs, .s, .m) .top(100.px) // will set top to 100px .top(100.px, multiplier: 0.5) // will set top to 50px // 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) Same for , , and . bottom left right But there are extra convenience methods! You can stick all of these sides to the center of parent or to the opposite side. Let’s take a look at the and examples: top to center top to bottom .top(side: .center) // will set top to 0px from the center .top(100.px, side: .center) // will set top to 100px from the center // 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) // multiplier is also available can stick to and Top center bottom can stick to and Bottom center top can stick to and Left center right can stick to and Right center left I believe you got the idea! 😀 But that is not all! I have more convenient methods for you! All sides // All sides .edges() // will set top, right, bottom, and left to 0px .edges(10.px) // will set top, right, bottom, and left to 10px .edges(5.px, breakpoints: .xs, .s, .m) // you know, only for certain screens Horizontal .edges(h: 0.px) // left and right to 0px .edges(h: 10.px) // left and right to 10px .edges(h: 5.px, breakpoints: .xs, .s, .m) Vertical .edges(v: 0.px) // top and bottom to 0px .edges(v: 10.px) // top and bottom to 10px .edges(v: 5.px, breakpoints: .xs, .s, .m) Both .edges(h: 0.px, v: 0.px) // left and right to 0px, and top and bottom to 0px .edges(h: 0.px, v: 10.px) // left and right to 0px, and top and bottom to 10px .edges(h: 2.px, v: 4.px, breakpoints: .xs, .s, .m) Centering Finally! So how to center the Div? 😁 😁 😁 Not that fast, we usually pronounce X and Y, so horizontal centering first! 😁 Center X .centerX() // will set centerX to 0px .centerX(100.px) // will set centerX to 100px .centerX(breakpoints: .xs, .s, .m) // center horizontally only for certain screens .centerX(50.px, breakpoints: .xs, .s, .m) Center Y (yeah!) .centerY() // will set centerY to 0px .centerY(100.px) // will set centerY to 100px .centerY(breakpoints: .xs, .s, .m) // center vertically only for certain screens .centerY(50.px, breakpoints: .xs, .s, .m) Also with side: extra argument! and for horizontal .left .right .centerX(side: .left) // centerX to 0px of the left .centerX(100.px, side: .right) // centerX to 100px of the right .centerX(side: .left, breakpoints: .xs, .s, .m) .centerX(50.px, side: .left, breakpoints: .xs, .s, .m) and for vertical .top .bottom .centerY(side: .top) // centerY to 0px of the top .centerY(100.px, side: .bottom) // centerY to 100px of the bottom .centerY(side: .top, breakpoints: .xs, .s, .m) .centerY(50.px, side: .top, breakpoints: .xs, .s, .m) Center for both X and Y .center() // centerX and centerY to 0px .center(100.px) // centerX and centerY to 100px .center(breakpoints: .xs, .s, .m) // centerX and centerY to 0px only certain screens .center(50.px, breakpoints: .xs, .s, .m) // you got the idea! Yeah, you should already feel the infinite power! 😎 Positioning Control the type of positioning like with the breakpoints: static, relative, absolute, fixed // set the position to absolute .position(.absolute) // set the position to fixed for certain screens .position(.fixed, breakpoints: .xs, .s, .m) Visibility Display .display(.block) .display(.none, breakpoints: .xs, .s, .m) Visibility .visibility(.visible) .visibility(.hidden, breakpoints: .xs, .s, .m) Opacity .opacity(1) .opacity(0, breakpoints: .xs, .s, .m) Does It Work With LivePreview? Yes! I know you really need it during the prototyping! To make it work just add into either: Preview.Content or AppStyles.all AppStyles.id(.autolayoutStyles) How To Install the Library? If you are new to then you have to create a new project using the Webber CLI tool. SwifWeb In the project open and edit section to make it look like this: Package.swift dependencies dependencies: [ // the rest of the other dependencies incuding swifweb/web .package(url: "https://github.com/swifweb/autolayout", from: "1.0.0"), ] Then edit to make it look like this: executableTarget .executableTarget(name: "App", dependencies: [ .product(name: "Web", package: "web"), .product(name: "Autolayout", package: "autolayout") ]), Next, just where needed. import Autolayout That’s it! Wanna learn more? Stay tuned for the upcoming articles! Don’t hesitate to ask any questions and feel free to contribute! in our Discord