CSS 中 Flutter 样式的解释 - LLF #5

2025-06-10

CSS 中 Flutter 样式的解释 - LLF #5

👋

CSS 可能很奇怪,让人困惑,所以让我用它作为比较来解释 Flutter 的样式。Flutter 的样式相当简单,这在我看来是不可接受的,样式就应该总是令人困惑和奇怪。


玩笑归玩笑,CSS 被广泛使用,所以我想尝试使用 CSS 作为比较示例来解释 Flutter 的样式。

它们在命名、属性(样式)值以及您期望的渲染输出方面有很多共同之处。但与 Web 不同的是,在 Flutter 中,您可以使用与应用程序其他部分相同的语言编写样式,而无需为样式单独编写语言。在 Flutter 中,我们使用 Dart 语言本身编写样式。

让我们看一下构建 Flutter 应用程序时将使用的一些最常见的样式。

这里有包含本文提到的所有 Flutter 代码的仓库。

目录

布局

让我们从布局开始。无论是 Flutter 还是 CSS,我们都可以随意定位和组织元素/Widget。我们可能想让某些项目排成一行或一列,又或者想创建一个可滚动的列表。

让我们看一下我们将使用的一些更常见的布局:

柱子

将元素列表放置在垂直方向(或列)中。

CSS

<div class="column">
    <div class="item">...</div>
    <div class="item">...</div>
    ...
</div>
Enter fullscreen mode Exit fullscreen mode

在 CSS 中,上面的代码会自动将元素放置items在一列中。但为了更好地模仿 Flutter,我们来举个例子,看看如何使用 flex-box 来实现:

<style>
    .column {
        display: flex;
        flex-direction: column;
    }
</style>
Enter fullscreen mode Exit fullscreen mode


build(context) {
    return Column(
        children: [
            Item(),
            Item(),
        ],
    );
}
Enter fullscreen mode Exit fullscreen mode

正如您所见,Flutter 采用了更具组合性的方法,更喜欢使用小部件而不是属性。

要将物品排成一排,也是同样的操作。

CSS

