Skip to content

v0.3.0 "CSS Grid"

Compare
Choose a tag to compare
@nicoburns nicoburns released this 12 Feb 20:05
· 314 commits to main since this release
868b3a4

Highlights

  • CSS Grid algorithm support
  • Style helper functions

See below for details of breaking changes.

New Feature: CSS Grid

We very excited to report that we now have support for CSS Grid layout. This is in addition to the existing Flexbox layout support, and the two modes interoperate. You can set a node to use Grid layout by setting the display property to Display::Grid.

Learning Resources

Taffy implements the CSS Grid specification faithfully, so documentation designed for the web should translate cleanly to Taffy's implementation. If you are interested in learning how to use CSS Grid, we would recommend the following resources:

  • CSS Grid Garden. This is an interactive tutorial/game that allows you to learn the essential parts of CSS Grid in a fun engaging way.
  • A Complete Guide To CSS Grid by CSS Tricks. This is detailed guide with illustrations and comphrehensive written explanation of the different Grid propertie and how they work.

Supported Features & Properties

In addition to the usual sizing/spacing proerties (size, min_size, padding, margin, etc), the following Grid style properties are supported on Grid Containers:

Property Explanation
grid-template-columns The track sizing functions of the grid's explicit columns
grid-template-rows The track sizing functions of the grid's explicit rows
grid-auto-rows Track sizing functions for the grid's implicitly generated rows
grid-auto-columns Track sizing functions for the grid's implicitly generated columns
grid-auto-flow Whether auto-placed items are placed row-wise or column-wise. And sparsely or densely.
gap The size of the vertical and horizontal gaps between grid rows/columns
align-content Align grid tracks within the container in the inline (horizontal) axis
justify-content Align grid tracks within the container in the block (vertical) axis
align-items Align the child items within their grid areas in the inline (horizontal) axis
justify-items Align the child items within their grid areas in the block (vertical) axis

And the following Grid style properties are supported on Grid Items (children):

Property Explanation
grid-row The (row) grid line the item starts at (or a span)
grid-column The (column) grid line the item end at (or a span)
align-self Align the item within it's grid area in the inline (horizontal) axis. Overrides align-items.
justify-self Align the item within it's grid area in the block (vertical) axis. Overrides justify-items.

The following properties and features are not currently supported:

  • Subgrids
  • Masonry grid layout
  • Named grid lines
  • Named areas: grid-template-areas and grid-area
  • grid-template or grid shorthand

Example

See examples/grid_holy_grail.rs for an example using Taffy to implement the so-called Holy Grail Layout. If you want to run this example, the don't forget the enable the CSS Grid cargo feature:

cargo run --example grid_holy_grail --features grid

New Feature: Style Helpers

Ten new helper functions have added to the taffy prelude. These helper functions have short, intuitive names, and have generic return types which allow them to magically return the correct type depending on context. They make defining styles much easier, and means you won't typically need to use types like Dimension or TrackSizingFunction directly.

For example, instead of:

let size : Size<Dimension> = Size { width: Dimension::Points(100.0), height: Dimension::Percent(50.0) };

you can now write

let size : Size<Dimension> = Size { width: points(100.0), height: percent(50.0) };

And that same helper function will work other types like LengthPercentage and MinTrackSizingFunction that also have a Points variant. There are also generic impl's for Size<T>, Rect<T> and Line<T> which means if your node is the same size in all dimensions you can even write

let size : Size<Dimension> = points(100.0);

Available style helpers:

