Search code examples
flutterflutter-layoutflutter-web

Why don't the buttons in Flutter Web have a margin?


I have the following code:

Scaffold(
      appBar: AppBar(
        title: Text('Test'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {},
              child: Text('Boton 1'),
            ),
            ElevatedButton(
              onPressed: () {},
              child: Text('Boton 2'),
            ),
            ElevatedButton(
              onPressed: () {},
              child: Text('Boton 3'),
            ),
          ],
        ),
      ),
    )

Why on mobile do the buttons have a margin but on the web they do not?

Note: I know I can add padding/margin manually, set default button style, etc. I want to know why the default behaviour is different.

enter image description here


Solution

  • Quite an interesting question. Thanks for asking.

    This is basically due to the ThemeData.materialTapTargetSize parameter for the MaterialApp.

    This feature decides what should be touchable dimensions of Material Button, in your case ElevatedButton.

    The difference in behaviour is due to this piece of code in flutter/lib/src/material/theme_data.dart at line no 377. flutter sdk: ">=2.12.0 <3.0.0"

    switch (platform) {
      case TargetPlatform.android:
      case TargetPlatform.fuchsia:
      case TargetPlatform.iOS:
        materialTapTargetSize ??= MaterialTapTargetSize.padded;
        break;
      case TargetPlatform.linux:
      case TargetPlatform.macOS:
      case TargetPlatform.windows:
         materialTapTargetSize ??= MaterialTapTargetSize.shrinkWrap;
        break;
    }
    

    The MaterialTapTargetSize.padded, make buttons take a height of 48. Whereas, the MaterialTapTargetSize.shrinkWrap does what it says and removes that constraint.

    If you have your MaterialApp like this,

    MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
      home: CupertinoPickerExample(),
    )
    

    Then the out put is,

    enter image description here