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 Widget
s 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
Panel
s 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 Widget
s with special behaviour that relate to
layout and styling:
LabelledBlockInput
- This
Widget
wraps around anInput
, and adds aLabel
to it. The combination of theInput
and itsLabel
are then arranged in two columns next to each other. SuccessiveLabelledBlockInput
s appear underneath each other, with all theLabel
s aligned and all the Inputs aligned. LabelledInlineInput
- A
LabelledInlineInput
also wraps around anInput
and adds aLabel
. 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
Widget
s to make them stand out amongst their peers. This concept is called the “priority” of aWidget
. Normally, you would not specify the priority of aWidget
. But, amongst chosen grouping ofWidget
s, you may set oneWidget
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). AWidget
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 addWidget
s, stating their priority (or lack of it). ThePriorityGroup
will ensure that only one of theWidget
s added to it will ever have primary priority. (Many could have no priority set, and many could be secondary.)
Styling¶
Complex Widget
s 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”>. Widget
s 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 Widget
s (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 Layout
s.)
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 Widget
s 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 Widget
s, and later customise this look to your
liking. For this reason, a stylesheet is provided which includes
styling for all the standard Reahl Widget
s. 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).