<style>
    .row {
        display: flex;
        flex-direction: row;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

在 CSS 中,我们只需要将 flex-direction 更改为row,这样所有项目就会水平并排放置。


build(context) {
    return Row(
        children: [
            Item(),
            Item(),
        ],
    );
}
Enter fullscreen mode Exit fullscreen mode

在 Flutter 中,我们可以切换Column小部件Row并进行排序!

列和行都是 Flex

一些属性是默认设置的,而另一些属性是强制设置的(比如方向)。我们可以使用 Flex 代替 Row 或 Column,在下面的例子中,它将渲染与使用 Column 相同的内容:

build(context) {
    return Flex(
        direction: Axis.vertical,
        children: [
            Item(),
            Item(),
        ],
    );
}
Enter fullscreen mode Exit fullscreen mode

中心

你们喜欢居中效果吗?我喜欢,而且 Flutter 让居中变得非常简单。假设我们想把一个图标放在一个盒子的中央。

CSS
在 CSS 中,有很多不同的方法可以做任何一件事,我们可以使用我们的老朋友flex-box

<div class="box">
    <span class="icon">...</span>
</div>

<style>
    .box {
        width: 30px;
        height: 30px;
        display: flex;
        justify-content: center;
        align-items: center;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

或者,我们可以使用绝对定位:


<style>
.container {
  height: 200px;
  position: relative;
  border: 3px solid green;
}

.center {
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}
</style>

<div class="container">
  <div class="center">
    <button>Centered Button</button>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Flutter
就像在 CSS 中一样,我们可以通过多种方式将内容置于屏幕中央

使用 Center 小部件,如果我们只有一个子部件:

build(context) {
    return Center(
        child: Item()
    );
}
Enter fullscreen mode Exit fullscreen mode

或者,如果我们有多个元素,我们可以将元素置于列或行的中心:

build(context) {
    return Row(
        mainAxisAligment: MainAxisAlignment.center,
        crossAxisAligment: CrossAxisAlignment.center,
        children: [
            Item(),
            Item(),
        ],
    );
}
Enter fullscreen mode Exit fullscreen mode

这将使所有项目水平和垂直居中。

请注意,使用这种方法,我们可以以各种方式定位项目,例如spaceBetween,spaceEvenly等...

如果我们想将一个元素放置在另一个元素之上,或者放置在右上角,该怎么办?这完全可以。

CSS
在 CSS 中,我们会使用绝对定位

<div class="parent">
    <span class="child">...</span>
</div>

<style>
    .parent {
        width: 30px;
        height: 30px;
        position: relative; <!-- This is required -->
    }

    .child {
        position: absolute;
        top: 15px;
        right: 15px;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Flutter
在 Flutter 中,我们通过使用Stack小部件来实现这一点:

Stack(
  children: [
    Container(
        width: 100,
        height: 100,
    ),

    // This will be rendered on top of previous widgets
    Positioned(
        top: 15, 
        right: 15,
        child: Icon(Icons.close),
    ),
  ],
);
Enter fullscreen mode Exit fullscreen mode

堆栈:一个将其子项相对于其框的边缘定位的小部件。

CSS 渲染方式

这是它在 CSS 中的样子


文本

任何用户界面中最重要的元素之一就是文本。如果没有文本,我们的应用和网站就只是一堆方框和图像。让我们看看如何添加和处理文本。

段落

CSS
在css中我们通常使用<p>标签:

<p>
    CSS stands for Complicated Sac of Sheets
</p>
Enter fullscreen mode Exit fullscreen mode

加点颜色怎么样?很简单

<p class="red">
    CSS stands for Complicated Sac of Sheets
</p>

<style>
    .red {
        color: red;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Flutter
Flutter 还提供了一个简单的小部件来帮助我们渲染文本,称为 Text:

Text('Flutter is a type of arrhythmia');
Enter fullscreen mode Exit fullscreen mode

并且着色也很简单:

Text(
    'Flutter is a type of arrhythmia',
    style: TextStyle(color: Colors.red),
);
Enter fullscreen mode Exit fullscreen mode

一个段落中有多种样式

CSS
在 CSS 中,我们可以<span>在元素内部嵌套元素<p>,并为每个元素赋予特定的样式:

<p>
    CSS stands for <span class="css-description">Complicated Sac of Sheets</span>
</p>

<style>
    p {
        color: #666666;
        font-size: 14px;
    }

    .css-description {
        color: brown;
        font-size: 20px;
    }

</style>
Enter fullscreen mode Exit fullscreen mode

Flutter
在 Flutter 中我们必须使用 RichText 小部件才能做到这一点,让我们来看看:

RichText(
    text: TextSpan(
        children: [
            TextSpan(
                text: 'Flutter is',
                style: TextStyle(
                    color: Color(0xff666666),
                    fontSize: 14,
                ),
            ),
            TextSpan(
                text: 'a type of arrhythmia',
                style: TextStyle(
                    color: Colors.brown,
                    fontSize: 20,
                ),
            )
        ],
    ),
);
Enter fullscreen mode Exit fullscreen mode

正如您在 Flutter 中看到的,与 CSS 相比,它有点麻烦。

示例中文本的图像

示例中提到的文本在 CSS 中如下所示


图片

CSS
在 CSS 中显示图像很容易,只需添加一个<img>标签并将 src 属性设置为图像路径或链接。

<img src="http://example.images.com/my-image.png">
Enter fullscreen mode Exit fullscreen mode

Flutter
在 Flutter 中它非常相似,但我们根据图像的加载位置以不同的方式创建图像。

网络图像

Image.network('http://example.images.com/my-image.png');
Enter fullscreen mode Exit fullscreen mode

查看更多

资产图像

Image.asset('assets/my-image.png');
Enter fullscreen mode Exit fullscreen mode

查看更多

记忆图像:

Image.memory(bytes);
Enter fullscreen mode Exit fullscreen mode

查看更多

文件图片:

Image.file(file);
Enter fullscreen mode Exit fullscreen mode

查看更多

奖金模因


盒子装饰品

我们都喜欢那些带有圆角、边框和过度渐变的盒子,对吗?

边界

在 CSS 中我们设置border属性

<div class="parent"></div>

<style>
    .parent {
        width: 150px;
        height: 150px;
        border: 2px solid green;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Flutter在 Flutter 中我们可以通过在容器中
设置来为容器添加边框borderBoxDecoration

Container(
    decoration: BoxDecoration(
        border: Border.all(
            color: Colors.green, 
            width: 2,
        ),
    ),
    child: ...
)
Enter fullscreen mode Exit fullscreen mode

边界半径

CSS
在 CSS 中我们使用border-radius属性

<div class="parent"></div>

<style>
    .parent {
        width: 150px;
        height: 150px;
        border-radius: 10px;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Flutter
在 Flutter 中,我们可以为容器添加圆角,添加BorderRadius到容器中BoxDecoration

Container(
    decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(10),
    ),
    child: ...
)
Enter fullscreen mode Exit fullscreen mode

或者只是在容器顶部添加半径:

Container(
    decoration: BoxDecoration(
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10),
            topRight: Radius.circular(10),
        ),
    ),
    child: ...
)
Enter fullscreen mode Exit fullscreen mode

想要给任何小部件添加圆角吗?使用ClipRRect可以让我们为任何子部件添加圆角:

ClipRRect(
    borderRadius: BorderRadius.circular(10),
    child: Image.network(
        '...',
        height: 150.0,
        width: 100.0,
    ),
)
Enter fullscreen mode Exit fullscreen mode

渐变

CSS
在 CSS 中我们可以设置渐变作为元素的背景:

<div class="parent"></div>

<style>
    .parent {
        width: 150px;
        height: 150px;
        background: linear-gradient(70deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%);
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Flutter在 Flutter 中,我们还可以将LinearGradient
添加到容器中BoxDecoration

Container(
    decoration: BoxDecoration(
        gradient: LinearGradient(
            colors: [
                Colors.yellow, 
                Colors.red,
            ],
            stops: [0, 1] 
        ),
    ),
    child: ...
)
Enter fullscreen mode Exit fullscreen mode

了解更多


这就是本文的全部内容,我希望你能从中有所收获,并且它不会让你感到困惑,反而会给你带来帮助😅

这些只是我可以比较的一些风格,所以如果人们感兴趣的话,我可能会将其转换成迷你系列。

一如既往,感谢您的阅读。如果您有任何建议、疑问,或者希望我在这些文章中涵盖的内容,请记得留言。


如果你有兴趣阅读更多内容,本系列的下一篇文章与此类似,但针对 JS/React 开发人员

鏂囩珷鏉ユ簮锛�https://dev.to/nombrekeff/flutter-styling-explained-in-css-llf-5-51nm
PREV
我努力工作是为了逃避工作——我对重构的看法
NEXT
从 Blob 下载任何文件