开发中踩过的坑-Css

文中大部分内容来源于笔者JowayYoung的 文章。全部坑位的源码都按语言方向记录在笔者Github上,若有未记录的坑位可提PR让笔者合并,给个Star支持下咧!

CSS方向

自动适应布局

针对移动端,笔者通常会结合JS依据屏幕宽度设计图宽度的比例动态声明<html>font-size,以rem为长度单位声明所有节点的几何属性,这样就能做到大部分移动设备的页面兼容,兼容出入较大的地方再通过媒体查询做特别处理。

笔者通常将rem布局比例设置成1rem=100px,即在设计图上100px长度在CSS代码上使用1rem表示。

function AutoResponse(width = 750) {
    const target = document.documentElement;
    if (target.clientWidth >= 600) {
        target.style.fontSize = "80px";
    } else {
        target.style.fontSize = target.clientWidth / width * 100 + "px";
    }
}
AutoResponse();
window.addEventListener("resize", () => AutoResponse());

当然还可依据屏幕宽度设计图宽度的比例使用calc()动态声明<html>font-size,这样就能节省上述代码。不对,是完全代替上述代码。

html {
    font-size: calc(100vw / 7.5);
}

若以iPad Pro分辨率1024px为移动端和桌面端的断点,还可结合媒体查询做断点处理。1024px以下使用rem布局,否则不使用rem布局

@media screen and (max-width: 1024px) {
    html {
        font-size: calc(100vw / 7.5);
    }
}
自动适应背景

使用rem布局声明一个元素背景,多数情况会将background-size声明为cover。可能在设计图对应分辨率的移动设备下,背景会完美贴合显示,但换到其他分辨率的移动设备下就会出现左右空出1pxnpx的空隙。

此时将background-size声明为100% 100%,跟随widthheight的变化而变化。反正widthheight都是量好的实际尺寸。

.elem {
    width: 1rem;
    height: 1rem;
    background: url("pig.jpg") no-repeat center/100% 100%;
}
监听屏幕旋转

你还在使用JS判断横屏竖屏调整样式吗?那就真的Out了。

/* 横屏 */
@media all and (orientation: landscape) {
    /* 自定义样式 */
}
/* 竖屏 */
@media all and (orientation: portrait) {
    /* 自定义样式 */
}
支持弹性滚动

在苹果系统上非<body>元素的滚动操作可能会存在卡顿,但安卓系统不会出现该情况。通过声明overflow-scrolling:touch调用系统原生滚动事件优化弹性滚动,增加页面滚动的流畅度。

body {
    -webkit-overflow-scrolling: touch;
}
.elem {
    overflow: auto;
}
禁止滚动传播

桌面端浏览器不一样,移动端浏览器有一个奇怪行为。当页面包含多个滚动区域时,滚完一个区域后若还存在滚动动量则会将这些剩余动量传播到下一个滚动区域,造成该区域也滚动起来。这种行为称为滚动传播

若不想产生这种奇怪行为可直接禁止。

.elem {
    overscroll-behavior: contain;
}
禁止屏幕抖动

对于一些突然出现滚动条的页面,可能会产生左右抖动的不良影响。在一个滚动容器里,打开弹窗就隐藏滚动条,关闭弹窗就显示滚动条,来回操作会让屏幕抖动起来。提前声明滚动容器的padding-right为滚动条宽度,就能有效消除这个不良影响。

每个移动端浏览器的滚动条宽度都有可能不一致,甚至不一定占位置,通过以下方式能间接计算出滚动条的宽度。100vw为视窗宽度,100%为滚动容器内容宽度,相减就是滚动条宽度,妥妥的动态计算。

body {
    padding-right: calc(100vw - 100%);
}
禁止长按操作

有时不想用户长按元素呼出菜单进行点链接打电话发邮件保存图片扫描二维码等操作,声明touch-callout:none禁止用户长按操作。

有时不想用户复制粘贴盗文案,声明user-select:none禁止用户长按操作和选择复制。

* {
    /* pointer-events: none; */ /* 微信浏览器还需附加该属性才有效 */
    user-select: none; /* 禁止长按选择文字 */
    -webkit-touch-callout: none;
}

但声明user-select:none会让<input><textarea>无法输入文本,可对其声明user-select:auto排除在外。

input,
textarea {
    user-select: auto;
}
禁止页面字体调整
   // 设置网页字体为默认大小
WeixinJSBridge.invoke('setFontSizeCallback', {'fontSize': 0 });
          // 重写设置网页字体大小的事件
       WeixinJSBridge.on('menu:setfont', function() {
       WeixinJSBridge.invoke('setFontSizeCallback', {'fontSize': 0 });
});
 // 针对ios
  body {
    -webkit-text-size-adjust: 100% !important;
    text-size-adjust: 100% !important;
    -moz-text-size-adjust: 100% !important;
  }
禁止高亮显示

触摸元素会出现半透明灰色遮罩,不想要!

* {
    -webkit-tap-highlight-color: transparent;
}
禁止动画闪屏

在移动设备上添加动画,多数情况会出现闪屏,给动画元素的父元素构造一个3D环境就能让动画稳定运行了。

