被遗忘的CSS和HTML(一)

color

也许你天天都在写color: #xxx,但是,你是否还记得什么是color?你是不是第一反应:字体颜色。

如果是,很遗憾,color就是被你遗忘的CSS。

如果是,你是否曾想过,字体大小叫font-size,字体粗细叫font-weight,字体类型叫font-family……为何,偏偏字体颜色是color,而不是font-color呢?以及,font缩写里为什么没有color的位置?

一切只因color,不是字体颜色。

color,更好的叫法应该是foreground-color,前景色。前景色这个词,在CSS里,应该很陌生,基本不会被人叫出来,而与之相对的是background-color,背景色。是的,这才是真正的color,与background-color相对的颜色。

问题就是,什么是前景色?不在背景上的颜色都是前景色。。。呵呵,有点放屁的感觉。

另外一个问题,哪些颜色是前景色?除了background-color,其他都是前景色。。。神经病啊~~

好吧,除了background-color,有如下color是前景色:

  1. 字体颜色:并没有font-color,只能通过color设定
  2. border-color:边框颜色
  3. outline-color:轮廓颜色
  4. column-rule-color:列间边框颜色
  5. text-decoration-color:下划线颜色
  6. text-shadow:text-shadow中的颜色
  7. box-shadow:box-shadow中的颜色

除了1以外,这些前景色和color是什么关系呢?聪明的你,一定猜得到。是的,默认值。

在没有设定以上2~7的color值时,浏览器对这些颜色的计算值是color。

举个粟子:

http://component.sankuai.com/component/@mtfe/atom-button#~simpl

两组按钮

简单看下其中一个填充色按钮和描边按钮的CSS代码:

Types组按钮样式

Line Shape组按钮样式

对于这个组件,比如,我想要添加蓝色填充按钮和蓝色描边按钮,那我需要为填充按钮添加border-color和background-color,为描边按钮添加color和border-color,是否有更简单的方式呢?答案是有。使用color就可以做到了。

<style>
  .btn {
    font-size: 20px;
    padding: 1em 2em;
    border-radius: 5px;
    position: relative;
    background-color: transparent;
    outline: 0;
    overflow: hidden;
    border: 2px solid;
  }
  .btn.fill::after{
    content: '';
    box-sizing: border-box;
    border-width: 2em;
    border-style: solid;
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 0;
  }
  .btn.fill span {
    color: white;
  position: relative;
  z-index: 1;
  }
  button.orange {
    color: #f80;
  }
  .btn.green {
    color: #06c1ae;
  }
  .btn.red {
    color: #ec5300;
  }
  .btn.grey {
    color: #d2d2d2;
  }
</style>
<button class="btn orange fill"><span>按钮0</span></button>
<button class="btn orange stroke">按钮1</button>
<button class="btn green fill"><span>按钮2</span></button>
<button class="btn green stroke">按钮3</button>
<button class="btn red fill"><span>按钮4</span></button>
<button class="btn red stroke">按钮5</button>
<button class="btn grey fill"><span>按钮6</span></button>
<button class="btn grey stroke">按钮7</button>

border-style

使用border实现各类三角形,应该是很多人都知道的小技巧。那使用border实现圆形、实现三横线【照片4】,在Boostrap里做响应式menu时可以看到)等呢?

简单的一个圆形应用:

使用border-style实现波浪

我们看到,上下内容之间,是有一条波浪分隔的,那如何实现这条波浪呢?

<style>
  .up, .down {
    height: 100px;
    width: 100%;
    position: relative;
    padding:2em;
    box-sizing: border-box;
  }
  .up {
    background-color: #fecd0f;
    color: #666;
  }
  .up::after {
    content: '';
    position: absolute;
    bottom: -5px;
    left: 0;
    width: 100%;
    border-bottom: 8px dotted white;
  }
</style>
<div style="box-shadow:0 0 4px;width:250px;">
  <div class="up">
    上面的内容在这里
  </div>
  <div class="down">
    下面的内容在这里
  </div>
</div>

三横线


使用border-style实现三横线

的实现:

<style>
  .menu {
    display: inline-block;
    border-width: 9px;
    border-bottom-style: double;
    border-top: 3px solid;
    border-color: #fecd0f;
    width: 2em;
    height: 3px;
  }
</style>
<i class="menu"></i>

其他实现:


选中radio
<style>
  .radio {
    display: inline-block;
    border: 9px double #fecd0f;
    border-radius: 50%;
  }
