做dropselect的单选样式记录 | 青训营笔记

39 阅读2分钟

样式拆解

dropselect可分为两个div容器, 其中一个.dropinput包括

  • input:会回显所选文字(单选)或存放所选选项的容器(多选)
  • .clearable 全部清空,以及
  • 一个可以改变状态的下拉(上拉)箭头, 另一个div(也即.optionlist)中存放各个optionlist-item

样式中需要解决的问题有:

  • 整体disabled样式如何继承

  • input

    • 怎样将光标隐藏
    • 怎样添加下拉空心箭头
    • clearable的叉怎么画
  • div-scroll

    • 怎样把scroll的滚动条隐藏
    • 怎样做出阴影,和高档的无边框
  • optionlist-item

    • 完成状态的✅怎么画
    • 鼠标形式如何改变
    • 选项,描述以及表示已选状态的✅应当如何排列

问题详解

整体disabled样式如何继承

首先要将鼠标样式改为禁用 cursor: not-allowed !important; 其次,在dropinput中实现 cursor:inherit border:inherit 该部分代码如下:

scss
复制代码
.disabled {
    cursor: not-allowed !important;
    .dropinput {
      input,
      &--input-box {
        color: $--font-color-disabled;
        background-color: rgba($--color-disabled, 0.4);
        border: 1px solid #e9e9e9 !important;
      }
    }
  }

dropinput

怎样将光标隐藏

使用该代码将光标颜色改为透明, caret-color:transparent; 而当需要光标时,再将其改为字体颜色

scss
复制代码
.my-dropselect {
    &-multiple-search {
      input {
        caret-color: $--font-color-main;
      }
    }
 }

怎样将原有的focus-visible自带的焦点框去除?

这个问题困扰了我很长时间,不论怎样在浏览器中debug我都看不到这个焦点框到底是个什么鬼东西,终于,我想起之前的一个坑:它有没有可能是outline?

我去找了iview的源码看了一下,嗯,它就是outline,所以使用outline:none;就可以完美达到目的了,喜极而泣,喜大普奔,内牛满面...

怎样添加下拉空心箭头

使用css可以利用border画出下拉箭头和上拉箭头

scss
复制代码
        &-down {
            width: 3px;
            height: 3px;
            position: absolute;
            left: 0;
            top: 0;
            z-index: 2; /*兼容ie8-*/
            border: 1px solid #b0b0b0;
            border-width: 1px 1px 0 0;
            transform: rotate(135deg);
            // margin-bottom:10px;
          }
          &-up {
            width: 3px;
            height: 3px;
            position: absolute;
            left: 0;
            bottom: 0;
            z-index: 2; /*兼容ie8-*/
            border: 1px solid #b0b0b0;
            border-width: 1px 0 0 1px;
            transform: rotate(45deg);
          }
        }

更改width和height可改变大小

clearable的叉怎么画

scss
复制代码
    &--clearable {
          &::before,
          &::after {
            position: absolute;
            content: ' ';
            background-color: #b0b0b0;
            left: 12px;
            width: 1px;
            height: 12px;
          }
          &::before {
            transform: rotate(45deg);
          }

          &::after {
            transform: rotate(-45deg);
          }

都是用scss写的,其实是class,相当于

css
复制代码
        .clearable {
          ::before,
          ::after {
            position: absolute;
            content: ' ';
            background-color: #b0b0b0;
            left: 12px;
            width: 1px;
            height: 12px;
          }
          ::before {
            transform: rotate(45deg);
          }

          ::after {
            transform: rotate(-45deg);
          }

div-scroll

怎样把scroll的滚动条隐藏并保留功能

做成scroll的形式相信大家都知道,就是 overflow-y: auto;

那么怎样把scroll的滚动条隐藏呢?

有的答案说 overflow-y: hidden;但这样就没办法实现滚动功能了

如何将滚动条隐藏并保留功能:

scss
复制代码
.--optionlist {
    /* 隐藏 Chrome、Safari 和 Opera 的滚动条 */
    &::-webkit-scrollbar {
      display: none;
    }
    /* 以上的对IE不兼容,所以需要再添加下面两行代码 */
    -ms-overflow-style: none; /* IE and Edge */
    scrollbar-width: none; /* Firefox */
}

将滚动变得顺滑

使用scroll-behavior: smooth;

怎样做出阴影,和高档的无边框

阴影可以使用 box-shadow : 0 0 5px 4px #yourcolor;

颜色可以选择主题颜色叠加白色/黑色(视主题不同)透明度20%左右的颜色

无边框,border:none; 呜呜呜这个做出来真的高档,谁用谁知道,要不是设计稿要求,我都想让input也无边框,真的老好看了,你看就是这样

image.png

嗯,所以高档还是要box-shadow一起配合才行

optionlist-item

已选状态的✅怎么画

画✅又可以使用html自带字符&#10003&#10004,css里是\2173这些可以作为字体进行编辑;

又可以用css原生画出来

scss
复制代码
&-selected {
    width: 3px;
    height: 6px;
    border-right: 2px solid $--font-color-disabled;
    border-bottom: 2px solid $--font-color-disabled;
    transform: rotate(40deg);
    color: $--font-color-disabled;
    }

鼠标形式如何改变

cursor:pointer

选项,描述以及表示已选状态的✅应当如何排列

呜呜呜这个花了我真的好长时间

image.png 像这样选项和已选状态✅在一行显示,两端对齐的很好解决,只需要在父容器optionlist-item中设定 justify-content: space-between;即可

但是如果加上描述,那就是惨兮兮的这个样子

image.png

怎样让它符合设计文档要求,也就是呈现出下面这个符合要求的样子呢?

image.png

感谢chatgpt,它告诉我了一个奇技淫巧

scss
复制代码
.optionlist-item {
      display: flex;
      flex-direction: column;
      align-items: left;
      &--selected {
          margin-left: auto;
      }
}

当然如果只是这样的话,就会出现这种效果

image.png

我怎样让选择时和未选时的描述与选项标题空隙保持一致呢?这个空隙是什么?

我实验了一下 .optionlist-item{gap:10px;}

发现确实空隙变大了,但是将其设置为0,仍然没有办法紧贴在一起,还是会出现上图的效果。

苦思冥想,我觉得应该让span标签在以列排列的弹性布局中叠起来,怎么叠起来呢?

使用更改margin-topmargin-bottom就可以叠起来了,再次喜大普奔TAT

代码如下:

scss
复制代码
.optionlist-item {
      display: flex;
      flex-direction: column;
      align-items: left;
      gap:0;
      &--selected {
          margin-left: auto;
          margin-top: -4px;
          margin-bottom: -4px;
      }
      &-description {
            margin-top: -4px;
        }