Layout and styling

Styling is probably not the first thing a programmer wants to worry about. That is why Reahl comes with some styling you can use when starting a project – perhaps to be replaced by a graphic designer later. (We hope to improve on this in future.)

Layout you can’t completely get away from though, and Reahl has concepts to help with this. Let us detour to introduce layout and styling ideas because that will allow us to use better layout further on in the tutorial to make our examples look just a little bit better.

Layout

A Layout is used to change what a Widget looks like, what css classes are attached to it for styling, or even how children Widgets are added to it – all for the purpose of influencing look and layout.

A Widget is configured to use a particular Layout by calling use_layout() on the Widget after construction. (You can also call use_layout() where you construct only a WidgetFactory for later use.) For example, the HorizontalLayout or VerticalLayout can be used to make a Menu appear with its items horizontally next to each other or stacked vertically.

The pure module includes some layouts based on the Pure.css framework. The ColumnLayout changes a Widget by adding several Panels to it that are arranged in columns next to each other. You can specify the size of these columns, and in such a way that the size can change, depending on the size of the device used for viewing. See the documentation for ColumnLayout and UnitSize for more details.

PageColumnLayout is meant to be used with an HTML5Page. It changes the page to have a header and footer with several columns inbetween.

Here is an example of how these Layouts are used to change a page and a Menu on that page:

class MyCustomPage(HTML5Page):
    def __init__(self, view, bookmarks):
        super(MyCustomPage, self).__init__(view, style='basic')

        columns_needed = [('secondary', UnitSize('1/4')), 
                          ('main', UnitSize('3/4'))]
        self.use_layout(PageColumnLayout(*columns_needed))

        menu = Menu.from_bookmarks(view, bookmarks)
        menu.use_layout(HorizontalLayout())
        self.layout.header.add_child(menu)

Special Widgets

There are also some Widgets with special behaviour that relate to layout and styling:

LabelledBlockInput
This Widget wraps around an Input, and adds a Label to it. The combination of the Input and its Label are then arranged in two columns next to each other. Successive LabelledBlockInputs appear underneath each other, with all the Labels aligned and all the Inputs aligned.
LabelledInlineInput
A LabelledInlineInput also wraps around an Input and adds a Label. The result though is an element that flows with text and can be used as part of a paragraph (P), for example.
PriorityGroup

Sometimes it is useful to visually highlight certain Widgets to make them stand out amongst their peers. This concept is called the “priority” of a Widget. Normally, you would not specify the priority of a Widget. But, amongst chosen grouping of Widgets, you may set one Widget as having “primary” priority, with the others having “secondary” priority.

A Widget with “secondary” priority will have a CSS class reahl-priority-secondary attached to it, which is normally styled such that it fades a bit into the background (perhaps lighter, or slightly greyed out). A Widget with “primary” priority will have CSS class reahl-priority-primary which is normally styled such that it stands out visually.

The PriorityGroup is an object to which you can add Widgets, stating their priority (or lack of it). The PriorityGroup will ensure that only one of the Widgets added to it will ever have primary priority. (Many could have no priority set, and many could be secondary.)

Styling

Complex Widgets in Reahl are written such that the Widget has an identifiable HTML element that represents the Widget. Identifiable means that the HTML element has an id or class attribute which can be used as target of CSS selectors. This allows for CSS to be attached to each Widget (or its contents). For example, the TabbedPanel is in a <div class=”reahl-tabbedpanel”>. Widgets that map one-to-one to HTML tags do not have special classes – they can be targeted in CSS by just using the HTML tag name they represent: the reahl.web.ui.P Widget is just a <p>, for example.

Given these ways to be able to target a Widget via CSS, you can write normal CSS to provide your own look and feel for Reahl Widgets (if you really want to). In the reference documentation for each Widget an explanation is given of what the HTML for that Widget looks like, for this purpose. (Similar documentation is provided with Layouts.)

In order to use your own CSS on a page, you need to add a link to it on your HTML5Page subclass. For example in the __init__ of your class, you can write:

self.head.add_css(Url('/link/to/my/own.css'))

The minutae of what Widgets look like is probably not the first thing on a programmer’s mind however. It is useful just to start programming using some look for the Widgets, and later customise this look to your liking. For this reason, a stylesheet is provided which includes styling for all the standard Reahl Widgets. You can include this style by adding it to the Head of your HTML5Page:

self.head.add_css(Url('/styles/basic.css'))

If you are using the HTML5Page as a page, the same effect can be accomplished by merely passing style='basic' to its constructor (as can be seen in almost all of our code examples so far).

Table Of Contents

Previous topic

Buttons allow users to act

Next topic

Moving between Views