zoukankan      html  css  js  c++  java
  • css绘制特殊图形,meida查询,display inline-box间隙问题以及calc()函数

     本文同时发表于本人个人网站 www.yaoxiaowen.com

    距离上一篇文章已经一个月了,相比于写代码,发现写文章的确是更需要坚持的事情。言归正传,梳理一下这一个月来,在写ife任务时,有必要记录的问题吧。
    一,css画特殊图形。
    在网页中,需要一些特殊图形时。比如半圆形,三角形等,我们一般是让ui切图,但是实际上,利用css的边框 (border)属性,我们可以绘制一些有规律的图形。
    盒模型中元素有四个角,那么每个角就存在一个弧度的属性。
    先看代码:

    1 .half_circle{
    2 width: 50px;
    3 height: 50px;
    4 border-radius: 25px 0 0 0;
    5 border-color: blue olivedrab red black;
    6 border-width: 2px;
    7 }

    然后效果图如下:

    当然,这个图不是很直观,如果图形能标注出圆心半径,边框长度等信息,这样才能一目了然,不过比较抱歉,做这样一个标注图太麻烦了,所以我就不做了,但是我觉的,学过高中数学的人,应该都能看出来,左上角的那个圆弧到底是怎么画出来,总长度是50,左上角圆弧半径为25,从左上角沿着左边框和上边框分别移动25,找到两个点,然后做个圆弧正好与这两个点相切,其实算起来圆心正好是这个盒子的正中心。所以其实 border-radius 来画圆弧的基本原理就是,从某个角作为起点,沿着两条边框分别移动x个长度,然后依据这两个点,做两条垂直的线,然后交叉点就是圆心,x作为半径,然后就可以画圆弧了。

    然后再看下面两个图形的主要代码:

     1 .four_triangle_1{
     2 width: 0px;
     3 height: 0px;
     4 border-color:red green blue pink;
     5 border-width: 25px;
     6 }
     7 
     8 .four_triangle_2{
     9 width: 0px;
    10 height: 0px;
    11 border-color:red green blue pink;
    12 border-width: 20px 10px 30px 40px;
    13 }

    效果图。

    仔细琢磨一下,这两段代码,以及对应的图,明白其中的原理就可以了(主要是它交叉的点是怎么确定的)。然后就可以利用想象力来绘制各种图了,网上讲述css来绘制各种图形的文章太多了,但是万变不离其宗,理解了基本的原理,剩下的稍微一琢磨,就可以写了。

    另外,我们在android当中,绘制圆弧都是用 shape资源的corners属性,假设 使用rectangle,在一个控件左右绘制 半圆,可是有时候为什么会绘制的不是我们想要的半圆呢, 那是因为这个控件的高度是 wrap_content。我们只有知道了控件的确切高度,才能在两边绘制出完美的半圆。

    二, 命名规则 Hyphen ?underscore
    我之前在html当中命名id或者class时,使用的都是下划线(underscore),因为c,java之类的代码都是使用下划线的,所以也都习惯了,但是我在使用[attribute|=value] 选择器时, 这样写的[class|=col],发现根本没效果,测试了好几次,在w3c文档中,关于 [attribute|=value] 选择器 说明时,发现了这样一句话,
    该值必须是整个单词,比如 lang="en",或者后面跟着连字符,比如 lang="en-us"。

    然后才明白,我代码中 使用underscore,对于这个选择器没效果,必须使用 连字符 (Hyphen,有时候也称为中划线)。前端的坑真多啊,网上看了一下css命名规范,关于 Hyphen还是 underscore的问题,普遍还是建议的使用 Hyphen的好。(并且这个还牵扯到浏览器兼容问题)。

    三,media 媒体查询
    在android中,针对不同的手机尺寸分辨率,我们使用资源时可以进行区分,比如 drawable-xhpi, mdpi,layout_w360dp之类的,前端也需要面对不同的设备,以及各种尺寸,那么解决这个问题的方式就是 media。

    @media 查询,可以针对不同的媒体类型(比如 screen屏幕,speech 发声设备等),以及不同的屏幕尺寸,来设定不同的css样式,
    例如这样

    1 @media (min- 769px) {...}
    2 @media (max- 768px ) {...}

    这样我们就能依据屏幕尺寸是否大于768px,来使用不同的样式表。
    按照规范的定义,是这样的
    媒体查询包含一个可选的媒体类型和零或多个满足CSS3规范的表达式来描述媒体特征,这些表达式会被解析为true或false。
    它不仅包含min-width,device-height,orientation这些常用的媒体功能,而且还支持 and,not,only逻辑操作符,以及 使用逗号来分隔列表。这样它就可以组成各种复杂的查询条件。

    四:display:inline-box 存在多余的间隙

    前几天碰到了的这个问题,类似下面这样的,
    html代码:

    1 <div id="wrapper">
    2 <div class="box">1</div>
    3 <div class="box">2</div>
    4 <div class="box">3</div>
    5 <div class="box">4</div>
    6 </div>

    css代码:

     1 #wrapper{
     2 width: 400px;
     3 border: 1px blue dotted;
     4 }
     5 
     6 .box{
     7 width: 25%;
     8 display: inline-block;
     9 border: 1px red solid;
    10 }

    我的本意是,是希望每个box占据25%宽度,然后正好是一行。这样的需求还是比较常见的的。
    可是看看实际效果吧。
    效果图:

    我使用了display:inline-block,但是每个box后面,竟然产生了空隙。这让我非常纳闷,上网搜索,才明白其中的原理。
    某个大神的博客解释的比较清晰:

    HTML 中的换行符、空格符、制表符等产生了空白符,而这些归根结底都是字符,那么它们的大小都是受 font-size 来控制的,字体大小直接导致 inline 或者 inline-block 后元素之间空隙的大小,把 inline-block 元素间的空隙认为总是某个固定大小是错误的。

    也就说,我们使用inline-box,其实元素性质是inline,但是从一行内来说,其实还是box,所以产生了 white space,这是历史问题,因为西方文字本来就是使用空格来作为分割,而东方文字则不是如此。
    而根据其原理,解决方案其实也很简单,在父元素当中,添加 font-size: 0,不过这样解决也会带来一个麻烦,那就是每个里面的子元素,font-size都需要重新设定。

    五,box-sizing 以及 calc() 函数
    上一个问题的解决方式,来看看实际效果。
    效果图: 

    可以看到,中间的间隙的确为0了,但是四个box依旧没有充满一行,原因很简单,我们设置25%,但是根据标准盒子模型,这个width,height,仅仅包含内容区(content),不包括padding,border,更不包括margin。所以虽然我们设置了25%,但是每个box,加上border,他们的实际所占据的宽度是超过25%的,

    当然,不包括margin是合乎逻辑的,但是不包括 padding,border,其实不符合人类的思维习惯。所以在比较早的IE浏览器盒子模型中,(也叫做 IE怪异模式),它的盒子的width,就是包含 padding和border的。

    但是目前的w3c标准的width,height仅仅包含content区域,在有些场景下,会对我们写布局造成麻烦,就拿上面那个问题来说,宽度是百分比,而不是固定值啊,那怎么解决这个问题呢。css中有 calc() 函数,这是个计算函数,使用“+”、“-”、“*” 和 “/”四则运算,以及 百分比、px、em、rem等单位,可以进行混合计算,来动态的计算值。

    我把上面那个布局css中,设置来写

    1 .box{
    2 width: calc(25% - 2px);
    3 height: 50px;
    4 display: inline-block;
    5 border: 1px red solid;
    6 }

    效果图:

    这样就能达到我们想要的目的了。
    关于 calc()函数还要注意两点。
    1,四个运算符前后要有空格。
    2,实际上,calc()函数,并不只是计算 <length>,其他的像<frequency>, <angle>, <time>, <number>, <integer>它也是可以使用的。

    解决上述问题,除了 calc() 函数,还有没有其他办法呢?
    我们把css代码改成这样。

    1 .box{
    2 box-sizing: border-box;
    3 width: 25%;
    4 display: inline-block;
    5 border: 1px red solid;
    6 }

    测试一下,也能达到我们想要的效果,因为前面所说的,盒模型仅仅包含content,不直观,所以我们设置了 box-sizing: border-box,其实就相当于 IE怪异模式一样的计算方式,将padding,border也计算进盒子width当中。

    其他一点感悟:
    在写ife task1_7的时候,这个页面比较复杂,内容比较多。后来发现自己写的太乱了,有时候改动 某个区域的某个内容,会影响到其他区域的内容,这就说明,我写的代码耦合度太高了,解耦,应该是软件工程领域的银弹之一吧。今后在写html,css时需要注意这个问题,比如float的内容,要把父元素清除浮动;使用 absolute,relative 定位方式时,也要注意让他们的参考点,尽量是依据于直接父元素。

    -------
    作者: www.yaoxiaowen.com
    github: https://github.com/yaowen369

  • 相关阅读:
    每天学习一个设计模式(十二):创建型之单例模式
    每天学习一个设计模式(十一):创建型之原型模式
    每天学习一个设计模式(十):创建型之工厂方法模式
    每天学习一个设计模式(九):创建型之建造者模式
    数据库
    操作系统
    计算机网络
    Java 基础知识
    Linux基本操作
    git 基本操作
  • 原文地址:https://www.cnblogs.com/yaoxiaowen/p/6194703.html
Copyright © 2011-2022 走看看