</style>
<i class="radio"></i>

锚点和:target

锚点,可以快速将页面滚动至特定位置;:target选择器可以选中当前锚点。

锚点定位是一种被忽略得很彻底的定位技术,毕竟现在JS大行其道,前端总会有的没的都写几行JS搞定,甚是方便。并不是说哪种好哪种坏,都没有错,“黑猫白猫,能抓到老鼠就是好猫”。

考虑一种场景,在手机端,使用Hybrid技术或Web页面,如下图:

蒙版场景

当点击底部价格旁边的“明细”时,会出现如下蒙层

蒙版

现在,有一个操作需要考虑:返回。返回有两种方式:1. 点击左上角的自定义的返回按钮;2. 安卓用户点击手机自带的返回按钮。

当用户返回时,最好的操作是仅关闭蒙层,显示先前的页面。要实现这样的功能,方式1会相对简单;方式2,对于Hybrid里通常会在JSBridge里直接添加一个“返回”的监测功能,由Bridge去处理。

那问题是,真的需要这样吗?或者,如果它仅仅是Web页面,没有Hybrid的JSBridge怎么办?

至少目前,JS没办法去监听系统级返回,而这时候,锚点和:target就可以很好的替我们实现这个功能了。

<style>
  #click-target {
    display: inline-block;
    line-height: 3em;
    width: 7em;
    text-align: center;
    background-color: #f80;
    color: white;
    outline: none;
  }
  .my-target {
    position: fixed;
    z-index: 10000;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, .8);
    color: white;
    transform: translateY(100%);
 
  }
  .my-target.width-animate-out {
    transition: transform .2s ease-in-out;
  }
  .my-target:target {
 
    transform: translateY(0);
  }
</style>
<a href="#my-target" id="click-target">点一个</a>
<div id="my-target" class="my-target width-animate-out">哎呀,我弹出来了~~</div>

除了target具有“定位”功能外,input也是一个很好的定位Hack。有兴趣的可以自行研究。

锚点当然有其问题,每个技术都有其适用场景。比如,锚点会产生历史记录,这是一个最需要考虑的问题了。其他的,你们用了就会发现,这里不细说。

定时隐藏

通常,我们在处理页面或某个操作的错误提醒时,都习惯性使用toast模式,会定个时,在特定时间后让toast消失。对于前端来讲,这是非常熟悉的应用场景,我们的代码也经常是这样的:

setTiimeout(function() {
​  // 关闭喽
​  thatElement.style.display = 'none'
}, 1000)

抛开你已经会的setTiimeout,是否可以想想,还有什么方法吗?在CSS里,同样存在着定时功能,只是我们通常会忽略,或者说我们没有换个角度看。与时间有关,CSS里是动画。

是的,只是一个显隐,一个transition或animation就可以做到了,只需要我们定义transition-delay或者animation-delay,这就是一个被我们忽略的定时。实现及代码如下:

<style>
  .toast-container {
    position: relative;
    border: 2px dashed #f33;
    border-radius: .5em;
    padding: 2.5em;
    overflow: hidden;
  }
  .toast {
    position: absolute;
    top: -100%;
    left: 0;
    width: 100%;
    text-align: center;
    background: rgba(0, 0, 0, .7);
    color: white;  
    pointer-events: none;
    transition-property: top, opacity, transform;
    transition-duration: .5s, 2s, .2s;
    transition-delay: 0s, 1.5s, 3.5s;
    transition-timing-function: ease-in-out;
    transform: translateY(0);
    opacity: 1;
    padding: .5em 0;
  }
  #toast-trigger:checked ~ .toast {
    top: 0;
    opacity: 0;
    transform: translateY(-100%);
  }
</style>
<div class="toast-container">
  <input type="checkbox" id="toast-trigger" />
  <label for="toast-trigger">Show me toast</label>
  <i class="toast">哈哈哈哈,我就是那个toast啊</i>
</div>

例子中使用的是transition,同样的,你也可以使用animation去实现其他的定时任务。对于setInterval任何,我们只需要使用animation-iteration-count: infinite;即可。当然,太过复杂的定时任务,还是使用setTimeout/setInterval或requestAnimationFrame会更好。还是那句话:各种技术都有其适用场景。

宽高等比缩放

在处理图片时,我们有时候需要保证图片的宽度和高度保持一定的比例R,当屏幕的宽度或者高度变化时,我们的图片能够按比例R进行缩放。比方说:

