A (partial) implementation of the CSS box and flexbox layout algorithm.
The following CSS attributes and value types are supported:
Name | Value |
---|---|
width, height | positive number |
min_width, min_height | positive number |
max_width, max_height | positive number |
left, right, top, bottom | number |
margin, margin_left, margin_right, margin_top, margin_bottom | number |
padding, padding_left, padding_right, padding_top, padding_bottom | positive number |
border_width, border_left_width, border_right_width, border_top_width, border_bottom_width | positive number |
flex_direction | "column" , "row" |
justify_content | "flex-start" , "center" , "flex-end" , "space-between" , "space-around" |
align_items, align_self | "flex-start" , "center" , "flex-end" , "stretch" |
flex | positive number |
flex_wrap | "wrap" , "nowrap" |
position | "relative" , "absolute" |
In your virtualenv, install Colosseum:
$ pip install colosseum
Colosseum provides a CSS
class that allows you to define CSS
properties, and apply them can be applied to any DOM-like tree of
objects. There is no required base class; Colosseum will duck-type
any object providing the required API. The simplest possible DOM
node is the following:
- class MyDOMNode(object):
- def __init__(self, style, children):
self.parent = None self.children = [] if children:
- for child in children:
- self.add(child)
self.style = style.apply(self)
- def add(self, child):
self.children.append(child) child.parent = self.parent if self.parent:
self.parent.dirty = True
That is, a node must provide:
- a
parent
attribute, declaring the parent in the DOM tree; the root of the DOM tree has aparent
ofNone
. - a
children
attribute, containing the list of DOM child nodes. - a
style
attribute, generated by callingapply()
on aCSS
declaration.
With that a compliant DOM node definition, you can then and query the layout that results:
>>> from colosseum import CSS, ROW, COLUMN >>> node = MyDOMNode(style=CSS(width=1000, height=1000, flex_direction=ROW)) >>> node.children.add(MyDOMNode(style=CSS(width=100, height=200))) >>> node.children.add(MyDOMNode(style=CSS(width=300, height=150))) >>> layout = node.style.layout >>> print(layout) <Layout (1000x1000 @ 0,0)> >>> layout.width 1000 >>> layout.height 1000 >>> layout.top 0 >>> layout.left 0 >>> for child in node.children: ... print(child.style.layout) <Layout (100x200 @ 0,0)> <Layout (300x150 @ 100,0)>
Requesting the layout
attribute of the style attribute forces the box
model to be evaluated. Once evaluated, the layout will be cached. Modifying
any CSS property on a node will mark the layout as dirty, and the layout will
be recomputed the next time the layout is accessed. For example, if we switch
the outer node to be a "column" flex box, rather than a "row" flex box, you'll
see the coordinates of the child boxes update to reflect a vertical, rather
than horizontal layout:
>>> node.style.flex_direction = COLUMN >>> print(node.style.layout) <Layout (1000x1000 @ 0,0)> >>> for child in node.children: ... print(child.style.layout) <Layout (100x200 @ 0,0)> <Layout (300x150 @ 0,200)>
Style attributes can also be set in bulk, using the set()
method on
the style attribute:
>>> node.style.set(width=1500, height=800) >>> print(node.style.layout) <Layout (1500x800 @ 0,0)>
Style attributes can also be removed by deleting the attribute on the style attribute. The value of the property will revert to the default:
>>> node.style.set(margin_top=10, margin_left=20) >>> print(node.style.layout) <Layout (1500x800 @ 20,10)> >>> del(node.style.margin_left) >>> print(node.style.margin_left) 0 >>> print(node.style.layout) <Layout (1500x800 @ 0,10)>
Colosseum is part of the BeeWare suite. You can talk to the community through:
- @pybeeware on Twitter
- The BeeWare Users Mailing list, for questions about how to use the BeeWare suite.
- The BeeWare Developers Mailing list, for discussing the development of new features in the BeeWare suite, and ideas for new tools for the suite.
If you experience problems with Colosseum, log them on GitHub. If you want to contribute code, please fork the code and submit a pull request.
The algorithm and test suite for this library is a language port of CSS-layout project, open-sourced by Facebook.