suger258956 suger258956
首页
  • 基础学习

    • HTML
    • CSS
    • JavaScript
  • 进阶学习

    • ES6
    • TypeScript
GitHub (opens new window)
首页
  • 基础学习

    • HTML
    • CSS
    • JavaScript
  • 进阶学习

    • ES6
    • TypeScript
GitHub (opens new window)
  • 基础学习

    • HTML

    • CSS

      • CSS基础
      • 页面布局
      • 定位与浮动
      • 场景应用
        • 1. 实现一个三角形
        • 2. 实现一个扇形
        • 3. 实现一个圆和半圆
        • 4. 实现一个宽高自适应的正方形
        • 5. 画一个梯形
        • 6. 画一条0.5px的线
        • 7. 设置小于12px的字体
        • 8. 如何解决 1px 问题?
    • JavaScript

  • 进阶学习

  • web前端
  • 基础学习
  • CSS
sugar258596
2023-08-01
目录

场景应用

# 场景应用

# 1. 实现一个三角形

CSS绘制三角形主要用到的是border属性,也就是边框。

平时在给盒子设置边框时,往往都设置很窄,就可能误以为边框是由矩形组成的。实际上,border属性是右三角形组成的,下面看一个例子:

    div{
        width:0;
        height:0;
        border:100px solid;
        border-color:orange blue red green;
    }

将元素的长宽都设置为0,显示出来的效果是这样的:

所以可以根据border这个特性来绘制三角形:

(1)三角1

    div{
        width:0;
        height:0;
        border-top:50px solid red;
        border-right:50px solid transparent;
        border-left:50px solid transparent;
    }

(2)三角2

    div{
        width:0;
        height:0;
        border-bottom:50px solid red;
        border-right:50px solid transparent;
        border-left:50px solid transparent;
    }

(3)三角3

    div{
        width:0;
        height:0;
        border-left:50px solid red;
        border-top:50px solid transparent;
        border-right:50px solid transparent;
    }

(4)三角4

    div{
        width:0;
        height:0;
        border-right:50px solid red;
        border-top:50px solid transparent;
        border-bottom:50px solid transparent;
    }

(5)三角5

    div{
        width:0;
        height:0;
        border-top:50px solid red;
        border-right:50px solid transparent;
    }

还有很多,就不一一实现了,总体的原则就是通过上下左右边框来控制三角形的方向,用边框的宽度比来控制三角形的角度。

# 2. 实现一个扇形

用CSS实现扇形的思路和三角形基本一致,就是多了一个圆角的样式,实现一个90°的扇形:

    div{
        border:100px solid transparent;
        width:0;
        height:0;
        border-radius:100px;
        border-top-color:red;
    }

# 3. 实现一个圆和半圆

(1)实现圆:

    div{
        width:100px;
        height:100px;
        border-radius:50%;
        background-color:red;
    }

注意:在使用border-radius时,使用50%和100%都可以得到一个圆,那这两个值到底有什么区别呢:border-radius的值是百分比的话,就相当于盒子的宽度和高度的百分比。如一个50px 150px的方形,如果border-radius设置为100%,则等价于:

     border-radius:50% / 150px ;1

而border-radius又是由border-top-left-radius、border-top-right-radius、border-bottom-left-radius、border-bottom-right-radius组成,所有上面border-radius:100%又等价于:

    border-top-left-radius:100%;
    border-top-right-radius:100%;
    border-bottom-left-radius:100%;
    border-bottom-right-radius:100%;

或

    border-top-left-radius:50px 150px;
    border-top-right-radius:50px 150px;
    border-bottom-left-radius:50px 150px;
    border-bottom-right-radius:50px 150px;

为什么border-radius设置成100%和50%都能画成圆呢?因为,在W3C中对重合曲线做了规定:如果两个相邻的半径和超过了对应的盒子的边的长度,那么浏览器要重新计算以保证它们不重合。也就是说,如果相邻圆角的半径都设置成大于50%,那么浏览器会根据图形的实际情况做一些计算。因此,为了避免不必要的计算,建议使用border-radius: 50%。

(2)实现半圆:

    div{
        width:100px;
        height:50px;
        border-radius:0px 0px 100px 100px;
        background-color:red;
    }

# 4. 实现一个宽高自适应的正方形

  • 利用vw来实现:
    .square{
        width:10%;
        height:10vw;
        background:tomato;
    }

  • 利用元素的margin/padding百分比是相对父元素width的性质来实现:
    .square{
        width:20%;
        height:0;
        padding-top:20%;
        background:tomato;
    }

  • 利用子元素的margin-top的值来实现:
    .square{
        width:30%;
        overflow:hidden;
        background:yellow;
    }
    .square::after{
        content:"";
        display:block;
        margin-top:100%;
    }

# 5. 画一个梯形

    <div class="trapezoid"></div>

(1)实现一个直角梯形:

    .trapezoid{
        height:0;
        width:100px;
        border-bottom:100px solid red;
        border-right:40px solid transparent;
    }

效果:

(2)实现一个等腰梯形

    .trapezoid{
        height:0;
        width:100px;
        border-width:0 40px 100px 40px;
        border-style:none solid solid;
        border-color:transparent transparent red;
    }

