HomeBlogResponsive Design met Flutter: ontmoet Fluid UI!
#Engineering #Design
Bas - DeveloperBas de Vaan
12 juni 2023

Responsive Design met Flutter: ontmoet Fluid UI!

Bij Dutch Coding Company bouwen we steeds vaker apps die geschikt moeten zijn voor een breed scala aan devices. We hebben natuurlijk al veel apps gebouwd voor smartphones, maar web-apps die gebruikt worden op grotere schermen, kleinere schermen en naast andere vensters op hetzelfde scherm zijn nu ook heel gebruikelijk voor het app team. En dan hebben we ook nog smart watches en tablets! Al deze apparaten zijn enorm krachtig, maar moeten de UI op een verschillende manier en in een ander formaat laten zien.

Key takeaways
  • De vraag naar responsie design en apps groeit nog steeds. En nu er steeds meer doel-platforms mogelijk zijn in Flutter, is er
    een behoefte aan een goede oplossing die kan omgaan met verschillende schermgroottes.
  • Utopia is een goed design framework dat designers en ontwikkelaars helpt om beter samen te werken en beter bruikbare responsive designs op te leveren.
  • Er bestaat al een Figma plugin die designers kunnen gebruiken, en een interactieve view waarmee je configuraties kan testen.
  • Fluid UI is een open source package dat deze principes gebruikt en het simpel maakt om ze toe te passen in een Flutter app.
  • Fluid UI is nu nog in beta, maar er zal flink ontwikkeld worden aan en met deze package. Bij Dutch Coding Company zullen we onze ervaringen hiermee de komende tijd delen, dus stay tuned!

We hebben een tijd nagedacht hoe we hier het beste mee om kunnen gaan. We lopen tegen veel problemen aan als een design is gemaakt voor een bepaald schermformaat of voor enkele breakpoints en de app op een formaat moet werken dat er net tussenin valt.Een goed voorbeeld hiervan is als we een goed browser design hebben, maar de gebruiker de app naast andere vensters plaatst. Dat is te verwachten gedrag voor echte power users die veel achter hun computer zitten, en er zijn veel apps voor precies die doelgroep! Helaas hebben we niet de tijd om een speciaal ontwerp te maken voor elk mogelijk schermformaat.

We liepen een beetje toevallig tegen https://utopia.fyi aan. Dit is een design methode waar designers werken met formaten die direct afhangen van de breedte van het app-venster en developers kunnen deze formaten gemakkelijk in de app inbouwen. We waren meteen geïnteresseerd in het idee en wilden het proberen! Mijn collega Niels had al supersnel een goede fluid setup draaiend en vanaf dat startpunt hebben we uitgebouwd tot het goed genoeg was om een eerste beta versie te releasen van onze open source implementatie van Utopia in Flutter; Fluid UI!

Maar laten we even een stapje terug doen en kijken welke design principes het belangrijkst voor ons (geen mede-code junkies, de package zelf komt verder op ook aan bod!)

Fluid Spaces

Het idee achter een fluid space is dat de spacing in een design niet vast staat, maar varieert op basis van de schermgrootte. Stel dat je

normaal een padding van 24px rondom al je content hebt. Dat klinkt prima voor je browser, maar past het ook op een telefoon?

Waarschijnlijk helemaal niet. In onze code gebruiken we waardes in een schaal die we aangeven met T-shirt maten. Op deze manier weten we zeker dat onze maten in zekere mate consistent zijn. Designers vinden deze schaal ook handig; kijk bijvoorbeeld naar dit artikel over waarom stapjes van 8 helpen om je workflow te versnellen (engels). In de praktijk definiëren we deze schaal ergens in onze code en gebruiken de T-shirt maten in de app.

Maar zoals we eerder al concludeerden, zijn deze maten niet altijd zinnig voor elk formaat scherm. Dus kiezen we, in het geval van een Fluid Space, een minimum en een maximum ‘basis’ waarde en gebruiken multipliers om daarmee de echte formaten te berekenen. We moeten ook bepalen wat het kleinste en grootste scherm is dat we gaan ondersteunen.

