Flutter: Neumorphic Button

Wartelski.
4 min readAug 14, 2023

--

Neumorphic design is a visual trend that has gained traction with UI/UX designers and become a popular aesthetic choice for contemporary software, websites, and mobile apps.

Nowadays, it is all about aesthetics and minimalistic designs. Neumorphic buttons are specially designed buttons which will give your app an aesthetic touch.

The term “neumorphism” became more widely known after a 2019 Dribbble post by designer Oleksandr Plyuto, who showcased a UI concept using this design approach. However, it’s important to note that similar design elements had been explored by other designers before Plyuto’s post. The trend gained momentum as more designers started adopting the style, sharing their work on platforms like Dribbble and Behance, and discussing the pros and cons of neumorphic design.

Neumorphic Design Features:

  • UI elements in neumorphic design: buttons, toggles, cards
  • Soft, semi-3D appearance
  • Created using subtle shadows, highlights, and gradients
  • Two shadows used: one light, one dark
  • Light shadow: top-left corner
  • Dark shadow: bottom-right corner
  • Illusion of depth, as if UI elements are extruded from the background

Pros & Cons of Neumorphic Design

Some benefits of neumorphism include:

Aesthetic appeal: Neumorphic designs can be visually pleasing, offering a fresh and modern look that combines the best of flat design and skeuomorphism.
Intuitive user experience: The soft, 3D appearance of neumorphic elements can make them more recognizable and easier to interact with, providing a more intuitive user experience.

However, there are also some criticisms and challenges associated with neumorphism:

Accessibility concerns: The subtle differences in color and shadow can make it difficult for some users, particularly those with visual impairments, to distinguish UI elements. This may lead to accessibility issues.
Limited color palette: Neumorphism’s reliance on a monochromatic color scheme may not suit all projects, as it can limit creative expression and branding opportunities.

The Fall of Neumorphism

Neumorphic design is still recognizable as of 2023. While Neumorphism offers a visually pleasing experience, it doesn’t seek to improve pre-existing issues.

The fall of Neumorphism is likely because of the following reasons:

  1. Accessibility concerns: the use of subtle color differences, shadows, and depth can create challenges for users with visual impairments. As the design community becomes more focused on inclusive and accessible design, neumorphism’s limitations in this regard may result in decreased adoption.
  2. Practicality and usability: The visual style of neumorphism might not always translate well into practical and usable interfaces, as the subtle depth effects can sometimes reduce the clarity of UI elements. Designers may prioritize other styles that provide a more intuitive user experience and clear visual cues.
  3. Limited color palette: Reliance on a monochromatic color scheme can restrict creative expression and branding opportunities, making it less appealing for designers and clients who require more vibrant or varied color options.
  4. Evolving design trends: Design trends change over time, with new styles emerging and capturing the attention of the design community. It’s possible that other design trends (like glassmorphism or further evolutions of flat design) may have gained popularity, overshadowing neumorphism.
  5. Experimentation: Neumorphism might have been a temporary trend that served as an experimental phase for designers exploring different ways to incorporate depth and tactility into user interfaces. As designers continue to refine their approach, they may develop new styles that build upon or move away from neumorphism.

However, a lot of the designs we see do have quite a bit of overlap. Minimalism and Neumorphism have a few things in common, and they’re commonly used by Apple’s iOS designs.

How to create neumorphic button in Flutter

Code:

main.dart



import 'package:flutter/material.dart';
import './neumorphism.dart';


void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: const NeumorphismButtonDemo(),
);
}
}

neumorphism.dart

import 'package:flutter/material.dart' hide BoxDecoration, BoxShadow;
import 'package:flutter_inset_box_shadow/flutter_inset_box_shadow.dart';

class NeumorphismButtonDemo extends StatefulWidget {
const NeumorphismButtonDemo({super.key});

@override
State<NeumorphismButtonDemo> createState() => _NeumorphismButtonDemoState();
}

class _NeumorphismButtonDemoState extends State<NeumorphismButtonDemo> {
bool isElevated = true;

@override
Widget build(BuildContext context) {
Offset distance = isElevated ? const Offset(5, 5) : const Offset(10, 10);
double blur = isElevated ? 15.0 : 20.0;
return Scaffold(
backgroundColor: Colors.grey[300],
body: Center(
child: GestureDetector(
onTap: () {
setState(() {
isElevated = !isElevated;
});
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: 100,
width: 100,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Colors.grey[500]!,
offset: distance,
blurRadius: blur,
spreadRadius: 1,
inset: isElevated,
),
BoxShadow(
color: Colors.white,
offset: -distance,
blurRadius: blur,
spreadRadius: 1,
inset: isElevated,
)
],
),
child: const Icon(
Icons.home,
size: 40,
color: Colors.green
),
),
),
)
);
}
}
  • use Animated Container to make the transition between states smoother
  • we need a boolean which tells us if our button is elevated or not: add a boolean variable and, inside the onTap() function of GestureDetector(), change its current state.
  • we need two different shadows for two corners: one will generate a shadow effect and the other will generate a blend effect.
  • Flutter currently does not support the inset property for shadows. So I used flutter_inset_box_shadow package. To make it work:

add the package:

flutter pub add flutter_inset_box_shadow

then, import it as follows:

import 'package:flutter/material.dart' hide BoxDecoration, BoxShadow;
import 'package:flutter_inset_box_shadow/flutter_inset_box_shadow.dart';

It is necessary to hide BoxDecoration and BoxShadow because this library replaces them.

I hope you found it informative; please give it a couple claps if it was. 🙂

If you are interested in such a topic as Flutter, feel free to follow me on Medium.

--

--

Wartelski.

Fullstack Flutter developer building cross-platform apps for startups. Passionate about web development, cybersecurity, and the latest tech trends. ©