如果我们想构建真实的响应组件,通常不再足以让某些东西滑入下一行。有时有必要改变组件的结构,这可能很快变得复杂。我想使用以下示例来显示如何使用Flexbox和Grid解决该问题。
这个例子
让我们假设我们要实现以下卡:
该卡由头像,标题和简短的描述文本组成。
在移动视图中,头像和标题应在同一行中,描述应占据下面的整个行。
对于较大的视口,我们希望化身更大,并且描述也位于头像旁边。
好吧,让我们看看我们如何实现。
Flex解决方案
我们从flexbox实现开始,因为我总是从flexbox开始。
移动变体的初始实现看起来像这样:
<section>
<div className="flex items-center gap-4">
<Avatar className="h-16 w-16" />
<h3 className="text-2xl font-bold">Title</h3>
</div>
<p className="mt-5">Description</p>
</section>
但是,当我们尝试实现较大的视口时,它会很快变得困难。
问题是结构发生了变化。
我在这里能想到的唯一解决方案是复制描述:
<section>
<div className="flex items-center gap-4">
<Avatar className="h-16 w-16 flex-shrink-0 sm:h-24 sm:w-24" />
<div className="w-full">
<h3 className="text-2xl font-bold">Title</h3>
<p className="mt-5 hidden sm:block">Description</p>
</div>
</div>
<p className="mt-5 sm:hidden">Description</p>
</section>
要解决问题,我们必须将标题和描述与div
分组,
隐藏描述(hidden
)和
仅在我们处于较大的视口时显示它(sm:block
)。
默认情况下显示小视口的描述,
当我们处于较大的视口(sm:hidden
)中时,隐藏了。
,但我们需要做更多的事情。
标题的分组可能会导致化身挤压,
因此,我们需要将w-full
添加到分组div
和flex-shrink-0
中。
此解决方案远非最佳。
我们必须包括更多标记,我们必须复制内容。
可能有一种更好的方法来解决flexbox,
但是我想不到一个。
如果您知道更好的解决方案,请发表评论
救援
让我们尝试用网格而不是flexbox实现相同的布局。
我们再次从移动视图开始:
<section className="grid grid-cols-[5rem,1fr] items-center">
<Avatar className="h-16 w-16" />
<h3 className="text-2xl font-bold">Title</h3>
<p className="col-span-2 mt-5">Description</p>
</section>
除了网格验证的任意值外,整个过程都很简单。
我们创建一个带有2列的网格,第一列是5REM宽(比头像宽),第二个是1FR宽(grid grid-cols-[5rem,1fr]
)。
在第一行的第一列中是阿凡达,
在第二列中是标题。
我们将描述扩展到两列(col-span-2
)和
它在第二行中。
在较大的视口,
实际上,我们只需要在2行上绘制头像和
取回描述的col跨度。
整个过程看起来像这样:
<section className="grid grid-cols-[5rem,1fr] items-center sm:grid-cols-[7rem,1fr]">
<Avatar className="row-span-2 h-16 w-16 sm:h-24 sm:w-24" />
<h3 className="text-2xl font-bold">Title</h3>
<p className="col-span-2 mt-5 sm:col-span-1">Description</p>
</section>
使用row-span-2
,我们可以在行上绘制头像和
使用sm:col-span-1
,我们重置了描述的col跨度。
我们还必须在网格的第一列(sm:grid-cols-[7rem,1fr]
)中为阿凡达(Avatar)预留更多的空间。
结论
使用网格解决方案,我们需要更少的标记。
我们也不再需要重复,也更容易理解。