如何实现新的 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 的文本?

如何使用recyclerview实现Material Design父子过渡

AngularJS Material Design 没有 Animations 支持,如何实现?