Type(s)Helpers that work with that type
LengthPercentage zero() Generates a Points variant with the value 0.0
points(val: f32) Generates a Points variant with the specified value
percent(val: f32) Generates a Percent variant with the specified value.
Note that the scale of 0-1 not 0-100.
LengthPercentageAuto
Dimension
All helpers from LengthPercentage and...
auto() Generates an Auto variant
MinTrackSizingFunction All helpers from LengthPercentageAuto/Dimension and...
min_content() Generates an MinContent variant
max_content() Generates an MinContent variant
MaxTrackSizingFunction All helpers from MinTrackSizingFunction and...
fit_content(limit: LengthPercentage) Generates a FitContent variant with the specified limit.
Nest the points or percent helper inside this function to specified the limit.
fr(fraction: f32) Generates a Fraction (fr) variant with the specified flex fraction
NonRepeatingTrackSizingFunction All helpers from MaxTrackSizingFunction and...
minmax(min: MinTrackSizingFunction, max: MaxTrackSizingFunction) Equivalent to CSS minmax() function.
flex(fraction: f32) Equivalent to CSS minmax(0px, 1fr). This is likely what you want if you want evenly sized rows/columns.
TrackSizingFunction All helpers from NonRepeatingTrackSizingFunction and...
repeat(rep: GridTrackRepetition, tracks: Vec<TrackSizingFunction>) Equivalent to css repeat() function.
Vec<TrackSizingFunction> evenly_sized_tracks(count: u16) Equivalent to CSS repeat(count, minmax(0px, 1fr)
AvailableSpace auto() Generates an Auto variant
min_content() Generates an MinContent variant
max_content() Generates an MinContent variant
Size<T> Any helper that works for T will also work for Size<T> and will set both width and height to that value
Rect<T> Any helper that works for T will also work for Rect<T> and will set top, left, bottom, and right to that value

Breaking API changes

Changes to alignment style types

  • AlignContent and JustifyContent has been merged.
    • JustifyContent is now an alias of AlignContent and contains the Stretch variant.
    • This variant will be ignored (falling back to Start) when applied Flexbox containers. It is valid value for Grid containers.
  • AlignItems and AlignSelf have been merged.
    • The Auto variant of AlignSelf has been removed. You should now use Option::None if you wish to specify AlignSelf::Auto.
    • AlignSelf is now an alias of AlignItems.
    • JustifyItems and JustifySelf aliases have been added. These properties have no affect on Flexbox containers, but apply to Grid containers.
  • Default impls have been removed from all alignment types. This is because the correct default varies by property, and the types are now shared between multiple properties. The Style struct still has a default for each alignment property, so this is considered unlikely to affect you in practice.

Strict style types

  • New types LengthPercentage and LengthPercentageAuto have been added.
    • LengthPercentage is like Dimension but only contains the Points and Percent variants, which allows us to increase type safety for properties that don't support the Auto value.
    • LengthPercentageAuto is currently identical to Dimension but will allow us to expand dimension in future to support values like MinContent, MaxContent and FitContent.
  • Some style properties have been updated to use either LengthPercentage or LengthPercentageAuto instead of Dimension. You will need to update your code, but it is recommended that you use the new style helpers (see above) rather than using the new types directly (although you certainly can use them directly if you want to).

Position properties renamed

  • The position property is now renamed to inset and is now in line with CSS inset specs
  • The position_type property is now renamed to position and is now in line with CSS position specs. The PositionType enum has been similarly renamed to Position.

Changes to LayoutTree

  • Added generic associated type to LayoutTree for a ChildIter, an iterator on the children of a given node.
  • Changed the children method of LayoutTree to return the ChildIter generic associated type to allow for custom tree storage implementations which do not store the children of a node contiguously.
  • Added child_count method to LayoutTree for querying the number of children of a node. Required because the children method now returns an iterator instead of an array.
  • Added is_childless method to LayoutTree for querying whether a node has no children.

AvailableSpace has been moved

The AvailableSpace enum has been moved from the layout module to the style module. If you are importing it via the prelude then you will unaffected by the change.

Fixes

  • Flexbox nodes sized under a min-content constraint now size correctly (#291)
  • Aspect ratio is now applied correctly in many circumstances
  • Absolutely positioned items now apply margins correctly
  • Min/max size are now applied correctly
  • Inset applied incorrectly to relatively positioned flexbox children when both top and bottom or left and right were specified (#348)
  • Fix case where column-gap style could be used in place of row-gap style (when using a percentage gap with an indefinite container size)

Removed

  • Removed top_from_points, bot_from_points, top_from_percent, and bot_from_percent methods removed from Rect<Dimension>. These functions were incredibly specific for an unusual use case, so we would be surprised if anyone was using them. Please use the new style helpers instead.
  • Removed min_main_size, max_main_size, min_cross_size, max_cross_size, and cross_size methods from Style. Use the more general cross and main methods directly on the size, min_size, and max_size properties instead.
  • Removed main_margin_start, main_margin_end, cross_margin_start, cross_margin_end from Style. Use the more general main_start, main_end, cross_start, and cross_end on the margin property instead.