/colosseum

A (partial) implementation of the CSS box and flexbox layout algorithm.

Primary LanguagePythonOtherNOASSERTION

Colosseum

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"

Quickstart

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 a parent of None.
  • a children attribute, containing the list of DOM child nodes.
  • a style attribute, generated by calling apply() on a CSS 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)>

Community

Colosseum is part of the BeeWare suite. You can talk to the community through:

Contributing

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.

Acknowledgements

The algorithm and test suite for this library is a language port of CSS-layout project, open-sourced by Facebook.