gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5364Rust 86Markdown 12TOML 91841 Definitions

⎇ 439a292e9a6bff9c9a9736d37494354f852dbd05 src/style/mod.rs Rust · 733 lines · 26.8 KB History Who touched what raw

Create style traits 439a292e9 · Nico Burns ·

1//! A typed representation of [CSS style properties](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) in Rust. Used as input to layout computation.
2mod alignment;
3mod dimension;
4
5#[cfg(feature = "flexbox")]
6mod flex;
7
8pub use self::alignment::{AlignContent, AlignItems, AlignSelf, JustifyContent, JustifyItems, JustifySelf};
9pub use self::dimension::{AvailableSpace, Dimension, LengthPercentage, LengthPercentageAuto};
10
11#[cfg(feature = "flexbox")]
12pub use self::flex::{FlexDirection, FlexWrap, FlexboxContainerStyle, FlexboxItemStyle};
13
14#[cfg(feature = "grid")]
15mod grid;
16#[cfg(feature = "grid")]
17pub(crate) use self::grid::{GenericGridPlacement, OriginZeroGridPlacement};
18#[cfg(feature = "grid")]
19pub use self::grid::{
20    GridAutoFlow, GridContainerStyle, GridItemStyle, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction,
21    MinTrackSizingFunction, NonRepeatedTrackSizingFunction, TrackSizingFunction,
22};
23use crate::geometry::{Point, Rect, Size};
24
25#[cfg(feature = "grid")]
26use crate::geometry::Line;
27#[cfg(feature = "serde")]
28use crate::style_helpers;
29#[cfg(feature = "grid")]
30use crate::util::sys::GridTrackVec;
31
32/// The core set of styles that are shared between all CSS layout nodes
33///
34/// Note that all methods come with a default implementation which simply returns the default value for that style property
35/// but this is a just a convenience to save on boilerplate for styles that your implementation doesn't support. You will need
36/// to override the default implementation for each style property that your style type actually supports.
37pub trait CoreStyle {
38    /// What layout strategy should be used?
39    // fn display(&self);
40
41    // Overflow properties
42    /// How children overflowing their container should affect layout
43    #[inline(always)]
44    fn overflow(&self) -> Point<Overflow> {
45        Style::DEFAULT.overflow
46    }
47    /// How much space (in points) should be reserved for the scrollbars of `Overflow::Scroll` and `Overflow::Auto` nodes.
48    #[inline(always)]
49    fn scrollbar_width(&self) -> f32 {
50        0.0
51    }
52
53    // Position properties
54    /// What should the `position` value of this struct use as a base offset?
55    #[inline(always)]
56    fn position(&self) -> Position {
57        Style::DEFAULT.position
58    }
59    /// How should the position of this element be tweaked relative to the layout defined?
60    #[inline(always)]
61    fn inset(&self) -> Rect<LengthPercentageAuto> {
62        Style::DEFAULT.inset
63    }
64
65    // Size properies
66    /// Sets the initial size of the item
67    #[inline(always)]
68    fn size(&self) -> Size<Dimension> {
69        Style::DEFAULT.size
70    }
71    /// Controls the minimum size of the item
72    #[inline(always)]
73    fn min_size(&self) -> Size<Dimension> {
74        Style::DEFAULT.min_size
75    }
76    /// Controls the maximum size of the item
77    #[inline(always)]
78    fn max_size(&self) -> Size<Dimension> {
79        Style::DEFAULT.max_size
80    }
81    /// Sets the preferred aspect ratio for the item
82    /// The ratio is calculated as width divided by height.
83    #[inline(always)]
84    fn aspect_ratio(&self) -> Option<f32> {
85        Style::DEFAULT.aspect_ratio
86    }
87
88    // Spacing Properties
89    /// How large should the margin be on each side?
90    #[inline(always)]
91    fn margin(&self) -> Rect<LengthPercentageAuto> {
92        Style::DEFAULT.margin
93    }
94    /// How large should the padding be on each side?
95    #[inline(always)]
96    fn padding(&self) -> Rect<LengthPercentage> {
97        Style::DEFAULT.padding
98    }
99    /// How large should the border be on each side?
100    #[inline(always)]
101    fn border(&self) -> Rect<LengthPercentage> {
102        Style::DEFAULT.border
103    }
104}
105
106/// Sets the layout used for the children of this node
107///
108/// The default values depends on on which feature flags are enabled. The order of precedence is: Flex, Grid, Block, None.
109#[derive(Copy, Clone, PartialEq, Eq, Debug)]
110#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
111pub enum Display {
112    /// The children will follow the block layout algorithm
113    #[cfg(feature = "block_layout")]
114    Block,
115    /// The children will follow the flexbox layout algorithm
116    #[cfg(feature = "flexbox")]
117    Flex,
118    /// The children will follow the CSS Grid layout algorithm
119    #[cfg(feature = "grid")]
120    Grid,
121    /// The children will not be laid out, and will follow absolute positioning
122    None,
123}
124
125impl Display {
126    /// The default of Display.
127    #[cfg(feature = "flexbox")]
128    pub const DEFAULT: Display = Display::Flex;
129
130    /// The default of Display.
131    #[cfg(all(feature = "grid", not(feature = "flexbox")))]
132    pub const DEFAULT: Display = Display::Grid;
133
134    /// The default of Display.
135    #[cfg(all(feature = "block_layout", not(feature = "flexbox"), not(feature = "grid")))]
136    pub const DEFAULT: Display = Display::Block;
137
138    /// The default of Display.
139    #[cfg(all(not(feature = "flexbox"), not(feature = "grid"), not(feature = "block_layout")))]
140    pub const DEFAULT: Display = Display::None;
141}
142
143impl core::fmt::Display for Display {
144    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
145        match self {
146            Display::None => write!(f, "NONE"),
147            #[cfg(feature = "block_layout")]
148            Display::Block => write!(f, "BLOCK"),
149            #[cfg(feature = "flexbox")]
150            Display::Flex => write!(f, "FLEX"),
151            #[cfg(feature = "grid")]
152            Display::Grid => write!(f, "GRID"),
153        }
154    }
155}
156
157impl Default for Display {
158    fn default() -> Self {
159        Self::DEFAULT
160    }
161}
162
163/// The positioning strategy for this item.
164///
165/// This controls both how the origin is determined for the [`Style::position`] field,
166/// and whether or not the item will be controlled by flexbox's layout algorithm.
167///
168/// WARNING: this enum follows the behavior of [CSS's `position` property](https://developer.mozilla.org/en-US/docs/Web/CSS/position),
169/// which can be unintuitive.
170///
171/// [`Position::Relative`] is the default value, in contrast to the default behavior in CSS.
172#[derive(Copy, Clone, PartialEq, Eq, Debug)]
173#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
174pub enum Position {
175    /// The offset is computed relative to the final position given by the layout algorithm.
176    /// Offsets do not affect the position of any other items; they are effectively a correction factor applied at the end.
177    Relative,
178    /// The offset is computed relative to this item's closest positioned ancestor, if any.
179    /// Otherwise, it is placed relative to the origin.
180    /// No space is created for the item in the page layout, and its size will not be altered.
181    ///
182    /// WARNING: to opt-out of layouting entirely, you must use [`Display::None`] instead on your [`Style`] object.
183    Absolute,
184}
185
186impl Default for Position {
187    fn default() -> Self {
188        Self::Relative
189    }
190}
191
192/// How children overflowing their container should affect layout
193///
194/// In CSS the primary effect of this property is to control whether contents of a parent container that overflow that container should
195/// be displayed anyway, be clipped, or trigger the container to become a scroll container. However it also has secondary effects on layout,
196/// the main ones being:
197///
198///   - The automatic minimum size Flexbox/CSS Grid items with non-`Visible` overflow is `0` rather than being content based
199///   - `Overflow::Scroll` nodes have space in the layout reserved for a scrollbar (width controlled by the `scrollbar_width` property)
200///
201/// In Taffy, we only implement the layout related secondary effects as we are not concerned with drawing/painting. The amount of space reserved for
202/// a scrollbar is controlled by the `scrollbar_width` property. If this is `0` then `Scroll` behaves identically to `Hidden`.
203///
204/// <https://developer.mozilla.org/en-US/docs/Web/CSS/overflow>
205#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
206#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
207pub enum Overflow {
208    /// The automatic minimum size of this node as a flexbox/grid item should be based on the size of its content.
209    /// Content that overflows this node *should* contribute to the scroll region of its parent.
210    #[default]
211    Visible,
212    /// The automatic minimum size of this node as a flexbox/grid item should be based on the size of its content.
213    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
214    Clip,
215    /// The automatic minimum size of this node as a flexbox/grid item should be `0`.
216    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
217    Hidden,
218    /// The automatic minimum size of this node as a flexbox/grid item should be `0`. Additionally, space should be reserved
219    /// for a scrollbar. The amount of space reserved is controlled by the `scrollbar_width` property.
220    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
221    Scroll,
222}
223
224impl Overflow {
225    /// Returns true for overflow modes that contain their contents (`Overflow::Hidden`, `Overflow::Scroll`, `Overflow::Auto`)
226    /// or else false for overflow modes that allow their contains to spill (`Overflow::Visible`).
227    #[inline(always)]
228    pub(crate) fn is_scroll_container(self) -> bool {
229        match self {
230            Self::Visible | Self::Clip => false,
231            Self::Hidden | Self::Scroll => true,
232        }
233    }
234
235    /// Returns `Some(0.0)` if the overflow mode would cause the automatic minimum size of a Flexbox or CSS Grid item
236    /// to be `0`. Else returns None.
237    #[inline(always)]
238    pub(crate) fn maybe_into_automatic_min_size(self) -> Option<f32> {
239        match self.is_scroll_container() {
240            true => Some(0.0),
241            false => None,
242        }
243    }
244}
245
246/// A typed representation of the CSS style information for a single node.
247///
248/// The most important idea in flexbox is the notion of a "main" and "cross" axis, which are always perpendicular to each other.
249/// The orientation of these axes are controlled via the [`FlexDirection`] field of this struct.
250///
251/// This struct follows the [CSS equivalent](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) directly;
252/// information about the behavior on the web should transfer directly.
253///
254/// Detailed information about the exact behavior of each of these fields
255/// can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS) by searching for the field name.
256/// The distinction between margin, padding and border is explained well in
257/// this [introduction to the box model](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model).
258///
259/// If the behavior does not match the flexbox layout algorithm on the web, please file a bug!
260#[derive(Clone, PartialEq, Debug)]
261#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
262#[cfg_attr(feature = "serde", serde(default))]
263pub struct Style {
264    /// What layout strategy should be used?
265    pub display: Display,
266
267    // Overflow properties
268    /// How children overflowing their container should affect layout
269    pub overflow: Point<Overflow>,
270    /// How much space (in points) should be reserved for the scrollbars of `Overflow::Scroll` and `Overflow::Auto` nodes.
271    pub scrollbar_width: f32,
272
273    // Position properties
274    /// What should the `position` value of this struct use as a base offset?
275    pub position: Position,
276    /// How should the position of this element be tweaked relative to the layout defined?
277    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
278    pub inset: Rect<LengthPercentageAuto>,
279
280    // Size properties
281    /// Sets the initial size of the item
282    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
283    pub size: Size<Dimension>,
284    /// Controls the minimum size of the item
285    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
286    pub min_size: Size<Dimension>,
287    /// Controls the maximum size of the item
288    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
289    pub max_size: Size<Dimension>,
290    /// Sets the preferred aspect ratio for the item
291    ///
292    /// The ratio is calculated as width divided by height.
293    pub aspect_ratio: Option<f32>,
294
295    // Spacing Properties
296    /// How large should the margin be on each side?
297    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
298    pub margin: Rect<LengthPercentageAuto>,
299    /// How large should the padding be on each side?
300    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
301    pub padding: Rect<LengthPercentage>,
302    /// How large should the border be on each side?
303    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
304    pub border: Rect<LengthPercentage>,
305
306    // Alignment properties
307    /// How this node's children aligned in the cross/block axis?
308    #[cfg(any(feature = "flexbox", feature = "grid"))]
309    pub align_items: Option<AlignItems>,
310    /// How this node should be aligned in the cross/block axis
311    /// Falls back to the parents [`AlignItems`] if not set
312    #[cfg(any(feature = "flexbox", feature = "grid"))]
313    pub align_self: Option<AlignSelf>,
314    /// How this node's children should be aligned in the inline axis
315    #[cfg(feature = "grid")]
316    pub justify_items: Option<AlignItems>,
317    /// How this node should be aligned in the inline axis
318    /// Falls back to the parents [`JustifyItems`] if not set
319    #[cfg(feature = "grid")]
320    pub justify_self: Option<AlignSelf>,
321    /// How should content contained within this item be aligned in the cross/block axis
322    #[cfg(any(feature = "flexbox", feature = "grid"))]
323    pub align_content: Option<AlignContent>,
324    /// How should contained within this item be aligned in the main/inline axis
325    #[cfg(any(feature = "flexbox", feature = "grid"))]
326    pub justify_content: Option<JustifyContent>,
327    /// How large should the gaps between items in a grid or flex container be?
328    #[cfg(any(feature = "flexbox", feature = "grid"))]
329    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
330    pub gap: Size<LengthPercentage>,
331
332    // Flexbox properties
333    /// Which direction does the main axis flow in?
334    #[cfg(feature = "flexbox")]
335    pub flex_direction: FlexDirection,
336    /// Should elements wrap, or stay in a single line?
337    #[cfg(feature = "flexbox")]
338    pub flex_wrap: FlexWrap,
339    /// Sets the initial main axis size of the item
340    #[cfg(feature = "flexbox")]
341    pub flex_basis: Dimension,
342    /// The relative rate at which this item grows when it is expanding to fill space
343    ///
344    /// 0.0 is the default value, and this value must be positive.
345    #[cfg(feature = "flexbox")]
346    pub flex_grow: f32,
347    /// The relative rate at which this item shrinks when it is contracting to fit into space
348    ///
349    /// 1.0 is the default value, and this value must be positive.
350    #[cfg(feature = "flexbox")]
351    pub flex_shrink: f32,
352
353    // Grid container properies
354    /// Defines the track sizing functions (heights) of the grid rows
355    #[cfg(feature = "grid")]
356    pub grid_template_rows: GridTrackVec<TrackSizingFunction>,
357    /// Defines the track sizing functions (widths) of the grid columns
358    #[cfg(feature = "grid")]
359    pub grid_template_columns: GridTrackVec<TrackSizingFunction>,
360    /// Defines the size of implicitly created rows
361    #[cfg(feature = "grid")]
362    pub grid_auto_rows: GridTrackVec<NonRepeatedTrackSizingFunction>,
363    /// Defined the size of implicitly created columns
364    #[cfg(feature = "grid")]
365    pub grid_auto_columns: GridTrackVec<NonRepeatedTrackSizingFunction>,
366    /// Controls how items get placed into the grid for auto-placed items
367    #[cfg(feature = "grid")]
368    pub grid_auto_flow: GridAutoFlow,
369
370    // Grid child properties
371    /// Defines which row in the grid the item should start and end at
372    #[cfg(feature = "grid")]
373    pub grid_row: Line<GridPlacement>,
374    /// Defines which column in the grid the item should start and end at
375    #[cfg(feature = "grid")]
376    pub grid_column: Line<GridPlacement>,
377}
378
379impl Style {
380    /// The [`Default`] layout, in a form that can be used in const functions
381    pub const DEFAULT: Style = Style {
382        display: Display::DEFAULT,
383        overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
384        scrollbar_width: 0.0,
385        position: Position::Relative,
386        inset: Rect::auto(),
387        margin: Rect::zero(),
388        padding: Rect::zero(),
389        border: Rect::zero(),
390        size: Size::auto(),
391        min_size: Size::auto(),
392        max_size: Size::auto(),
393        aspect_ratio: None,
394        #[cfg(any(feature = "flexbox", feature = "grid"))]
395        gap: Size::zero(),
396        // Alignment
397        #[cfg(any(feature = "flexbox", feature = "grid"))]
398        align_items: None,
399        #[cfg(any(feature = "flexbox", feature = "grid"))]
400        align_self: None,
401        #[cfg(feature = "grid")]
402        justify_items: None,
403        #[cfg(feature = "grid")]
404        justify_self: None,
405        #[cfg(any(feature = "flexbox", feature = "grid"))]
406        align_content: None,
407        #[cfg(any(feature = "flexbox", feature = "grid"))]
408        justify_content: None,
409        // Flexbox
410        #[cfg(feature = "flexbox")]
411        flex_direction: FlexDirection::Row,
412        #[cfg(feature = "flexbox")]
413        flex_wrap: FlexWrap::NoWrap,
414        #[cfg(feature = "flexbox")]
415        flex_grow: 0.0,
416        #[cfg(feature = "flexbox")]
417        flex_shrink: 1.0,
418        #[cfg(feature = "flexbox")]
419        flex_basis: Dimension::Auto,
420        // Grid
421        #[cfg(feature = "grid")]
422        grid_template_rows: GridTrackVec::new(),
423        #[cfg(feature = "grid")]
424        grid_template_columns: GridTrackVec::new(),
425        #[cfg(feature = "grid")]
426        grid_auto_rows: GridTrackVec::new(),
427        #[cfg(feature = "grid")]
428        grid_auto_columns: GridTrackVec::new(),
429        #[cfg(feature = "grid")]
430        grid_auto_flow: GridAutoFlow::Row,
431        #[cfg(feature = "grid")]
432        grid_row: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
433        #[cfg(feature = "grid")]
434        grid_column: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
435    };
436}
437
438impl Default for Style {
439    fn default() -> Self {
440        Style::DEFAULT
441    }
442}
443
444impl CoreStyle for Style {
445    #[inline(always)]
446    fn overflow(&self) -> Point<Overflow> {
447        self.overflow
448    }
449    #[inline(always)]
450    fn scrollbar_width(&self) -> f32 {
451        self.scrollbar_width
452    }
453    #[inline(always)]
454    fn position(&self) -> Position {
455        self.position
456    }
457    #[inline(always)]
458    fn inset(&self) -> Rect<LengthPercentageAuto> {
459        self.inset
460    }
461    #[inline(always)]
462    fn size(&self) -> Size<Dimension> {
463        self.size
464    }
465    #[inline(always)]
466    fn min_size(&self) -> Size<Dimension> {
467        self.min_size
468    }
469    #[inline(always)]
470    fn max_size(&self) -> Size<Dimension> {
471        self.max_size
472    }
473    #[inline(always)]
474    fn aspect_ratio(&self) -> Option<f32> {
475        self.aspect_ratio
476    }
477    #[inline(always)]
478    fn margin(&self) -> Rect<LengthPercentageAuto> {
479        self.margin
480    }
481    #[inline(always)]
482    fn padding(&self) -> Rect<LengthPercentage> {
483        self.padding
484    }
485    #[inline(always)]
486    fn border(&self) -> Rect<LengthPercentage> {
487        self.border
488    }
489}
490
491#[cfg(feature = "flexbox")]
492impl FlexboxContainerStyle for Style {
493    #[inline(always)]
494    fn flex_direction(&self) -> FlexDirection {
495        self.flex_direction
496    }
497    #[inline(always)]
498    fn flex_wrap(&self) -> FlexWrap {
499        self.flex_wrap
500    }
501    #[inline(always)]
502    fn gap(&self) -> Size<LengthPercentage> {
503        self.gap
504    }
505    #[inline(always)]
506    fn align_content(&self) -> Option<AlignContent> {
507        self.align_content
508    }
509    #[inline(always)]
510    fn align_items(&self) -> Option<AlignItems> {
511        self.align_items
512    }
513    #[inline(always)]
514    fn justify_content(&self) -> Option<JustifyContent> {
515        self.justify_content
516    }
517}
518#[cfg(feature = "flexbox")]
519impl FlexboxItemStyle for Style {
520    #[inline(always)]
521    fn flex_basis(&self) -> Dimension {
522        self.flex_basis
523    }
524    #[inline(always)]
525    fn flex_grow(&self) -> f32 {
526        self.flex_grow
527    }
528    #[inline(always)]
529    fn flex_shrink(&self) -> f32 {
530        self.flex_shrink
531    }
532    #[inline(always)]
533    fn align_self(&self) -> Option<AlignSelf> {
534        self.align_self
535    }
536}
537
538#[cfg(feature = "grid")]
539impl GridContainerStyle for Style {
540    #[inline(always)]
541    fn grid_template_rows(&self) -> &[TrackSizingFunction] {
542        &self.grid_template_rows
543    }
544    #[inline(always)]
545    fn grid_template_columns(&self) -> &[TrackSizingFunction] {
546        &self.grid_template_columns
547    }
548    #[inline(always)]
549    fn grid_auto_rows(&self) -> &[NonRepeatedTrackSizingFunction] {
550        &self.grid_auto_rows
551    }
552    #[inline(always)]
553    fn grid_auto_columns(&self) -> &[NonRepeatedTrackSizingFunction] {
554        &self.grid_auto_columns
555    }
556    #[inline(always)]
557    fn grid_auto_flow(&self) -> GridAutoFlow {
558        self.grid_auto_flow
559    }
560    #[inline(always)]
561    fn gap(&self) -> Size<LengthPercentage> {
562        self.gap
563    }
564    #[inline(always)]
565    fn align_content(&self) -> Option<AlignContent> {
566        self.align_content
567    }
568    #[inline(always)]
569    fn justify_content(&self) -> Option<JustifyContent> {
570        self.justify_content
571    }
572    #[inline(always)]
573    fn align_items(&self) -> Option<AlignItems> {
574        self.align_items
575    }
576    #[inline(always)]
577    fn justify_items(&self) -> Option<AlignItems> {
578        self.justify_items
579    }
580}
581#[cfg(feature = "grid")]
582impl GridItemStyle for Style {
583    #[inline(always)]
584    fn grid_row(&self) -> Line<GridPlacement> {
585        self.grid_row
586    }
587    #[inline(always)]
588    fn grid_column(&self) -> Line<GridPlacement> {
589        self.grid_column
590    }
591    #[inline(always)]
592    fn align_self(&self) -> Option<AlignSelf> {
593        self.align_self
594    }
595    #[inline(always)]
596    fn justify_self(&self) -> Option<AlignSelf> {
597        self.justify_self
598    }
599}
600
601#[cfg(test)]
602mod tests {
603    use super::Style;
604    use crate::geometry::*;
605
606    #[test]
607    fn defaults_match() {
608        #[cfg(feature = "grid")]
609        use super::GridPlacement;
610
611        let old_defaults = Style {
612            display: Default::default(),
613            overflow: Default::default(),
614            scrollbar_width: 0.0,
615            position: Default::default(),
616            #[cfg(feature = "flexbox")]
617            flex_direction: Default::default(),
618            #[cfg(feature = "flexbox")]
619            flex_wrap: Default::default(),
620            #[cfg(any(feature = "flexbox", feature = "grid"))]
621            align_items: Default::default(),
622            #[cfg(any(feature = "flexbox", feature = "grid"))]
623            align_self: Default::default(),
624            #[cfg(feature = "grid")]
625            justify_items: Default::default(),
626            #[cfg(feature = "grid")]
627            justify_self: Default::default(),
628            #[cfg(any(feature = "flexbox", feature = "grid"))]
629            align_content: Default::default(),
630            #[cfg(any(feature = "flexbox", feature = "grid"))]
631            justify_content: Default::default(),
632            inset: Rect::auto(),
633            margin: Rect::zero(),
634            padding: Rect::zero(),
635            border: Rect::zero(),
636            gap: Size::zero(),
637            #[cfg(feature = "flexbox")]
638            flex_grow: 0.0,
639            #[cfg(feature = "flexbox")]
640            flex_shrink: 1.0,
641            #[cfg(feature = "flexbox")]
642            flex_basis: super::Dimension::Auto,
643            size: Size::auto(),
644            min_size: Size::auto(),
645            max_size: Size::auto(),
646            aspect_ratio: Default::default(),
647            #[cfg(feature = "grid")]
648            grid_template_rows: Default::default(),
649            #[cfg(feature = "grid")]
650            grid_template_columns: Default::default(),
651            #[cfg(feature = "grid")]
652            grid_auto_rows: Default::default(),
653            #[cfg(feature = "grid")]
654            grid_auto_columns: Default::default(),
655            #[cfg(feature = "grid")]
656            grid_auto_flow: Default::default(),
657            #[cfg(feature = "grid")]
658            grid_row: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
659            #[cfg(feature = "grid")]
660            grid_column: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
661        };
662
663        assert_eq!(Style::DEFAULT, Style::default());
664        assert_eq!(Style::DEFAULT, old_defaults);
665    }
666
667    // NOTE: Please feel free the update the sizes in this test as required. This test is here to prevent unintentional size changes
668    // and to serve as accurate up-to-date documentation on the sizes.
669    #[test]
670    fn style_sizes() {
671        use super::*;
672
673        fn assert_type_size<T>(expected_size: usize) {
674            let name = ::core::any::type_name::<T>();
675            let name = name.replace("taffy::geometry::", "");
676            let name = name.replace("taffy::style::dimension::", "");
677            let name = name.replace("taffy::style::alignment::", "");
678            let name = name.replace("taffy::style::flex::", "");
679            let name = name.replace("taffy::style::grid::", "");
680
681            assert_eq!(
682                ::core::mem::size_of::<T>(),
683                expected_size,
684                "Expected {} for be {} byte(s) but it was {} byte(s)",
685                name,
686                expected_size,
687                ::core::mem::size_of::<T>(),
688            );
689        }
690
691        // Display and Position
692        assert_type_size::<Display>(1);
693        assert_type_size::<Position>(1);
694        assert_type_size::<Overflow>(1);
695
696        // Dimensions and aggregations of Dimensions
697        assert_type_size::<f32>(4);
698        assert_type_size::<LengthPercentage>(8);
699        assert_type_size::<LengthPercentageAuto>(8);
700        assert_type_size::<Dimension>(8);
701        assert_type_size::<Size<LengthPercentage>>(16);
702        assert_type_size::<Size<LengthPercentageAuto>>(16);
703        assert_type_size::<Size<Dimension>>(16);
704        assert_type_size::<Rect<LengthPercentage>>(32);
705        assert_type_size::<Rect<LengthPercentageAuto>>(32);
706        assert_type_size::<Rect<Dimension>>(32);
707
708        // Alignment
709        assert_type_size::<AlignContent>(1);
710        assert_type_size::<AlignItems>(1);
711        assert_type_size::<Option<AlignItems>>(1);
712
713        // Flexbox Container
714        assert_type_size::<FlexDirection>(1);
715        assert_type_size::<FlexWrap>(1);
716
717        // CSS Grid Container
718        assert_type_size::<GridAutoFlow>(1);
719        assert_type_size::<MinTrackSizingFunction>(8);
720        assert_type_size::<MaxTrackSizingFunction>(12);
721        assert_type_size::<NonRepeatedTrackSizingFunction>(20);
722        assert_type_size::<TrackSizingFunction>(32);
723        assert_type_size::<Vec<NonRepeatedTrackSizingFunction>>(24);
724        assert_type_size::<Vec<TrackSizingFunction>>(24);
725
726        // CSS Grid Item
727        assert_type_size::<GridPlacement>(4);
728        assert_type_size::<Line<GridPlacement>>(8);
729
730        // Overall
731        assert_type_size::<Style>(352);
732    }
733}