效果:

# 6. 画一条0.5px的线

  • 采用transform: scale()的方式,该方法用来定义元素的2D 缩放转换:
    transform;scale(0.5,0.5);
  • 采用meta viewport的方式
 <meta name="viewport" content="width=device-width,initial-scale=1.0,minimun-scale=1.0,maximum-scale=1.0,user-scalable=no"/>

这样就能缩放到原来的0.5倍,如果是1px那么就会变成0.5px。viewport只针对于移动端,只在移动端上才能看到效果

# 7. 设置小于12px的字体

在谷歌下css设置字体大小为12px及以下时,显示都是一样大小,都是默认12px。

解决办法:

  • 使用Webkit的内核的-webkit-text-size-adjust的私有CSS属性来解决,只要加了-webkit-text-size-adjust:none;字体大小就不受限制了。但是chrome更新到27版本之后就不可以用了。所以高版本chrome谷歌浏览器已经不再支持-webkit-text-size-adjust样式,所以要使用时候慎用。

  • 使用css3的transform缩放属性-webkit-transform:scale(0.5); 注意-webkit-transform:scale(0.75);收缩的是整个元素的大小,这时候,如果是内联元素,必须要将内联元素转换成块元素,可以使用display:block/inline-block/...;

  • 使用图片:如果是内容固定不变情况下,使用将小于12px文字内容切出做图片,这样不影响兼容也不影响美观。

# 8. 如何解决 1px 问题?

1px 问题指的是:在一些 Retina屏幕 的机型上,移动端页面的 1px 会变得很粗,呈现出不止 1px 的效果。原因很简单——CSS 中的 1px 并不能和移动设备上的 1px 划等号。它们之间的比例关系有一个专门的属性来描述:

    windoe.devicePixelRatio= 设备物理像素 / CSS像素

打开 Chrome 浏览器,启动移动端调试模式,在控制台去输出这个 devicePixelRatio 的值。这里选中 iPhone6/7/8 这系列的机型,输出的结果就是2:

这就意味着设置的 1px CSS 像素,在这个设备上实际会用 2 个物理像素单元来进行渲染,所以实际看到的一定会比 1px 粗一些。

解决1px 问题的三种思路:

思路一:直接写 0.5px

如果之前 1px 的样式这样写:

    border:1px solid #333;

可以先在 JS 中拿到 window.devicePixelRatio 的值,然后把这个值通过 JSX 或者模板语法给到 CSS 的 data 里,达到这样的效果(这里用 JSX 语法做示范):

    <div id="container" data-device={{window.devicePixeRatio}}></div>

然后就可以在 CSS 中用属性选择器来命中 devicePixelRatio 为某一值的情况,比如说这里尝试命中 devicePixelRatio 为2的情况:

    #container[data-device='2']{
        border:0.5px solid #333;
    }

直接把 1px 改成 1/devicePixelRatio 后的值,这是目前为止最简单的一种方法。这种方法的缺陷在于兼容性不行,IOS 系统需要8及以上的版本,安卓系统则直接不兼容。

思路二:伪元素先放大后缩小

这个方法的可行性会更高,兼容性也更好。唯一的缺点是代码会变多。

思路是先放大、后缩小:在目标元素的后面追加一个 ::after 伪元素,让这个元素布局为 absolute 之后、整个伸展开铺在目标元素上,然后把它的宽和高都设置为目标元素的两倍,border值设为 1px。接着借助 CSS 动画特效中的放缩能力,把整个伪元素缩小为原来的 50%。此时,伪元素的宽高刚好可以和原有的目标元素对齐,而 border 也缩小为了 1px 的二分之一,间接地实现了 0.5px 的效果。

代码如下:

    #container[data-device='2']{
        position;relative;
    }
    #container[data-device='2']::after{
        position:absolute;
        top:0;
        left:0;
        width:200%;
        height:200%;
        content:'';
        transform:scale(0.5);
        transform-origin:left top;
        box-sizing:border-box;
        border:1px solid #333;
    }

思路三:viewport 缩放来解决 这个思路就是对 meta 标签里几个关键属性下手:

 <meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable-no"/>

这里针对像素比为2的页面,把整个页面缩放为了原来的1/2大小。这样,本来占用2个物理像素的 1px 样式,现在占用的就是标准的一个物理像素。根据像素比的不同,这个缩放比例可以被计算为不同的值,用 js 代码实现如下:

    const sacle = 1 / windoe.devicePixeRation
    //  这里metaEl 指的是 meat 标签对于的 Dom
    metaEl.setAttrubute('content',"width=device-widht,user-scale=no,initial-scale=${scale}")

这样解决了,但这样做的副作用也很大,整个页面被缩放了。这时 1px 已经被处理成物理像素大小,这样的大小在手机上显示边框很合适。但是,一些原本不需要被缩小的内容,比如文字、图片等,也被无差别缩小掉了。

定位与浮动
数据类型

← 定位与浮动 数据类型→

最近更新
01
垃圾回收及内存泄漏
08-01
02
面向对象
08-01
03
异步编程
08-01
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式