39.前端基础-布局2

11.7 实现扇形、圆形

参考答案

圆形:

border-radius圆角的四个值按顺序取值分别为:左上、右上、右下、左下。这里只设置一个值,代表四个角的取值都为为50%

原理:border-radius: 50% 弯曲元素的边框以创建圆。
由于圆在任何给定点具有相同的半径,故宽和高都需要保证一样的值,不同的值将创建椭圆。

<div class="circle"></div>
<style>
  .circle {
     border-radius: 50%;
     width: 80px;
     height: 80px;
       background: #666;
  }
</style>

扇形:

  1. 利用border-radius,实现90度角的扇形:

    原理:

    左上角是圆角,其余三个角都是直角:左上角的值为宽和高一样的值,其他三个角的值不变(等于0)。

<div class="sector"></div>
<style>
.sector{
  border-radius:80px 0 0;
  width: 80px;
  height: 80px;
  background: #666;
}</style>
  1. 绘制任意角度的扇形
<div class="shanxing shanxing1">
    <div class="sx1"></div>
     <div class="sx2"></div>
</div>
<!--*绘制一个85度扇形*/--p>
<div class="shanxing shanxing2">
    <div class="sx1"></div>
     <div class="sx2"></div>
</div>
<!--*绘制一个向右扇形,90度扇形*-->
<div class="shanxing shanxing3">
    <div class="sx1"></div>
     <div class="sx2"></div>
</div>
<!--*绘制一个颜色扇形 */--p>
<div class="shanxing shanxing4">
    <div class="sx1"></div>
     <div class="sx2"></div>
</div>
<!--/*绘制一个不同颜色半圆夹角 */-->
<div class="shanxing shanxing5">
    <div class="sx1"></div>
     <div class="sx2"></div>
</div>
<style>
.shanxing{
    position: relative;
    width: 200px;
    height: 200px;
    border-radius: 100px;
    background-color: yellow;
}

.sx1{
    position: absolute;
    width: 200px;
    height: 200px;
    transform: rotate(0deg);
    clip: rect(0px,100px,200px,0px); /*这个clip属性用来绘制半圆,在clip的rect范围内的内容显示出来,使用clip属性,元素必须是absolute的 */
    border-radius: 100px;
    background-color: #f00;
    /*-webkit-animation: an1 2s infinite linear; */
}

.sx2{
    position: absolute;
    width: 200px;
    height: 200px;
    transform: rotate(0deg);
    clip: rect(0px,100px,200px,0px);
    border-radius: 100px;
    background-color: #f00;
    /*-webkit-animation: an2 2s infinite linear;*/
}

/*绘制一个60度扇形*/
.shanxing1 .sx1{transform: rotate(-30deg);}
.shanxing1 .sx2{transform: rotate(-150deg);}

/*绘制一个85度扇形*/
.shanxing2 .sx1{transform: rotate(-45deg);}
.shanxing2 .sx2{transform: rotate(-140deg);}

/*绘制一个向右扇形,90度扇形*/
.shanxing3 .sx1{transform: rotate(45deg);}
.shanxing3 .sx2{transform: rotate(-45deg);}

