Designing Dynamic Footer in Flutter Web

Abraham Aditya
Bina Nusantara IT Division
4 min readJan 4, 2024

Footer is the final section of a web page, often containing additional information, links, and other design elements. It is the area located beneath the main content, providing a visual conclusion that enhances the overall appearance of the site.

Recognizing the significance of the Footer section on a web page is evident through the numerous search results on search engines inquiring, “how to create a proper footer?” This pertains not only to the design elements of the Footer but also to the strategic positioning, ensuring that the Footer behaves in a manner befitting its purpose.

In its implementation in Flutter, the framework provides the BottomNavigationBar widget, which is highly suitable for creating footers. This widget allows the addition of icons and text for each item, along with mechanisms for handling page transitions. However, it’s worth noting that BottomNavigationBar is specifically tailored for mobile devices, given its behavior of sticking to the bottom of the screen. Therefore, it may be less suitable for implementation on web platforms, as this sticky behavior is less common in the footers of many websites today.

Considering the aforementioned challenges, I aim to create a simple web template that can implement a dynamic Footer position structure along with other web components. Dynamic, in this context, implies that the placement of the Footer is determined based on certain conditions. The conditions are as follows:

  1. First Dynamic Condition: IF the height of the body or web content is less than the screen height, THEN there will be a widget that creates a space area allowing the Footer to position itself right at the bottom of the screen [IF contentBodyHeight < screenHeight THEN Footer is stickToBottomScreen]. The rationale behind this condition is that one of the Footer’s behaviors is to remain anchored at the bottom of the screen, ensuring it does not detach and can move upwards.
  2. Second Dynamic Condition: IF the height of the body or web content is greater than the screen height, THEN the space area between the body and Footer will be exhausted, causing the Footer to be positioned directly beneath the body, and the body will become scrollable [IF contentBodyHeight > screenHeight THEN Footer is not stickToBottomScreen]. The rationale behind this condition is that the Footer becomes a component that follows the body, allowing it to be scrollable downward and not stick to the bottom of the screen.

Here is the result of the implementation of the dynamic Footer web template.

Here is how to create it:

Step 1: Creating the Scaffold Class

Here, as usual, a Scaffold class is created, and I have added code comments for the backgroundColor property. This property can be utilized if condition 1 is met, to blend the color with the content widget if needed.

class MyTemplateWeb extends StatelessWidget {
const MyTemplateWeb({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
// backgroundColor: Colors.grey, // Can be used to match the color with the content widget..
body: MyPage(),
);
}
}

Step 2: Creating the Body Class for the Scaffold

Here, as usual, a Scaffold class is created, and I have added code comments for the backgroundColor property. This property can be utilized if condition 1 is met, to blend the color with the content widget if needed.
This is the main part of the dynamic footer. In the Scaffold body, there will be only 3 main widgets: MyHeader, MyContents (where all body content is created), and MyFooter.
All the height size requirements for the three widgets will be declared in this class (and passed as size values to each widget). The goal is to perform calculations in SizedBox to condition the size of the space area.

class MyPage extends StatelessWidget {
const MyPage({super.key});
@override
Widget build(BuildContext context) {
// Register height of content widgets here..
double headerHeight = 80;
double contentHeight = 400;
double footerHeight = 100;
return Stack(
children: [
LayoutBuilder(
builder: (context, constraints) {
double screenHeight =
constraints.maxHeight - (headerHeight + footerHeight);
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: screenHeight,
),
child: Column(
children: [
MyHeader(height: headerHeight),
MyContents(height: contentHeight),

// Dynamic position of height space widgets..
if (contentHeight < screenHeight) ...[
SizedBox(height: screenHeight - contentHeight)
],
MyFooter(height: footerHeight),
],
),
),
);
},
)
],
);
}
}

Step 3: Creating the Three Main Widgets

Here, you can create the three main widgets, and the MyContents widget will accommodate all the content widgets. Of course, adjustments may be needed for the height size in the MyPage class if the content loaded in MyContents is substantial.

class MyHeader extends StatelessWidget {
final double height;
const MyHeader({Key? key, required this.height}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.amber,
height: height,
child: const Center(
child: Text(
'Header Widget',
style: TextStyle(color: Colors.black),
),
),
);
}
}

class MyContents extends StatelessWidget {
final double height;
const MyContents({Key? key, required this.height}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: height,
width: double.infinity,
color: Colors.grey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
// Put the content widgets here..
Text('Content Widget'),
],
),
);
}
}

class MyFooter extends StatelessWidget {
final double height;
const MyFooter({Key? key, required this.height}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.black,
height: height,
child: const Center(
child: Text(
'Footer Widget',
style: TextStyle(color: Colors.white),
),
),
);
}
}

Closing

Dynamic Footer Web Template is a part of how to implement a dynamic footer in Flutter. Certainly, the implementation of a dynamic footer requires coordination with the overall web components to function effectively.
For the source code documentation, you can access it here.

--

--