分享开发时遇到的一些 ui 界面问题以及解决思路

1,086 阅读4分钟

前言

都是些简单案例,佬勿喷呀,面向基础像本人这样较一般的群体。

连续圆角分隔的 tab

设计稿中的样式大致如下:

image.png

从上面的三个选中项可以看到,点击到的元素需要背景变白,并且需要有圆角产生。

而正常情况下开发的圆角效果大多只能做到这样。

image.png

实现方法

我的思路可能一般般,感兴趣的可以先自行尝试一下,不要被我的思路影响到了。

整体 html 结构大致如下:

{/* 渐变背景色 */}
<div className="com-navbar">
  {/* 白色背景 用于遮挡下半部分 */}
  <div className="nav-bg"></div>
  {/* 定位覆盖背景元素 */}
  <div className="nav-wrap">
    <div>Vue</div>
    <div>React</div>
    <div>Js</div>
  </div>
</div>
  1. 给每个 tab 添加一个背景色和圆角,背景色由于是从左向右渐变的,所以取整体每个 tab 最左和最右那个区域的即可。
image.png image.png
  1. 给整体背景填充上正常的渐变色,此时就把缺失的边角填充上颜色了。
image.png
  1. 在整体背景上铺垫一个白色的盒子,然后再将这三个 tab 覆盖到背景上面即可实现该效果了。
image.png Kapture 2024-05-27 at 15.37.50.gif

代码放码上掘金了,有需要自提。

三角形

相信大家经常都会遇到这样的设计稿,切图当然能够解决,但是当里面的内容 (Date) 是变化的,宽高等会变化时,就又要自己搓 css 了,当然做起来也很简单。

image.png
  1. border

或许大家见得最多的就是用 border 来实现三角了,但是这种方式实现的三角宽高等往往都比较麻烦。

  1. clip-path

比较推荐用这种,宽高背景色等都好调控。开发起来不比切图做得快吗?

// 也就一行代码,对应三个点 (0, 0) (100%, 0) (0, 100%)
clip-path: polygon(0 0, 100% 0, 0 100%);
  1. svg

处理起来感觉会麻烦一点。

代码也比较简单就不列出来了,可以直接看码上掘金。

移动端的吸顶和吸底

移动端开发时,经常有下面这种需要顶部和底部固定的设计需求。此时除了需要注意吸顶吸底外,还需要注意内容不能被遮挡等问题;

image.png

code

当为固定到顶部时,我们可以借助 stickyfixed 来实现,这里先说 sticky ;比如上图的 navbar 此时它会定位固定到顶部并占据页面的高度。

<style>
  .navbar {
    position: sticky;
    top: 0px;
    height: 40px;
    background-color: skyblue;
  }
</style>
<div class="navbar">navbar</div>

当为固定到底部时,我们假如用 fixed 来实现,需要注意我们此时最好再给其添加一个高度相同的包裹盒子,主要用于占位防止内容被遮挡。

<style>
  .bottomBar {
    height: 60px;
  }
  .bottomBarFixed {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: 60px;
    background-color: green;
  }
</style>
<div class="bottomBar">
  <div class="bottomBarFixed">
    bottom
  </div>
</div>

而使用 fixed 定位时,需要注意以下问题,具体可看 MDN

比如我在码上掘金中的 demo ,就是采用了 transform 来使子元素的 fixed 定位基于该元素来定位的。

image.png

增大点击区域

比如有一个 close 的按钮,但是有时会发现比较难点击,我们可以增加正的 padding 和负的 margin 来实现,这样既不影响布局,也能把点击区域变为 30 * 30 的了。

.close {
  width: 20px;
  height: 20px;
  padding: 5px;
  margin: -5px;
}

图片高度保持为宽度的一半

使图片的高度保持为宽度的一个百分比,好像没有这样一个 css 的单位可以做到,只能借助 padding 来实现,从 MDN 中的描述可以看到,padding 的百分比是根据元素的宽度来的。

image.png

所以我们可以简单封装一个组件,当有这个需求的时候使用该组件即可。

import styles from './styles.less';
/** 将高度设置为宽度的百分比 */
export default ({heightPercent = 50, children, className, style}) => {
  return (
    <div className={className} style={style}>
      <div className={styles.percentHW} style={{paddingBottom: heightPercent + '%'}}>
        <div className={styles.content}>{children}</div>
      </div>
    </div>
  )
}
// styles.less
.percentHW {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 50%;

  .content {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
}

使用的时候,比如想要一个占据父元素60%宽度,高度为自身宽度的75%的图片可以这样使用。

<PercentHW heightPercent={75} style="width:60%">
  <img src='...' style="width:100%;height:100%;" />
</PercentHW>

取页面宽高的最小值

界面需求:弹窗需要占屏幕宽度或高度一半并取最小值;意思就是:缩小屏幕,怎样都要占据屏幕的一半并显示在屏幕中。并且再给一个最小值作为限制。

我们可以直接用 vmin 或者 vmax 单位来解决。

但是当宽高不一致,比如宽度的 50%,高度的 60% 就要用到 max min 两个 css 公式了。

<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .modal1 {
      width: max(300px, 50vmin);
      height: max(300px, 50vmin);
      background: skyblue;
    }
    .modal2 {
      width: max(300px, min(50vh, 50vw));
      height: max(300px, min(50vh, 50vw));
      background: green;
    }
  </style>
</head>
<body>
  <div class="modal1"></div>
  <div class="modal2"></div>
</body>
</html>