.elem {
    perspective: 1000;
    backface-visibility: hidden;
    transform-style: preserve-3d;
}
美化表单外观

表单元素样式太丑希望自定义,appearance:none来帮你。

button,
input,
select,
textarea {
    appearance: none;
    /* 自定义样式 */
}
美化滚动占位

滚动条样式太丑希望自定义,::-webkit-scrollbar-*来帮你。记住以下三个关键词就能随机应变了。

  • ::-webkit-scrollbar:滚动条整体部分
  • ::-webkit-scrollbar-track:滚动条轨道部分
  • ::-webkit-scrollbar-thumb:滚动条滑块部分
::-webkit-scrollbar {
    width: 6px;
    height: 6px;
    background-color: transparent;
}
::-webkit-scrollbar-track {
    background-color: transparent;
}
::-webkit-scrollbar-thumb {
    border-radius: 3px;
    background-image: linear-gradient(135deg, #09f, #3c9);
}
美化输入占位

输入框占位文本太丑,::-webkit-input-placeholder来帮你。

input::-webkit-input-placeholder {
    color: #66f;
}
对齐输入占位

有强迫症的同学总会觉得输入框文本位置整体偏上,感觉未居中心里就痒痒的。桌面端浏览器里声明line-height等于height就能解决,但移动端浏览器里还是未能解决,需将line-height声明为normal才行。

input {
    line-height: normal;
}
对齐下拉选项

下拉框选项默认向左对齐,是时候改改向右对齐了。

select option {
    direction: rtl;
}
修复点击无效

在苹果系统上有些情况下非可点击元素监听click事件可能会无效,针对该情况只需对不触发click事件的元素声明cursor:pointer就能解决。

.elem {
    cursor: pointer;
}
识别文本换行

多数情况会使用JS换行文本,那就真的Out了。若接口返回字段包含\n<br>,千万别替换掉,可声明white-space:pre-line交由浏览器做断行处理。

* {
    white-space: pre-line;
}
开启硬件加速

想动画更流畅吗,开启GPU硬件加速呗!

.elem {
    transform: translate3d(0, 0, 0);
    /* transform: translateZ(0); */
}
描绘像素边框

万年话题,如何描绘一像素边框
新项目最好使用的是设置viewport的scale值,这个方法兼容性好,后期写起来方便。老项目的话,改起来可能比较多,用的比较多的方法就是伪元素+transform的方法。 其他的背景图片,阴影的方法毕竟还是不太灵活,而且兼容性不好。
1、设置viewport的scale值

<html>
  <head>
      <title>1px question</title>
      <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
      <meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">        
      <style>
          html {
              font-size: 1px;
          }            
          * {
              padding: 0;
              margin: 0;
          }
          .top_b {
              border-bottom: 1px solid #E5E5E5;
          }

          .a,.b {
                      box-sizing: border-box;
              margin-top: 1rem;
              padding: 1rem;                
              font-size: 1.4rem;
          }

          .a {
              width: 100%;
          }

          .b {
              background: #f5f5f5;
              width: 100%;
          }
      </style>
      <script>
          var viewport = document.querySelector("meta[name=viewport]");
          //下面是根据设备像素设置viewport
          if (window.devicePixelRatio == 1) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
          }
          if (window.devicePixelRatio == 2) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
          }
          if (window.devicePixelRatio == 3) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
          }
          var docEl = document.documentElement;
          var fontsize = 32* (docEl.clientWidth / 750) + 'px';
          docEl.style.fontSize = fontsize;
      </script>
  </head>
  <body>
      <div class="top_b a">下面的底边宽度是虚拟1像素的</div>
      <div class="b">上面的边框宽度是虚拟1像素的</div>
  </body>
</html>


2、利用 css 的 伪元素::after + transfrom 进行缩放

1 条border
.setOnePx{
  position: relative;
  &::after{
    position: absolute;
    content: '';
    background-color: #e5e5e5;
    display: block;
    width: 100%;
    height: 1px; /*no*/
    transform: scale(1, 0.5);
    top: 0;
    left: 0;
  }
}
4 条border
.setBorderAll{
     position: relative;
       &:after{
           content:" ";
           position:absolute;
           top: 0;
           left: 0;
           width: 200%;
           height: 200%;
           transform: scale(0.5);
           transform-origin: left top;
           box-sizing: border-box;
           border: 1px solid #E5E5E5;
           border-radius: 4px;
      }
    }
控制溢出文本

万年话题,如何控制文本做单行溢出多行溢出

.elem {
    width: 400px;
    line-height: 30px;
    font-size: 20px;
    &.sl-ellipsis {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    &.ml-ellipsis {
        display: -webkit-box;
        overflow: hidden;
        text-overflow: ellipsis;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;
    }
}
在移动端中使用line-height=height实现文字垂直居中时,在安卓手机会发现文字偏上!
1、利用flex布局中的垂直居中属性实现垂直居中
父元素设置
   display:flex;
   height:1rem;
   align-items: center;
子元素
   transform: scale(0.5);
   transform-origin: left center;
2、不直接设置line-height=height
   line-height:normal; 
   padding:10px 0;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容