本文摘自这一年来自己在工作中经历的几个比较好的CSS问题(不一定复杂,但个人觉得都挺值得一说),同时也准备了2个JS问题
一、CSS篇
1.1 元素默认蓝色边框
input
标签元素(如button
、text
、areatext
)的一些事件(如click
、focus
等),在很多浏览器下默认会有蓝色边框出现,如把一个普通button
的background
和border
都设置为none
后,触发点击后样式如下:
这是由元素默认的轮廓线产生的,这是浏览器的一种防护机制,起到突出元素的作用,把它干掉就行了,方法如下:
outline:none/medium; //方法2: outline-width:0//方法1:
1.2 背景透明,文字不透明
我们通常是使用opacity
来做背景的透明化处理,该属性被所有浏览器支持,可以大胆使用,透明度从0.0(完全透明)到1.0(完全不透明),但该方法会使其所有子元素都透明,此时若只想让背景透明,其他不透明,则可以使用rgba
处理背景:
background-color:rgba(red,green,blue,alpha)
其中这个alpha
即设置透明度,取值在0~1之间。该方法除IE9以下不可用外,其他浏览器均可用,看一下效果:
同理,我们也可以用这个方法把整个背景做透明了,即多写一个div
作为modal层做透明处理,可以明显看到上面文字并未透明:
上述种效果代码如下:
<section> <divclass="item-pic"> <headerclass="header1"> <h4>你会微笑放手,说好不哭让我出新专辑h4> header> div> <divclass="item-pic"> <headerclass="header2"> <h4>你会微笑放手,说好不哭让我出新专辑h4> header> div> <divclass="item-pic"> <divclass="handle-opacity"> <header> <h4>你会微笑放手,说好不哭让我出新专辑h4> header> div> div> section> <stylelang="less"> .header1{ opacity:.6; } .header2{ background-color:rgba(0,0,0,0.45); } .handle-opacity{ position:absolute; width:100%; height:100%; background-color:rgba(255,255,255,0.45); header{ background-color:rgba(0,0,0,0.45); } }style>//html
1.3 div内置img元素,底部总有间距
用一个div
包裹一个img
,会出现img
不能完全覆盖div
空间,总会在底边留下一点空隙。
这种现象产生的原因是img
是行内元素,浏览器为下行字符(如:g、y、j、p、q)留下的一些空间,这些字符是会比其他字符多占据底部一些空间(具体以当前字体大小有关),这种规则会影响行内元素img
标签(其默认垂直对齐方式是依照基线来的,即vertical-align: baseline
),同样行内元素都会和外部元素留这么一丢丢安全距离。上图右侧就是加了文字的效果,这样就更说明一切了。
现在我们知道这种现象主要是由于下行字符串保护机制和img
是行内元素这两个因素导致的,那解决方案就从这两处入手,整理如下:
div
设置font-size: 0
或line-height: 0
,进而行高为0;
img
设置vertical-align: top 或者 middle/
,使其不再以默认基线为对齐方式;
img
设置display:block
,使其变成块级元素。
综上,个人认为方法3是最好用的,方法1不推荐使用。
1.4 元素自动填充上背景色
该现场多在表单输入等场景上会出现,初次看到确实很怪异,效果如图:
即当浏览器(chrome)给输入框自动填充内容后,也会自动给输入框带上背景(黄或灰蓝),该问题是由于chrome会默认给自动填充的input
、select
、textarea
等加上:-webkit-autofill
私有伪属性造成的,比较好的解决方案就是做样式覆盖,代码如下:
box-shadow:000px1000pxwhiteinset!important; } select:-webkit-autofill{ box-shadow:000px1000pxwhiteinset!important; } textarea:-webkit-autofill{ box-shadow:000px1000pxwhiteinset!important; }input:-webkit-autofill{
比较渣的办法是设置禁止自动填充,但还是别那样做了…
1.5 transform 基数值导致字体模糊
transform作为CSS3最为自豪的属性,已经成为了当前前端开发中不可或缺的方法,但它有个渲染的问题,即当元素设置有transform,且其值为基数或小数,同事其整体高度也有基数时,其内部文字会变模糊,如图:
上图上模糊状态下的,下图是修正过的,具体原因经查可能是因为transform
变换会在浏览器上单独创建一个绘画层并重新进行渲染,在此渲染过程中也处理了周围的文字,如果高度为奇数的文字可能会存在半个像素的计算量,浏览器对这半个像素会进行优化渲染,所以边缘会出现模糊的情况。解决方案即:
不要给transform属性值设置奇数和小数值;
调整整体元素高度不要为基数。
1.6 :last-child 和 :last-of-type
作为CSS常用伪类选择器,:last-child
经常会被用到,但有时遇到极端情况,它会意外失效,让人摸不着头脑,例子如下:
3个img
标签包裹在card
中,当前需求是使最后一张图的边框呈粉色,代码如下:
<divclass="card"> <imgv-for="(item,i)inpics":key="i":src="item" /> div> //css <stylelang="less"> .card{ >img{ width:150px; margin-right:10px; &:last-child{ border:5pxsolidpink; } } }style>//html
同理用:last-of-type
也能实现:
>img{ width:150px; margin-right:10px; &:last-of-type{ border:5pxsolidpink; } } }.card{
效果如下:
现在要往img
后加一个span
,发现:last-child
已失效:
<divclass="card"> <imgv-for="(item,i)inpics":key="i":src="item" /> <span>nextis...span> div> //css <stylelang="less"> .card{ >img{ width:150px; margin-right:10px; &:last-child{ border:5pxsolidpink; } } }style>//html
而此时:last-of-type
依然没问题:
现在得出结论:
:last-child
选取一群兄弟元素中的最后一个元素,且最后的这个元素必须是所声明的指定元素(注意2个条件);
:last-of-type
选取一群兄弟元素中的最后一个指定类型的元素。
可知,:last-of-type
更严谨一些,不容易产生意外bug,我更推荐使用它。同理适用于:nth-last-child(n)
和:nth-last-of-type(n)
二、DOM篇
这部分我会叙述一些DOM操作遇到的一些容易被忽视的问题。
2.1 IOS日期显示问题
经常做H5移动端开发的朋友我想对这个问题肯定不陌生,那就是在部门IOS版本(IOS5及以下)中,对以“-”间隔的字符串时间格式的解析是不成功的,比如我们写了这么一个鸡肋时间格式适配器:
if(!date)returnnull; date=newDate(date); letY=date.getFullYear(); letM=(date.getMonth()>=0&&date.getMonth()<=8)?`0${date.getMonth()+1}`:`${date.getMonth()+1}`; letD=(date.getDate()>=0&&date.getDate()<=9)?`0${date.getDate()}`:`${date.getDate()}`; return`Y-M-D` }functionDateFormat(date){
此时如果在IOS5及以下版本的iphone下,传入 "-12-31"就会呈现出NaN-NaN-NaN
,而其他IOS版本及安卓系统都是没问题的。
针对上述问题,要做兼容适配,即把以"-"间隔的事件字符串替换成以"/"即可,同样是这个适配器,添加一段代码:
if(!date)returnnull; if(typeofdate==='string'&&date.indexOf('T')!=-1&&date.indexOf('+')!=-1){ date=date.replace(/-/g,'/').replace('T','').substring(0,date.indexOf('.')) } date=newDate(date); letY=date.getFullYear(); letM=(date.getMonth()>=0&&date.getMonth()<=8)?`0${date.getMonth()+1}`:`${date.getMonth()+1}`; letD=(date.getDate()>=0&&date.getDate()<=9)?`0${date.getDate()}`:`${date.getDate()}`; return`Y-M-D` }functionDateFormat(date){
2.2 ENTER键使当前页刷新
这个真的很诡异的问题,当在一个表单中执行了ENTER键提交后,如果是打开新页面显示提交结果,则会发现当前表单页面也跟着刷新了,这种体验当然是很糟糕的。经查证,该问题的产生条件为:Form
中只有一个input
时,此时执行ENTER键会自动提交表单并刷新页面。解决方案也很粗暴,直接在input输入框附近写一个隐藏标签,这样就有2个input了,即避免了产生默认刷新的bug,实例如下:
<inputtype="text"v-model.trim="searchText"placeholder="搜索您感兴趣的内容" @keyup.enter="goSearch" /> <inputid="hidden"type="text"style="display:none" @keyup.enter="goSearch" /> form><form>
❤️爱心三连击
如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:
点个「在看」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)
欢迎关注我的5000star文章合集/ljianshu/Blog,希望可以带给你点启发!
如果想进前端交流群一起探讨技术,请在后台回复「1」
亲,点这涨工资