Overview
Flowery.Uno provides a comprehensive size system based on DaisySize enum, allowing controls to adapt to different screen sizes and device types. This guide covers the size system, responsive patterns, and mobile-specific considerations.
DaisySize System
The DaisySize enum provides five standard size variants:
public enum DaisySize
{
ExtraSmall , // Compact, dense UIs
Small , // Mobile-friendly
Medium , // Default size
Large , // Desktop optimized
ExtraLarge // Large displays
}
Default Size
Most controls default to DaisySize.Medium, which provides a balanced experience across platforms.
<!-- Default: Medium -->
< daisy:DaisyButton Content = "Default Size" />
<!-- Explicit size -->
< daisy:DaisyButton Content = "Large Button" Size = "Large" />
Size Tokens
Touch Target Heights
Flowery.Uno enforces mobile-friendly minimum touch targets on mobile platforms:
Size Desktop Height Mobile Height ExtraSmall24px 36px Small28px 40px Medium32px 44px Large36px 48px ExtraLarge40px 56px
Mobile touch targets meet accessibility guidelines (minimum 44px for tappable elements).
Icon Sizes
Size Icon Dimension ExtraSmall8px Small12px Medium16px Large20px ExtraLarge24px
Spacing
Size Spacing ExtraSmall4px Small4px Medium8px Large8px ExtraLarge8px
Font Sizes
Based on a 4px grid for consistent vertical rhythm:
Size Font Size Line Height ExtraSmall20px Tight Small21px Normal Medium22px Normal Large24px Relaxed ExtraLarge26px Relaxed
Responsive Patterns
Pattern 1: Size Binding
Bind control size to a view model property for centralized control:
< StackPanel >
<!-- Size selector -->
< daisy:DaisySizeDropdown SelectedSize = "{x:Bind ViewModel.CurrentSize, Mode=TwoWay}" />
<!-- Controls adapt automatically -->
< daisy:DaisyButton Content = "Adaptive Button"
Size = "{x:Bind ViewModel.CurrentSize, Mode=OneWay}" />
< daisy:DaisyInput PlaceholderText = "Type here"
Size = "{x:Bind ViewModel.CurrentSize, Mode=OneWay}" />
</ StackPanel >
public class MainViewModel : INotifyPropertyChanged
{
private DaisySize _currentSize = DaisySize . Medium ;
public DaisySize CurrentSize
{
get => _currentSize ;
set
{
if ( _currentSize != value )
{
_currentSize = value ;
OnPropertyChanged ();
}
}
}
}
Use conditional compilation or runtime checks for platform-specific sizes:
public DaisySize GetPlatformSize ()
{
# if __ANDROID__ || __IOS__
return DaisySize . Large ; // Touch-friendly on mobile
# elif __WASM__
return DaisySize . Medium ; // Balanced for web
# else
return DaisySize . Small ; // Compact for desktop
# endif
}
Pattern 3: Adaptive Window Size
Adjust control size based on window width:
public class AdaptiveViewModel : INotifyPropertyChanged
{
private double _windowWidth ;
public DaisySize CurrentSize => _windowWidth switch
{
< 640 => DaisySize . Small , // Mobile
< 1024 => DaisySize . Medium , // Tablet
< 1440 => DaisySize . Large , // Desktop
_ => DaisySize . ExtraLarge // Large displays
};
public double WindowWidth
{
get => _windowWidth ;
set
{
if ( _windowWidth != value )
{
_windowWidth = value ;
OnPropertyChanged ();
OnPropertyChanged ( nameof ( CurrentSize ));
}
}
}
}
Pattern 4: Visual State Manager
Use Visual State Manager for responsive layouts:
< Grid >
< VisualStateManager.VisualStateGroups >
< VisualStateGroup >
< VisualState x:Name = "Mobile" >
< VisualState.StateTriggers >
< AdaptiveTrigger MinWindowWidth = "0" />
</ VisualState.StateTriggers >
< VisualState.Setters >
< Setter Target = "PrimaryButton.Size" Value = "Large" />
< Setter Target = "NavPanel.Orientation" Value = "Vertical" />
</ VisualState.Setters >
</ VisualState >
< VisualState x:Name = "Desktop" >
< VisualState.StateTriggers >
< AdaptiveTrigger MinWindowWidth = "1024" />
</ VisualState.StateTriggers >
< VisualState.Setters >
< Setter Target = "PrimaryButton.Size" Value = "Medium" />
< Setter Target = "NavPanel.Orientation" Value = "Horizontal" />
</ VisualState.Setters >
</ VisualState >
</ VisualStateGroup >
</ VisualStateManager.VisualStateGroups >
< StackPanel x:Name = "NavPanel" >
< daisy:DaisyButton x:Name = "PrimaryButton" Content = "Adaptive" />
</ StackPanel >
</ Grid >
Control-Specific Sizing
< StackPanel Spacing = "8" >
< daisy:DaisyButton Content = "Extra Small" Size = "ExtraSmall" Variant = "Primary" />
< daisy:DaisyButton Content = "Small" Size = "Small" Variant = "Primary" />
< daisy:DaisyButton Content = "Medium" Size = "Medium" Variant = "Primary" />
< daisy:DaisyButton Content = "Large" Size = "Large" Variant = "Primary" />
< daisy:DaisyButton Content = "Extra Large" Size = "ExtraLarge" Variant = "Primary" />
</ StackPanel >
< StackPanel Spacing = "12" >
< daisy:DaisyInput PlaceholderText = "Extra Small Input"
Size = "ExtraSmall" Variant = "Bordered" />
< daisy:DaisyInput PlaceholderText = "Small Input"
Size = "Small" Variant = "Bordered" />
< daisy:DaisyInput PlaceholderText = "Medium Input (Default)"
Size = "Medium" Variant = "Bordered" />
< daisy:DaisyInput PlaceholderText = "Large Input"
Size = "Large" Variant = "Bordered" />
< daisy:DaisyInput PlaceholderText = "Extra Large Input"
Size = "ExtraLarge" Variant = "Bordered" />
</ StackPanel >
Toggles
< StackPanel Spacing = "12" >
< daisy:DaisyToggle Header = "Extra Small" Size = "ExtraSmall" Variant = "Primary" />
< daisy:DaisyToggle Header = "Small" Size = "Small" Variant = "Primary" />
< daisy:DaisyToggle Header = "Medium" Size = "Medium" Variant = "Primary" />
< daisy:DaisyToggle Header = "Large" Size = "Large" Variant = "Primary" />
< daisy:DaisyToggle Header = "Extra Large" Size = "ExtraLarge" Variant = "Primary" />
</ StackPanel >
Mobile Touch Targets : On mobile platforms, DaisyToggle enforces minimum touch targets even for smaller sizes to maintain accessibility.
Mobile-Specific Considerations
Flowery.Uno automatically detects mobile platforms and adjusts touch targets:
// Internal platform detection (simplified)
if ( PlatformCompatibility . IsMobile )
{
// Use mobile-optimized touch targets (minimum 44px)
minHeight = 44 ;
}
else
{
// Use desktop-optimized compact sizes
minHeight = 32 ;
}
Touch-Friendly Spacing
Increase spacing between interactive elements on mobile:
< StackPanel Spacing = "{x:Bind GetMobileSpacing()}" >
< daisy:DaisyButton Content = "Action 1" Size = "Large" />
< daisy:DaisyButton Content = "Action 2" Size = "Large" />
< daisy:DaisyButton Content = "Action 3" Size = "Large" />
</ StackPanel >
public double GetMobileSpacing ()
{
# if __ANDROID__ || __IOS__
return 16 ; // Generous spacing for touch
# else
return 8 ; // Compact for mouse/keyboard
# endif
}
Orientation Changes
Handle orientation changes gracefully:
public void OnOrientationChanged ( bool isLandscape )
{
if ( isLandscape )
{
// Landscape: More horizontal space, use compact sizes
ButtonSize = DaisySize . Small ;
PanelOrientation = Orientation . Horizontal ;
}
else
{
// Portrait: Limited horizontal space, use larger sizes
ButtonSize = DaisySize . Large ;
PanelOrientation = Orientation . Vertical ;
}
}
Breakpoint Strategies
Common Breakpoints
Breakpoint Width Recommended Size Mobile < 640px Large or ExtraLargeTablet 640px - 1024px Medium or LargeDesktop 1024px - 1440px Small or MediumLarge Display > 1440px Medium or Large
Breakpoint Helper
public static class ResponsiveHelper
{
public static DaisySize GetSizeForWidth ( double width )
{
return width switch
{
< 640 => DaisySize . Large , // Mobile: touch-friendly
< 1024 => DaisySize . Medium , // Tablet: balanced
< 1440 => DaisySize . Small , // Desktop: compact
_ => DaisySize . Medium // Large: comfortable
};
}
public static double GetSpacingForWidth ( double width )
{
return width switch
{
< 640 => 16 , // Mobile: generous
< 1024 => 12 , // Tablet: balanced
_ => 8 // Desktop: compact
};
}
}
Global Size Control
DaisySizeDropdown
Provide a global size selector for users:
< daisy:DaisySizeDropdown SelectedSize = "{x:Bind ViewModel.GlobalSize, Mode=TwoWay}"
MinWidth = "200" />
The dropdown includes localized size names in 12 languages.
Application-Wide Size
Store and persist user’s size preference:
public class AppSettings
{
private const string SizeKey = "GlobalSize" ;
public static DaisySize LoadSize ()
{
var value = ApplicationData . Current . LocalSettings . Values [ SizeKey ];
if ( value is int sizeInt && Enum . IsDefined ( typeof ( DaisySize ), sizeInt ))
{
return ( DaisySize ) sizeInt ;
}
return DaisySize . Medium ;
}
public static void SaveSize ( DaisySize size )
{
ApplicationData . Current . LocalSettings . Values [ SizeKey ] = ( int ) size ;
}
}
Layout Containers
Adaptive Grid
Create responsive grid layouts:
< Grid >
< Grid.ColumnDefinitions >
< ColumnDefinition Width = "Auto" />
< ColumnDefinition Width = "*" />
</ Grid.ColumnDefinitions >
<!-- Sidebar: Collapses on mobile -->
< StackPanel x:Name = "Sidebar"
Grid.Column = "0"
Visibility = "{x:Bind IsDesktop, Mode=OneWay}" >
<!-- Sidebar content -->
</ StackPanel >
<!-- Main content: Full width on mobile -->
< ScrollViewer Grid.Column = "1" >
<!-- Main content -->
</ ScrollViewer >
</ Grid >
Adaptive StackPanel
Switch between vertical and horizontal layouts:
< StackPanel Orientation = "{x:Bind LayoutOrientation, Mode=OneWay}"
Spacing = "{x:Bind LayoutSpacing, Mode=OneWay}" >
< daisy:DaisyButton Content = "Action 1" />
< daisy:DaisyButton Content = "Action 2" />
< daisy:DaisyButton Content = "Action 3" />
</ StackPanel >
public Orientation LayoutOrientation => WindowWidth < 640
? Orientation . Vertical
: Orientation . Horizontal ;
public double LayoutSpacing => WindowWidth < 640 ? 16 : 8 ;
Best Practices
Start with Medium size as default
Use DaisySize.Medium as the baseline and adjust for specific scenarios.
Use Large/ExtraLarge on mobile
Ensure touch targets meet minimum 44px height for accessibility on mobile devices.
Test on multiple screen sizes
Verify your UI works on phones (< 640px), tablets (640-1024px), and desktops (> 1024px).
Provide user control
Consider adding a DaisySizeDropdown in settings to let users choose their preferred size.
Use consistent spacing
Match spacing to control size for visual harmony.
Mobile-First Approach : Design for mobile first with touch-friendly sizes, then scale down for desktop.
Troubleshooting
Controls Too Small on Mobile
Cause : Using ExtraSmall or Small sizes on touch devices.
Solution : Use Large or ExtraLarge on mobile, or rely on automatic mobile touch target enforcement.
Inconsistent Sizes Across Controls
Cause : Mixing explicit sizes without a centralized binding.
Solution : Bind all control sizes to a single view model property.
Layout Doesn’t Adapt on Window Resize
Cause : Using static sizes instead of responsive bindings or Visual States.
Solution : Implement Visual State Manager or bind sizes to a computed property based on window width.
Next Steps
Styling Guide Learn about control customization and resource overrides
Accessibility Build accessible UIs with proper ARIA support
Theming Master theme switching and customization
Component Reference Explore all available controls