Achieving responsiveness across various device sizes is an integral part of building any product web or mobile, especially now that we are moving into the era of foldable phones (Foldables again ! ๐ฉ, I would rant in another article ๐).
Today we will go over achieving responsiveness with Flutter for the web, to fully understand the concept of web responsiveness, we must first take a trip to the conventional web development world (the HTML and CSS world I mean ๐)
The Conventional Web Development World...
In the conventional web development world (Flutter is about to make it unconventional though ๐), CSS has a popular framework called Bootstrap 5 which is primarily used to achieve responsiveness across various screen sizes for a web app or website. However, packages like flutter_bootstrap5 in Flutter give the same edge and with minimal code as well, Mind-Blowing right?
I played around with the package and I would try to explain the usage of this package with the code of what I came up with.
Using the Flutter Bootstrap5 package
dependencies:
flutter_bootstrap5: ^1.1.1+1
Like every other package in Flutter, we must first add the package to our dependency.
import 'package:flutter/material.dart';
import 'package:flutter_bootstrap5/flutter_bootstrap5.dart';
void main() => runApp(FlutterBoostrap());
class FlutterBoostrap extends StatelessWidget {
const FlutterBoostrap({super.key});
@override
Widget build(BuildContext context) {
return FlutterBootstrap5(
builder: (BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: BootStrapWebsite(),
theme: BootstrapTheme.of(context).toTheme(
theme: ThemeData(
scaffoldBackgroundColor:
BootstrapTheme.of(context).colors.black50,
appBarTheme: AppBarTheme(
elevation: 0.0,
),
),
),
);
},
);
}
}
To get access to the elements of the flutter bootstrap5 or FB5 (would be using FB5 for the most time in this article), we would have to wrap our Material App with the FB5 Widget as seen in the code above (and now we can make magic ๐).
We would be using a custom widget _buildCard just to populate the space on the website, here I make use of a card widget that takes two string parameters namely title and content.
Widget _buildCard(String title, String content) {
return Card(
child: Column(
children: [
Text(
title,
style: TextStyle(
fontSize: 50.0,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
SizedBox(height: 10.0),
Text(
content,
style: TextStyle(
fontSize: 50.0,
color: Colors.black,
),
),
SizedBox(height: 10.0),
TextButton(
onPressed: () {},
child: Text(
content,
style: TextStyle(
color: Colors.white,
),
),
),
],
),
);
}
Now let's go through the elements of FB5,
FB5 Containers
The containers set the maximum width at respective breakpoints, the options are as follows fluid, md, sm, xl, xxl, lg.You can refer to Containers. Bootstrap v5.2 for more specifics about the container sizes.
๐ NB: I would be using a fluid container for this practice project as it sets the container max-width 100% across different screen sizes
FB5 Rows
This is the same as the row widget we know in Flutter, but in this stance, it takes a list FB5Col as its children, and it has a classNames parameter and if specified it arranges its children as specified by the class name.๐ NB: The classNames parameter is used to describe the behavior of the children in any FB5 widget from spacing to row and column arrangement(i.e. in a grid system) etc.
FB5Col
As explained earlier, the FB5Col can only be used inside an FB5 Row widget, and it specifies children of the FB5Row widget.FB5 GRID
used to represent the grid system.
BootStrap Theme
This comes in handy for decorating your website or web app and even when specifying breakpoints as well.
๐ NB: you don't have to use BootStrap theme for beautification, you can always rely on inbuilt widget parameters like colors, font size, etcNow let's use FB5 to work. I also want to use the themes of FB5, so I would be wrapping my BootStrapWebsite class with the BootstrapTheme
๐ NB: I already set the home parameter of the materialApp to BootStrapWebsite in the previous code shared above.
class BootStrapWebsite extends StatelessWidget {
const BootStrapWebsite({super.key});
@override
Widget build(BuildContext context) {
return BootstrapTheme(
data: BootstrapTheme.of(context),
builder: (context) {
return FB5Container.fluid(...
Now let's work on the app bar, BootstrapTheme is used to give the background color of the app bar and some other basic customizations as well (my focus is more on the usage of the FB5 elements)
AppBar(
backgroundColor: BootstrapTheme.of(context).colors.secondary,
leading: PopupMenuButton(
itemBuilder: (context) => [
PopupMenuItem(
child: Text(
'Exploring the power of Flutter Bootstrap 5 ๐'),
),
]),
elevation: 0,
title: Text(
'Flutter Bootstrap 5',
),
actions: [
TextButton(
child: Text(
'Home',
style: TextStyle(color: Colors.white),
),
onPressed: () {},
),
TextButton(
onPressed: () {},
child: Text(
'About',
style: TextStyle(color: Colors.white),
),
),
TextButton(
onPressed: () {},
child: Text(
'Contact Us',
style: TextStyle(
color: BootstrapColors.white,
),
),
),
SizedBox(width: 50.0),
],
),
Now let's make use of an FB5 Row, using the classNames parameter we give a top margin of 5 and horizontal padding of 5, and the children (FB5 col) take the _buildCard as its child.
๐ NB: mt is margin-top and px is horizontal padding
FB5Row(
classNames: 'mt-5 px-5',
children: [
FB5Col(
child: _buildCard('Card 1', 'This is card 1'),
),
FB5Col(
child: _buildCard('Card 2', 'This is card 2'),
),
FB5Col(
child: _buildCard('Card 3', 'This is card 3'),
),
FB5Col(
child: _buildCard('Card 4', 'This is card 4'),
),
],
),
Now let's make use of the FB5Grid, here I used the classNames parameter to divide the row into 7 columns and the children take the _buildCard widget
FB5Grid(
classNames: 'row-cols-7',
children: [
_buildCard('Hi', 'This is Grid 1'),
_buildCard('Hi', 'This is Grid 2'),
_buildCard('Hi', 'This is Grid 3'),
_buildCard('Hi', 'This is Grid 4'),
_buildCard('Hi', 'This is Grid 5'),
_buildCard('Hi', 'This is Grid 6'),
],
)
Here is the result of what I created below, (I know the UI is bad ๐, just focus on the responsiveness ๐)
A link to the GitHub repo as well if you are interested in checking the full code out. You should explore more with the package to discover even more possibilities.