初始时,屏幕width = 1000px,图片width = 屏幕width * 0.5 = 500px,height = 图片width * 0.6 = 300px

缩放屏幕width = 800px,则按上述比例,需要图片:width = 400px,height = 240px

比较笨的方法是:监听resize => 获取屏幕宽度 => 计算出图片宽高 => style赋值

这样的方式,不仅笨,而且,很耗性能。不管是哪一步,都是相当耗性能的(性能相关:浏览器渲染机制基础

当一个功能有如下情况:

  1. 使用JS太耗性能
  2. 涉及太多样式计算

时,你需要考虑是否可以使用CSS解决

放在这个场景上,既耗性能,又有太多计算,而且还是尺寸计算。监听resize,调用回调,原本就是一个前端大忌。为此,可以想想,CSS能否解决呢?答案是肯定的。

这就涉及到另一个被我们遗忘的CSS了:paddingmargin的百分比取值。

paddingmargin是个很有意思的东西,而在取值上,它们却给了我们一个不错的玩法:(由于本例子中,我们只使用padding,以下只说padding

当padding取值为百分比时,其计算值相对于包含块的宽度

这是个很有趣的计算规则,意味着,我们的宽高等比缩放就可以完美得解决了。

首先,我们需要一个元素来定义宽高比:

<div style="width: 50%; padding-top: 30%; height: 0;"></div>

这里,我们将div的width定义为50%,这就是屏幕width * 0.5;然后,padding-top: 30%,这就是屏幕width * 0.3,正好等于图片width * 0.6。这就是我们要的比例。而height: 0只是为了保证不被污染。

其次,我们需要一个子元素,让它的宽高为100%,用于存放真正的content。

<div style="width: 50%; padding-top: 30%; height:0;">
  <div style="width:100%;height:100%;">这里是Content</div>
</div>

很显然,这样我们只能得到如下的效果:(以下内容比例做了调整并加了外框,请不要在意)

等比盒

我们需要调整一下样式,保证子元素能确切获取父元素的宽高,由于我们的父元素没有height,只有盒高,要获得其盒高,就需要用到position。因此:

<div style="outline:1px dashed #f88;position:relative;width: 30%; padding-top: 150%; height:0;">
  <div style="outline: 1px solid green;position:absolute;top:0;left:0;width:100%;height:100%;">这里是Content</div>
</div> 

是的,我们给父元素添加position: relative,然后让子元素相对于父元素绝对定位,这样子元素就能切实获取父元素的盒高了。处理后, 我们就得到了如下效果:

等比盒最终效果

这样,我们的宽高等比盒就OK了。

之前有人问:怎么让padding的百分比按高度来计算。这就又涉及到一个几乎不会被人使用的属性了:writing-mode,这里就不再多说了。

禁用点击

禁用点击,指的是对用户的点击,不予响应。在写React时,我们经常需要通过某个条件去判断是否处理回调函数。比如:

<Demo onClick={evt => this.state.disabled ? null : this.demoClicked(evt)} />

这种通过码方式来判断,应该是很常见的方式,这样的禁用方式,我喜欢称之为伪禁用

实际上,我们可以用更简便的方式来实现禁用,而且是真禁用。HTML里,禁用概念在表单元素里是十分常见的,我们会禁用一个checkbox,会禁用一个button,但是,我们又往往忘了,禁用button也就禁用了click事件的响应,这是一种真禁用

对于上述的例子,我们可以更简单的:

<button onClick={evt => this.demoClicked(evt)} disabled={this.state.disabled} />

前者我们关心的是点击时候是否禁用了;而后者我们关心的是点击是否禁用。从真正意义上讲,后者才是合理的,所谓的职责分离事件回调不应该去处理状态,它只需要去响应状态,状态的维护交给组件处理

表单相关

表单有很多的小巧运用,本文的篇幅已经有点长了,就先这样,下次续。

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

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,722评论 1 92
  • FreeCodeCamp - HTML5 and CSS 发现原来在另外一台电脑学 FreeCodeCamp 的时...
    付林恒阅读 9,325评论 2 17
  • 转载请声明 原文链接地址 关注公众号获取更多资讯 第一部分 HTML 第一章 职业规划和前景 职业方向规划定位...
    程序员poetry阅读 16,508评论 32 459
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    wzhiq896阅读 1,727评论 0 2
  • •前端面试题汇总 一、HTML和CSS 21 你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? ...
    Simon_s阅读 2,219评论 0 8