Bijvoorbeeld: laten we zeggen dat ons kleinste scherm 320 en ons grootste scherm 1240 pixels is. Laten we ook zeggen dat onze kleinste T-shirt maat M 12 is en de grootste 16. We kunnen natuurlijk spelen met deze getallen om te zien wat het beste werkt. Dit resulteert in een tabel die er ongeveer zo uitziet:

Deze multipliers kunnen we natuurlijk ook aanpassen, maar laten we even bekijken waar we zo op uitkomen. Wanneer we een kleine padding gebruiken op een object (T-shirt maat S), geeft dat normaal 8 pixels ruimte. Maar met een fluid size, wordt dit iets kleiner en krijgen we 6px ruimte. Dat verschilt niet heel erg op het oog, maar als we veel items op het scherm hebben met padding kan het een zeer merkbaar verschil maken. Als we een grotere waarde gebruiken, bijvoorbeeld voor de hoogte van een block of afbeelding, kan het verschil nog veel groter zijn. In het geval van XXL scheelt het wel 20 pixels. Zo past het een stuk beter op mobiele schermen.

Maar wat gebeurt er als we een scherm hebben dat ergens tussen het min en max valt? In dat geval berekenen we precies op welk percentage tussen de grenzen dat schermformaat valt en gebruiken dat percentage om de waarde tussen min en max te berekenen. Voor een scherm van bijvoorbeeld 800 pixels komt het neerloop 52%, dus de size M is dan ongeveer 12,08.

Fluid Types

Fluid Types werken ongeveer hetzelfde, maar worden dan gebruikt om de lettergrootte aan te passen. De verhouding in de grootte van een body text en een title van een pagina bepaalt hoe de tekst eruit komt te zien. Op een klein scherm is er niet heel veel ruimte voor extra nadruk, maar op een groot scherm wel! Dus in plaats van een lineaire functie, gebruiken we een exponentiële functie voor typografie, zodat het meer effect heeft op het verschil in in type schaling. Het mooie hieraan is dat we alleen een min en max schermgrootte en voor die beide een font size en een type schaling moeten bepalen. Dat is alles wat we nodig hebben om de font sizes te schalen.

Figma

Als je een designer bent en hiermee aan de slag wil, dan kan dat! Er is een Figma plugin die is ontwikkeld door het team van Utopia om je te helpen met het designen van apps op deze manier (engels). De plugins hebt je ook met het instellen van de configuratie voor je schaling en bij het hergebruiken van alle maatvoering van spacing en typografie. Er is zelfs een Kickstarter project om je te helpen.

null

Als je meer wil weten over Utopia, kan je eens kijken op hun website https://utopia.fyi. Ik vond hun YouTube video’s in het bijzonder goed, omdat ze daarin goed het probleem en hun oplossing uitleggen. Laten we nu eens naar het technische stuk kijken!

Fluid UI gebruiken in Flutter

Beste mede-developers, ik hoop dat je het hebt volgehouden tot dit deel van de blog, want hier wordt het echt leuk (voor mij dan). We hebben onszelf wat doelen gesteld bij het bouwen van deze package:

  • Het moet mogelijk zijn om de configuratiewaarden te gebruiken die je designer heeft bepaald
  • We wilden starten met de Spaces, Space pars en Types features, want dat is de kern van het design systeem.
  • We zochten naar een makkelijke manier om het te implementeren in onze apps.
  • Bij voorkeur ook een soort playground om de settings te testen en als demo van het framework

We hebben de meeste van deze delen al bereikt met onze eerste beta release op GitHub, dus check it out als je klaar bent met lezen 😄

Setup

Het is heel eenvoudig om Flutter UI in je project in te stellen. We hebben alles gebouwd in een Theme Extension die met een simpele constructor kan worden aangemaakt, maar als je bepaalde dingen aan je schaling wil aanpassen kan dat ook eenvoudig in de constructor.

FluidConfig config = FluidConfig.fromContext(context);

    return MaterialApp(
      theme: ThemeData(
        extensions: <ThemeExtension<dynamic>>[
          config,
        ],
      ),
      home: const MyHomePage(),
    );

