如何实现新的 Material Design 底部应用栏
Posted
技术标签:
【中文标题】如何实现新的 Material Design 底部应用栏【英文标题】:How to implement the new Material Design Bottom App Bar 【发布时间】:2019-08-31 13:57:02 【问题描述】:我的公司目前使用 Vue 和 scss 来构建我们最新的 PWA。在特定条件下(基于用户配置文件),左侧抽屉应替换为底部应用栏。
我们使用的是Vue Material,但我们的 UX 和 UI 设计师选择使用 Google 发布的最新版本的 Bottom App Bar。
但是,此特定组件的 CSS 尚未发布,并且不是 VueMaterial 组件库 (which currently support the older version) 的一部分,我正在努力重现新栏的第二个版本。
I can't post images so here is the link of what I'm refering to
我不明白如何使用纯 CSS 解决方案来重现栏和 FAB 之间的插图。我尝试使用 clip-path 和 mask-image 解决问题,但没有取得多大成功。
任何帮助或指导将不胜感激。
【问题讨论】:
【参考方案1】:这里有几个不同的选项。我添加了背景图像,因此很明显切口是透明的。
伪元素上的方框阴影
没有圆角,也不是很灵活。
body
height: 100vh;
background: url(https://placeimg.com/640/480/nature) center/cover no-repeat;
.bar
position: fixed;
right: 0;
bottom: 0;
left: 0;
height: 56px;
background: transparent;
overflow: hidden;
.bar::before
content: '';
position: absolute;
top: -32px;
left: 50%;
transform: translateX(-50%);
border-radius: 1000px;
width: 64px;
height: 64px;
box-shadow: 0px 0px 0px 5000px rebeccapurple;
<div class="bar"></div>
剪辑路径点的负载
代码取自this fiddle。
不是最容易配置的,但可能会创建一个预处理器 mixin 来处理这些点的生成。绝对比 box-shadow 技术提供更好的效果。
body
height: 100vh;
background: url(https://placeimg.com/640/480/nature) center/cover no-repeat;
.bar
position: fixed;
right: 0;
bottom: 0;
left: 0;
height: 56px;
background: rebeccapurple;
clip-path: polygon(0 0,
calc(50% - 38px) 0,
calc(50% - 37.487665px) 0.628287px,
calc(50% - 36.975331px) 1.256382px,
calc(50% - 36.462997px) 1.884094px,
calc(50% - 35.912306px) 2.511233px,
calc(50% - 35.863009px) 3.137607px,
calc(50% - 35.802788px) 3.763025px,
calc(50% - 35.731661px) 4.387296px,
calc(50% - 35.64965px) 5.010232px,
calc(50% - 35.55678px) 5.631641px,
calc(50% - 35.453079px) 6.251334px,
calc(50% - 35.338579px) 6.869124px,
calc(50% - 35.213314px) 7.484821px,
calc(50% - 35.077322px) 8.098238px,
calc(50% - 34.930646px) 8.709188px,
calc(50% - 34.77333px) 9.317486px,
calc(50% - 34.605421px) 9.922945px,
calc(50% - 34.426971px) 10.525381px,
calc(50% - 34.238035px) 11.124612px,
calc(50% - 34.038669px) 11.720454px,
calc(50% - 33.828934px) 12.312725px,
calc(50% - 33.608895px) 12.901246px,
calc(50% - 33.378619px) 13.485837px,
calc(50% - 33.138175px) 14.066321px,
calc(50% - 32.887636px) 14.642519px,
calc(50% - 32.62708px) 15.214257px,
calc(50% - 32.356586px) 15.781361px,
calc(50% - 32.076235px) 16.343658px,
calc(50% - 31.786113px) 16.900976px,
calc(50% - 31.486309px) 17.453146px,
calc(50% - 31.176915px) 18px,
calc(50% - 30.858023px) 18.541371px,
calc(50% - 30.529731px) 19.077094px,
calc(50% - 30.19214px) 19.607005px,
calc(50% - 29.845353px) 20.130945px,
calc(50% - 29.489474px) 20.648752px,
calc(50% - 29.124612px) 21.160269px,
calc(50% - 28.750878px) 21.665341px,
calc(50% - 28.368387px) 22.163813px,
calc(50% - 27.977255px) 22.655534px,
calc(50% - 27.5776px) 23.140354px,
calc(50% - 27.169545px) 23.618125px,
calc(50% - 26.753214px) 24.088702px,
calc(50% - 26.328733px) 24.551941px,
calc(50% - 25.896233px) 25.007701px,
calc(50% - 25.455844px) 25.455844px,
calc(50% - 25.007701px) 25.896233px,
calc(50% - 24.551941px) 26.328733px,
calc(50% - 24.088702px) 26.753214px,
calc(50% - 23.618125px) 27.169545px,
calc(50% - 23.140354px) 27.5776px,
calc(50% - 22.655534px) 27.977255px,
calc(50% - 22.163813px) 28.368387px,
calc(50% - 21.665341px) 28.750878px,
calc(50% - 21.160269px) 29.124612px,
calc(50% - 20.648752px) 29.489474px,
calc(50% - 20.130945px) 29.845353px,
calc(50% - 19.607005px) 30.19214px,
calc(50% - 19.077094px) 30.529731px,
calc(50% - 18.541371px) 30.858023px,
calc(50% - 18px) 31.176915px,
calc(50% - 17.453146px) 31.486309px,
calc(50% - 16.900976px) 31.786113px,
calc(50% - 16.343658px) 32.076235px,
calc(50% - 15.781361px) 32.356586px,
calc(50% - 15.214257px) 32.62708px,
calc(50% - 14.642519px) 32.887636px,
calc(50% - 14.066321px) 33.138175px,
calc(50% - 13.485837px) 33.378619px,
calc(50% - 12.901246px) 33.608895px,
calc(50% - 12.312725px) 33.828934px,
calc(50% - 11.720454px) 34.038669px,
calc(50% - 11.124612px) 34.238035px,
calc(50% - 10.525381px) 34.426971px,
calc(50% - 9.922945px) 34.605421px,
calc(50% - 9.317486px) 34.77333px,
calc(50% - 8.709188px) 34.930646px,
calc(50% - 8.098238px) 35.077322px,
calc(50% - 7.484821px) 35.213314px,
calc(50% - 6.869124px) 35.338579px,
calc(50% - 6.251334px) 35.453079px,
calc(50% - 5.631641px) 35.55678px,
calc(50% - 5.010232px) 35.64965px,
calc(50% - 4.387296px) 35.731661px,
calc(50% - 3.763025px) 35.802788px,
calc(50% - 3.137607px) 35.863009px,
calc(50% - 2.511233px) 35.912306px,
calc(50% - 1.884094px) 35.950663px,
calc(50% - 1.256382px) 35.97807px,
calc(50% - 0.628287px) 35.994517px,
50% 36px,
calc(50% + 0.628287px) 35.994517px,
calc(50% + 1.256382px) 35.97807px,
calc(50% + 1.884094px) 35.950663px,
calc(50% + 2.511233px) 35.912306px,
calc(50% + 3.137607px) 35.863009px,
calc(50% + 3.763025px) 35.802788px,
calc(50% + 4.387296px) 35.731661px,
calc(50% + 5.010232px) 35.64965px,
calc(50% + 5.631641px) 35.55678px,
calc(50% + 6.251334px) 35.453079px,
calc(50% + 6.869124px) 35.338579px,
calc(50% + 7.484821px) 35.213314px,
calc(50% + 8.098238px) 35.077322px,
calc(50% + 8.709188px) 34.930646px,
calc(50% + 9.317486px) 34.77333px,
calc(50% + 9.922945px) 34.605421px,
calc(50% + 10.525381px) 34.426971px,
calc(50% + 11.124612px) 34.238035px,
calc(50% + 11.720454px) 34.038669px,
calc(50% + 12.312725px) 33.828934px,
calc(50% + 12.901246px) 33.608895px,
calc(50% + 13.485837px) 33.378619px,
calc(50% + 14.066321px) 33.138175px,
calc(50% + 14.642519px) 32.887636px,
calc(50% + 15.214257px) 32.62708px,
calc(50% + 15.781361px) 32.356586px,
calc(50% + 16.343658px) 32.076235px,
calc(50% + 16.900976px) 31.786113px,
calc(50% + 17.453146px) 31.486309px,
calc(50% + 18px) 31.176915px,
calc(50% + 18.541371px) 30.858023px,
calc(50% + 19.077094px) 30.529731px,
calc(50% + 19.607005px) 30.19214px,
calc(50% + 20.130945px) 29.845353px,
calc(50% + 20.648752px) 29.489474px,
calc(50% + 21.160269px) 29.124612px,
calc(50% + 21.665341px) 28.750878px,
calc(50% + 22.163813px) 28.368387px,
calc(50% + 22.655534px) 27.977255px,
calc(50% + 23.140354px) 27.5776px,
calc(50% + 23.618125px) 27.169545px,
calc(50% + 24.088702px) 26.753214px,
calc(50% + 24.551941px) 26.328733px,
calc(50% + 25.007701px) 25.896233px,
calc(50% + 25.455844px) 25.455844px,
calc(50% + 25.896233px) 25.007701px,
calc(50% + 26.328733px) 24.551941px,
calc(50% + 26.753214px) 24.088702px,
calc(50% + 27.169545px) 23.618125px,
calc(50% + 27.5776px) 23.140354px,
calc(50% + 27.977255px) 22.655534px,
calc(50% + 28.368387px) 22.163813px,
calc(50% + 28.750878px) 21.665341px,
calc(50% + 29.124612px) 21.160269px,
calc(50% + 29.489474px) 20.648752px,
calc(50% + 29.845353px) 20.130945px,
calc(50% + 30.19214px) 19.607005px,
calc(50% + 30.529731px) 19.077094px,
calc(50% + 30.858023px) 18.541371px,
calc(50% + 31.176915px) 18px,
calc(50% + 31.486309px) 17.453146px,
calc(50% + 31.786113px) 16.900976px,
calc(50% + 32.076235px) 16.343658px,
calc(50% + 32.356586px) 15.781361px,
calc(50% + 32.62708px) 15.214257px,
calc(50% + 32.887636px) 14.642519px,
calc(50% + 33.138175px) 14.066321px,
calc(50% + 33.378619px) 13.485837px,
calc(50% + 33.608895px) 12.901246px,
calc(50% + 33.828934px) 12.312725px,
calc(50% + 34.038669px) 11.720454px,
calc(50% + 34.238035px) 11.124612px,
calc(50% + 34.426971px) 10.525381px,
calc(50% + 34.605421px) 9.922945px,
calc(50% + 34.77333px) 9.317486px,
calc(50% + 34.930646px) 8.709188px,
calc(50% + 35.077322px) 8.098238px,
calc(50% + 35.213314px) 7.484821px,
calc(50% + 35.338579px) 6.869124px,
calc(50% + 35.453079px) 6.251334px,
calc(50% + 35.55678px) 5.631641px,
calc(50% + 35.64965px) 5.010232px,
calc(50% + 35.731661px) 4.387296px,
calc(50% + 35.802788px) 3.763025px,
calc(50% + 35.863009px) 3.137607px,
calc(50% + 35.912306px) 2.511233px,
calc(50% + 36.462997px) 1.884094px,
calc(50% + 36.975331px) 1.256382px,
calc(50% + 37.487665px) 0.628287px,
calc(50% + 38px) 0,
100% 0,
100% 100%,
0 100%);
<div class="bar"></div>
SVG 剪辑路径
我想不出一种方法来让它工作,而不必用 javascript 修改路径。但是,它确实可以让您创建任何您喜欢的形状。
body
height: 100vh;
background: url(https://placeimg.com/640/480/nature) center/cover no-repeat;
.bar
position: fixed;
right: 0;
bottom: 0;
left: 0;
height: 56px;
background: rebeccapurple;
overflow: hidden;
clip-path: url(#circle);
<svg >
<defs>
<clipPath id="circle">
<path d="M0,64 v-64 h100 a32,32 0,0,0 64,0 h100 v64 z" />
</clipPath>
</defs>
</svg>
<div class="bar"></div>
【讨论】:
感谢您为我指明了正确的方向!我终于暂时使用了你的第一个解决方案,因为圆边的材料规格不清楚。 詹姆斯,感谢您的指点!我使用了 clip-path 方法并将 FAB 按钮关闭在右侧,并在底部应用栏上使用其他图标操作,请参阅 biblescout.app/#!/law-and-prophets 。【参考方案2】:很多可能性,但这里是一个简单的例子:
$size: 45px;
div
background: #550000;
float:left;
.bottom
height: 45px;
width: 45px * 2;
.left, .right
height: 45px * 1.5;
width: 45px * 2;
.bottom
background: #fff;
border-bottom-left-radius: 45px * 2;
border-bottom-right-radius: 45px * 2;
.top
height: 45px*1.28;
margin-top: 20px;
.left
border-top-right-radius: 20px;
margin-top: 10px;
.right
border-top-left-radius: 20px;
margin-top: 10px;
html:
<div class="left"></div>
<div class="top"><div class="bottom"></div></div>
<div class="right"></div>
https://codepen.io/anon/pen/YMZwBM
【讨论】:
如果这是一个要求,那么使用和 svg/多边形或图像作为背景可能是要走的路。以上是关于如何实现新的 Material Design 底部应用栏的主要内容,如果未能解决你的问题,请参考以下文章
Material Design Support 8大控件介绍
Material Design — 按钮( Buttons)
《Android进阶之光》--Material Design
如何更改 Material Design ActionBar 的文本?