position:relative 的妙用

342 阅读2分钟

前一阵子刚做完一个需求,碰到一个从没做过的样式,当时第一眼看到时先愣了一下,主要在于顶部的一个背景块的下边框是用下面元素上边框来实现的。

脑子里大致有一点实现的思路,首先是上下的兄弟元素,然后给上面的元素设置上左右边框,下面的元素只设置上边框。但是这样出来的效果有点问题,就是下面元素设置的上边框长度不够,和 ui 上有出入,如图所示:

可以看到下面元素的设置了圆角边框后,再设置上边框颜色,其两边延伸的长度有限,和 ui 对比感觉还是少了点长度,如果再给上面的元素设置四周边框,并隐藏掉下面框,就会产生第二个问题:

左右两边存在缺角,这个缺角自然是因为下面元素的圆角造成的空缺,看到这种情况,第一反应自然是将下面的元素或者上面的元素通过绝对定位移动下,来使得他们重叠来抵消这部分空白。

但是我并不想使用绝对定位,因为这就要改 dom 的结构了,而且需要计算偏移的距离,比较麻烦,不知道怎么的我就想到了初学前端时的 positive的几个属性,绝对定位absolute是将当前 dom 元素脱离现在的文档流,相当于生成了一个新的图层,浮在了原文档流的上面,而relative则是不使得当前 dom 元素脱离文档流但却可以通过设置偏移改变其在文档流的位置。

也就是说原则上我只需要对下面的元素设置position:relative属性,并设置top为负的值,使得其往上偏移一点就可以了,使用后完美的达到了 UI 所需的效果:

原来我担心的下面的元素上边框长度不够的问题也在上移的过程中和上面元素的左右边框完美融合了,达到了理想的效果,最后附上完整的实现代码:

<template>
  <scroll-view class="flex-1" scroll-y>
    <view v-for="i in list" class="m">
      <view class="card-title flex-center">
        <image
          src="../../static/index/ques.png"
          class="w-20 h-20 mr-10"
          />
        <div>{{ i.name }}</div>
      </view>
      <view class="rounded bg-white p-5 relative" style="border-top: 1px solid #CACDFC; top: -5px;">
        <view v-for="j in i.list" class="rounded bg-f8 p mx-10 my-10 hover" @click="toDetail(j)">
          <div class="text-14 font-medium">{{ j.title }}</div>
          <div class="text-999 text-13 mt">日期:{{ j.createTime }}</div>
        </view>
      </view>
    </view>
  </scroll-view>
</template>
<style lang="scss">
.card-title{
  padding: 15px;
  background: #eeefff;
  border: 1px solid #CACDFC;
  border-bottom: none;
  border-radius: 12px 12px 0 0;
  font-weight: 500;
}
</style>