Layouts
Layouts create a flexible structure for your user interface. The layouts in this module are based on the Every Layout Book. If you haven't read the book, go read it now:
These layouts allow us to create complex user interfaces with minimal CSS which are responsive and readable on all devices. The layouts can be combined together.
All layouts are located in the ludic.catalog.layouts
module.
Ideology
#In this module, layouts are designed as simple, reusable components that you can easily combine to create responsive, readable, and maintainable user interfaces. Instead of starting from scratch with basic HTML elements and manually writing CSS, you use these layouts as your foundational building blocks. This approach allows you to compose and arrange them in various ways to design your desired user interface, making your code more organized and easier to manage.
A New Way of Thinking About DesignWhen writing CSS, you might be tempted to apply e.g. specific spacing, colors, or font styles to an HTML element like a button. The idea of using the layout classes here is to define context which determines how an HTML element should be displayed. So for example, we might want to have a couple of buttons on one line, so we wrap them in a Cluster class which inserts a margin between all its children and puts them on one line. In another context, we want to widen a button so that it uses all available space and is displayed like a block element. In that case we use the Stack class.
To illustrate this concept, here is a button wrapped in a Cluster:
Here are the buttons wrapped in a Stack:
Let's see the code:
from ludic.catalog.buttons import Button from ludic.catalog.layouts import Cluster, Stack Cluster(Button("In a Cluster"), Button("In a Cluster")) Stack(Button("In a Stack"), Button("In a Stack"))
Stack
#In the Stack layout, there's margin inserted between all its children elements, and each child occupies all the available horizontal space. So, essentially, each child stretches out horizontally as much as possible, with margins separating them.
Example
Usage
from ludic.catalog.layouts import Stack from ludic.html import div Stack( div("One"), div("Two"), div("Three"), )
Use Cases
- Separating paragraphs in large texts
- Creating a list of posts on a blog site
- Separating menu and body on a page
Box
#The Box layout adds padding around its content from all directions. This means that there is an equal amount of space between the content and the edges of the box, including the left, right, top, and bottom sides. By default, the Box also includes a border and a background that is not transparent.
Example
Usage
from ludic.catalog.layouts import Box Box("Content")
Use Cases
- Creating a page menu or sidebar
- Making important text stand out on a page
- Using it to highlight a list of actions (buttons)
Center
#The Center layout ensures that its content stays centered on the page. It sets a maximum width for this content. If the content's width exceeds this maximum, instead of extending beyond the sides of the page, equal margins are created on both sides to keep the content centered.
Example
Usage
from ludic.catalog.layouts import Center, Stack from ludic.catalog.typography import Paragraph Center( Stack( Paragraph("Lorem ipsum"), Paragraph("Lorem ipsum"), ) )
Use Cases
- Main content of a web page
- Ideal layout for blog sites
Cluster
#The Cluster layout, when applied, adds margin between all of its inline children elements. It arranges all of its children elements on a single line until there is enough space on the page. It's important to note that the cluster layout is not intended to be used for block-level children elements like paragraphs.
Example
Usage
from ludic.catalog.buttons import Button, ButtonPrimary from ludic.catalog.layouts import Cluster Cluster( Button("Cancel"), ButtonPrimary("Save"), )
Use Cases
- Groups of elements that differ in length
- Buttons appearing together at the end of a form
- A list of tags or keywords
Sidebar
#The Sidebar layout enables you to have two blocks on a page with equal height but different widths. Typically, the sidebar is narrower than the main content area. If there isn't enough space to display both the sidebar and the main content side by side, the layout adjusts into a stack-like format, where one block is stacked on top of the other.
Example
Usage
from ludic.catalog.layouts import Box, Sidebar, Stack, WithSidebar from ludic.catalog.typography import Paragraph WithSidebar( Sidebar( div("My Sidebar"), ), Stack( H1("Content"), Paragraph("Lorem ipsum"), ), )
Use Cases
- A page with menu and content
- A list of actions next to a form
Right Sidebar
#You can also have the sidebar on the right side instead of left.
Example
Usage
from ludic.catalog.layouts import Box, Sidebar, Stack, WithSidebar from ludic.catalog.typography import Paragraph WithSidebar( Stack( H1("Content"), Paragraph("Lorem ipsum"), ), Sidebar( div("My Sidebar"), ), )
Switcher
#The Switcher layout ensures that all of its children elements have the same width until there is enough space available to display their content. However, if the layout is placed on a page where there isn't sufficient room, it collapses and switches to a stack-like format for display.
Example
Usage
from ludic.catalog.layouts import Switcher from ludic.html import div Switcher( div("One"), div("Two"), div("Three"), )
Use Cases
- Card components advertising products
Cover
#The Cover layout consists of a header, content and footer. The header is placed above the content and the footer is placed below. The content is centered both horizontally and vertically.
Example
Title
Usage
from ludic.catalog.layouts import Cover Cover( div("Header"), h1("Title"), div("Footer"), )
Use Cases
- Introductory page for a website
Grid
#The Grid layout creates a grid of blocks with equal height and width.
Example
Usage
from ludic.catalog.layouts import Grid Grid( div("One"), div("Two"), div("Three"), div("Four"), div("Five"), )
Use Cases
- Teasers for permalinks or products
Frame
#The Frame layout maintains aspect ratio even if it means the content needs to be cropped.
Example
Frame Content
Usage
from ludic.catalog.layouts import Frame from ludic.html import img Frame( img(src="/path/to/image", alt="my image"), )
Use Cases
- cropping media (videos and images) to a desired aspect ratio
Complex Example
#You are free to combine layouts and components together. The following is an example of a complex layout consisting of multiple nested layouts mentioned in this tutorial.
Open Layout In New TabSlightly modified code of the layout is shown below.
Center( Stack( Box( Cluster( b("Inverse Boxed Cluster Menu"), Cluster( Button("Item 1"), ... ), classes=["justify-space-between"], ), classes=["invert"], ), WithSidebar( Stack( H2("Stack", anchor=False), Paragraph(...), H3("Switcher", anchor=False), Switcher( Box("Switcher Item 1"), ... ), H3("Cluster In a Box", anchor=False), Box( Cluster( ButtonPrimary("Cluster Button 1"), ..., ), ), H3("Grid Advertisement", anchor=False), Grid(Box(...), ...), ), Sidebar( Box( Stack( H3("Sidebar", anchor=False), Button("The Sidebar Item 1"), ... ), ), ), ), classes=["large"], ), style={"margin-block": "2rem"}, )