Hierboven staat een heel simpele manier om een Fluid UI op te zetten. Als je deze setup gebruikt, kan je al meteen de default sizing scale functions gebruiken een type scale bouwen. Maar waarschijnlijk wil je de custom schaling gebruiken die je designer heeft bepaald.

FluidConfig config = FluidConfig.fromContext(context,
        spaceConfig: SpaceConfig(
          baseMin: 4,
          baseMax: 8,
          xxxsModifier: 0.25,
          xxsModifier: 0.5,
          xsModifier: 0.75,
          sModifier: 1,
          mModifier: 1.5,
          lModifier: 2,
          xlModifier: 3,
          xxlModifier: 4,
          xxxlModifier: 6,
        ),
        typeConfig: TypeConfig(
          minBaseFontSize: 16,
          maxBaseFontSize: 20,
          minTypeScaleModifier: 1.2,
          maxTypeScaleModifier: 1.5,
        ),
        viewportConfig: ViewportConfig(
          minViewportSize: 320,
          maxViewportSize: 1200,
        ));

    return MaterialApp(
      theme: ThemeData(
        extensions: <ThemeExtension<dynamic>>[
          config,
        ],
      ),
      home: const MyHomePage(),
    );

Gemakkelijk implementeren

Op de Github pagina staan een aantal voorbeelden over hoe je Spaces, Space Pair en Type Scales kan gebruiken, dus bekijk even de Readme op Github voor de details. Maar om even te laten zien hoe eenvoudig het is: dit is hoe je een SizedBox maakt met variabele width:

SizedBox(height: context.fluid.spaces.m);

Waneer je het browser venster vergroot of verkleint met de Flutter Web app erin, past deze box zich automatisch aan. Daarvoor hoef je geen extra functional code of handler te schrijven: de package zorgt ervoor dat wanneer de box een rebuild krijgt, dat meteen op het juiste formaat gebeurt.

Bij Dutch Coding Company gebruiken we heel vaak Google Fonts; het is een simpele manier om fonts in Flutter te gebruiken en geeft ons toegang tot een grote database van bruikbare fonts. We hebben daarom een makkelijke manier gemaakt om een Type Scale variant van een Google Font te gebruiken:

Text(
'Hello internet!',
textStyle: context.fluid.fromGoogleFont(GoogleFonts.firaSans).bold.displayLarge);

Zoals je ziet, retourneert deze functie een TextStyle die gebruikt kan worden in een Text widget. Het kan zowel regular als bold font laten zien in elk formaat dat gebruikt wordt Ine een TextTheme in flutter. Dus alles van een BodySmall tot een DisplayLarge. De copyWith functie kan later gebruikt worden om wat aanpassingen te maken, zoals de color of line spacing, dus het is heel eenvoudig om te gebruiken 🙂

Playground

null

We wilden een nice demo app hebben om mee te kunnen spelen voor verschillende Type Scales en fonts. Daarom hebben we de FluidUI Playground als een voorbeeld toegevoegd aan de app op de Github repository. Je kan het zelf draaien of bekijken op onze online web app! IN deze playground kun je zelf je settings aanpassen en zien hoe een simpele layout zich aanpast aan verschillende schermgroottes en configuraties. Je kan later deze exacte configuratie gebruiken in je eigen project. Als je de code voor de playground wil zien, ga dan naar de example app op Github!

WDYT?

Dat is zo ongeveer de eerste versie van Fluid UI! We gaan deze aanpak binnenkort proberen in een echt project bij Dutch Coding Company om te zien hoe het in de praktijk werkt en we zullen onze ervaringen delen. We zijn ook heel benieuwd naar wat jij van deze aanpak denkt. Verwacht je dat het voor designers net zo fijn werkt als voor developers? Zijn er dingen die we vergeten zijn in onze implementatie? Laat het ons weten. Je kan me een persoonlijk bericht sturen op de contactgegevens hieronder. Een berichtje op Twitter kan ook rekenen op antwoord; volg me op @bassiuz!

Dit vind je misschien ook interessant:

Laat je project niet stranden omdat een goede strategie ontbreekt. Kijk of jouw idee klaar is voor ontwikkeling met onze Digital Readiness Scan. Binnen 5 vragen weet je wat je volgende stap naar succes is.

Naar de scan