/*绘制一个颜色扇形 */
.shanxing4 .sx1{transform: rotate(45deg);background-color: #fff;}
.shanxing4 .sx2{transform: rotate(-45deg);background-color: #fff;}

/*绘制一个不同颜色半圆夹角 */
.shanxing5 .sx1{transform: rotate(45deg);background-color: #f00;}
.shanxing5 .sx2{transform: rotate(-45deg);background-color: #0f0;       
</style>

11.8 旋转45度

参考答案

CSS中使用rotate方法来实现对元素的旋转,在参数中加入角度值,旋转方式为顺时针旋转。

<!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title>Transform旋转</title>
 6         <style>
 7         div {
 8             width: 300px;
 9             margin: 150px auto;
10             background-color: yellow;
11             text-align: center;
12             -webkit-transform: rotate(45deg);    /* for Chrome || Safari */
13             -moz-transform: rotate(45deg);       /* for Firefox */
14             -ms-transform: rotate(45deg);        /* for IE */
15             -o-transform: rotate(45deg);         /* for Opera */
16         }
17         </style>
18     </head>
19     <body>
20         <div>黄色div</div>
21     </body>
22 </html>

11.9 画 0.5px 的直线

参考答案

  1. 使用scale缩放
<style>
.hr.scale-half {
    height: 1px;
    transform: scaleY(0.5);
}
</style>
    <p>1px + scaleY(0.5)</p>
    <div class="hr scale-half"></div>

Chrome/Safari都变虚了,只有Firefox比较完美看起来是实的而且还很细,效果和直接设置0.5px一样。所以通过transform: scale会导致Chrome变虚了,而粗细几乎没有变化。但是如果加上transform-origin: 50% 100%:

.hr.scale-half {
    height: 1px;
    transform: scaleY(0.5);
    transform-origin: 50% 100%;
}

chrome现在的效果如下

  1. 线性渐变linear-gradient
<style>
.hr.gradient {
    height: 1px;
    background: linear-gradient(0deg, #fff, #000);
}
</style>
<p>linear-gradient(0deg, #fff, #000)</p>
<div class="hr gradient"></div>

inear-gradient(0deg, #fff, #000)的意思是:渐变的角度从下往上,从白色#fff渐变到黑色#000,而且是线性的,在高清屏上,1px的逻辑像素代表的物理(设备)像素有2px,由于是线性渐变,所以第1个px只能是#fff,而剩下的那个像素只能是#000,这样就达到了画一半的目的。

  1. boxshadow
<style>
.hr.boxshadow {
    height: 1px;
    background: none;
    box-shadow: 0 0.5px 0 #000;
}
</style>
<p>box-shadow: 0 0.5px 0 #000</p>
<div class="hr boxshadow"></div>
  1. viewport
<meta name="viewport" content="width=device-width,initial-sacle=0.5">

其中width=device-width表示将viewport视窗的宽度调整为设备的宽度,这个宽度通常是指物理上宽度。默认的缩放比例为1时,如iphone 6竖屏的宽度为750px,它的dpr=2,用2px表示1px,这样设置之后viewport的宽度就变成375px。但是我们可以改成0.5,viewport的宽度就是原本的750px,所以1个px还是1px,正常画就行,但这样也意味着UI需要按2倍图的出,整体面面的单位都会放大一倍。

11.10 css 切换主题

参考答案

方式一:主题层

这应该是实现主题功能的一种最常用的手段了。首先,我们的站点会有一个最初的基础样式(或者叫默认样式);然后通过添加一些后续的额外的CSS来覆盖与重新定义部分样式。

具体实现

首先,我们引入基础的样式 components.* 文件

@import "components.tabs";
@import "components.buttons"

其中 components.tabs 文件内容如下

.tab {
    margin: 0;
    padding: 0;
    background-color: gray;
}

然后,假设我们的某个主题的样式文件存放于 theme.* 文件:

对应于 components.tabstheme.tabs 文件内容如下

.tab {
    background-color: red;
}

因此,我们只需要引入主题样式文件即可

@import "components.tabs";
@import "components.buttons"

@import "theme.tabs";

这样当前的样式就变为了

.tab {
    margin: 0;
    padding: 0;
    /* background-color: gray; */
    background-color: red;
}

优点

  • 实现方式简单
  • 可以实现将主题应用与所有元素

缺点

  • 过多的冗余代码
  • 许多的CSS其实是无用的,浪费了带宽
  • 把样式文件切分到许多文件中,更加琐碎

方式二:有状态的主题

该方式可以实现基于条件选择不同的主题皮肤,并允许用户在客户端随时切换主题。非常适合需要客户端样式切换功能,或者需要对站点某一部分(区域)进行独立样式设置的场景。

具体实现

还是类似上一节中 Tab 的这个例子,我们可以将 Tab 部分的 (S)CSS 改为如下形式:

.tab {
    background-color: gray;

    .t-red & {
        background-color: red;
    }

    .t-blue & {
        background-color: blue;
    }
}

这里我们把.t-red.t-blue称为 Tab 元素的上下文环境(context)。Tab 元素会根据 context 的不同展示出不同的样式。

最后我们给body元素加上这个开关

<body class="t-red">
    <ul class="tabs">...</ul>
</body>

此时 Tab 的颜色为红色。

当我们将t-red改为t-blue时,Tab 就变为了蓝色主题。

进一步的,我们可以创建一些 (S)CSS 的 util class(工具类)来专门控制一些 CSS 属性,帮助我们更好地控制主题。例如我们使用如下的.u-color-current类来控制不同主题下的字体颜色

.u-color-current {
    .t-red & {
        color: red;
    }

    .t-blue & {
        color: blue;
    }
}

这样,当我们在不同主题上下文环境下使用.u-color-current时,就可以控制元素展示出不同主题的字体颜色

<body class="t-red">
    <h1 class="page-title u-color-current">...</h1>
</body>

上面这段代码会控制<h1>元素字体颜色为红色主题时的颜色。

优点

  • 将许多主题放在了同一处代码中
  • 非常适合主题切换的功能
  • 非常适合站点局部的主题化
  • 可以实现将主题应用于所有元素

缺点

  • 有时有点也是缺点,将许多主题混杂在了同一块代码中
  • 可能会存在冗余

方式三:配置主题

这种方式其实是在开发侧来实现主题样式的区分与切换的。基于不同的配置,配合一些开发的自动化工具,我们可以在开发时期根据配置文件,编译生成不同主题的 CSS 文件。

它一般会结合使用一些 CSS 预处理器,可以对不同的 UI 元素进行主题分离,并且向客户端直接提供主题样式下最终的 CSS。

具体实现

我们还是以 Sass 为例:

首先会有一份 Sass 的配置文件,例如settings.config.scss,在这份配置中定义当前的主题值以及一些其他变量

$theme: red;

然后对于一个 Tab 组件,我们这么来写它的 Sass 文件

.tab {
    margin: 0;
    padding: 0;

    @if ($theme == red) {
        background-color: red;
    } @else {
        background-color: gray;
    }
}

这时,我们在其之前引入相应的配置文件后

@import "settings.config";
@import "components.tabs";

Tab 组件就会呈现出红色主题。

当然,我们也可以把我们的settings.config.scss做的更健壮与易扩展一些

$config: (
    theme: red,
    env: dev,
)

// 从$config中获取相应的配置变量
@function config($key) {
    @return map-get($config, $key);
}

与之前相比,这时候使用起来只需要进行一些小的修改,将直接使用theme变量改为调用config方法

.tab {
    margin: 0;
    padding: 0;

    @if (config(theme) == red) {
        background-color: red;
    } @else {
        background-color: gray;
    }
}

优点

  • 访问网站时,只会传输所需的 CSS,节省带宽
  • 将主题的控制位置放在了一个地方(例如上例中的settings.config.scss文件)
  • 可以实现将主题应用于所有元素

缺点

  • 在 Sass 中会有非常多逻辑代码
  • 只支持有限数量的主题
  • 主题相关的信息会遍布代码库中
  • 添加一个新主题会非常费劲

方式四:主题调色板

这种方式有些类似于我们绘图时,预设了一个调色板(palette),然后使用的颜色都从其中取出一样。

在实现主题功能时,我们也会有一个类似的“调色板”,其中定义了主题所需要的各种属性值,之后再将这些信息注入到项目中。

当你经常需要为客户端提供完全的定制化主题,并且经常希望更新或添加主题时,这种模式会是一个不错的选择。

具体实现

在方式三中,我们在一个独立的配置文件中设置了一些“环境”变量,来标示当前所处的主题。而在方式四中,我们会更进一步,抽取出一个专门的 palette 文件,用于存放不同主题的变量信息。

例如,现在我们有一个settings.palette.red.scss文件

$color: red;
$color-tabs-background: $color-red;

然后我们的components.tabs.scss文件内容如下

.tabs {
    margin: 0;
    padding: 0;
    backgroung-color: $color-tabs-background;
}

这时候,我们只需要引入这两个文件即可

@import "settings.palette.red";
@import "components.tabs";

可以看到,components.tabs.scss中并没有关于主题的逻辑判断,我们只需要专注于编辑样式,剩下就是选择所需的主题调色板(palette)即可。

优点

  • 编译出来的样式代码无冗余
  • 非常适合做一些定制化主题,例如一个公司采购了你们的系统,你可以很方便实现一个该公司的主题
  • 可以从一个文件中完全重制出你需要的主题样式

缺点

  • 由于主要通过设定不同变量,所以代码确定后,能实现的修改范围会是有限的

方式五:用户定制化

这种模式一般会提供一个个性化配置与管理界面,让用户能自己定义页面的展示样式。

“用户定制化”在社交媒体产品、SaaS 平台或者是 Brandable Software 中最为常见。

具体实现

要实现定制化,可以结合方式二中提到的 util class。

首先,页面中支持自定义的元素会被预先添加 util class,例如 Tab 元素中的u-user-color-background

<ul class="tabs u-user-color-background">...</ul>

此时,u-user-color-background还并未定义任何样式。而当用户输入了一个背景色时,我们会创建一个``标签,并将 hex 值注入其中

<style id="my-custom">
    .u-user-color-background {
        background-color: #00ffff;
    }
</style>

这时用户就得到了一个红色的 Tab。

优点

  • 不需要开发人员的输入信息(是用户定义的)
  • 允许用户拥有自己“独一无二”的站点
  • 非常实用

缺点

  • 不需要开发人员的输入信息也意味着你需要处理更多的“不可控”情况
  • 会有许多的冗余
  • 会浪费 CSS 的带宽
  • 失去部分 CSS 的浏览器缓存能力
全部评论

相关推荐

头像
不愿透露姓名的神秘牛友
04-08 00:50
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务