飘雪的浮云

飘雪的浮云 查看完整档案

合肥编辑南开大学  |  计算机科学与技术 编辑家里蹲  |  产品 编辑 luanzun.com 编辑
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

飘雪的浮云 发布了文章 · 2020-12-02

nginx+gunicorn+fastapi 部署自动后台启动

方案背景

系统版本:debian9
环境搭配:python3 虚拟环境 + fastapi + uvicorn + gunicorn
项目根目录: /data/wwwroot/domian.com

官方文档中是以 IP:PORT 形式启动 fastapi,但每次都要进虚拟环境通过命令启动 gunicorn,贼麻烦。后来改成 systemd + gunicorn 的方式后,开机自动启动 gunicorn 而且不占用端口。

具体部署 fastapi 另外写文章说明,本文章只说 nginx + systemd + gunicorn 的配置方式。

大概方案

新建以下文件:

/etc/systemd/system/gunicorn.service
/etc/systemd/system/gunicorn.socket

nginxconf 文件中 不用代理 ip:prot 形式,而是代理sock 文件。

具体步骤

在项目根目录创建 gunicorn的配置文件 gconfig.py ,其内容:

# coding=utf-8

# from gevent import monkey
# monkey.patch_all()
# import multiprocessing

debug = True
# 修改代码时自动重启
reload = True
#
reload_engine = 'inotify'
# //绑定与Nginx通信的端口
# bind = '127.0.0.1:3002'
bind = 'unix:/data/wwwroot/luejiao.com/tmp/gunicorn.sock'
pidfile = 'log/gunicorn.pid'

workers = 4  # 进程数
# workers = multiprocessing.cpu_count() * 2 + 1 #进程数

worker_class = 'uvicorn.workers.UvicornWorker'  # 默认为阻塞模式,最好选择gevent模式,默认的是sync模式
# 日志级别
# debug:调试级别,记录的信息最多;
# info:普通级别;
# warning:警告消息;
# error:错误消息;
# critical:严重错误消息;
loglevel = 'debug'
# 访问日志路径
accesslog = 'log/gunicorn_access.log'
# 错误日志路径
errorlog = './log/gunicorn_error.log'
# 设置gunicorn访问日志格式,错误日志无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'


# 执行命令
# gunicorn -c gconfig.py main:app
# gunicorn -c gconfig.py main:app -k uvicorn.workers.UvicornWorker

'''
自动执行
使用 supervisor
https://docs.gunicorn.org/en/stable/deploy.html#supervisor
参考资料:
https://www.jianshu.com/p/bbd0b4cfcac9
https://www.cnblogs.com/tk091/archive/2014/07/22/3859514.html
'''

/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
Type=notify
# the specific user that our service will run as
User=gunicorn
Group=www
# another option for an even more restricted service is
# DynamicUser=yes
# see http://0pointer.net/blog/dynamic-users-with-systemd.html
RuntimeDirectory=gunicorn

# WorkingDirectory 是项目路径目录
WorkingDirectory=/data/wwwroot/domian.com
# 代替手动执行的命令,
# 原本在虚拟环境中要执行的 gunicorn -c gconfig.py main:app -k uvicorn.workers.UvicornWorker
# 其中 gunicorn 和 gconfig.py 要写完整的路径名称
ExecStart=/data/wwwroot/luejiao.com/venv/bin/gunicorn -c /data/wwwroot/luejiao.com/gconfig.py main:app -k uvicorn.workers.UvicornWorker
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target

/etc/systemd/system/gunicorn.socket

[Unit]
Description=gunicorn socket

[Socket]
# ListenStream 写要生成的 sock 文件路径,要写完整路径。我是放到项目根目录下的。
ListenStream=/data/wwwroot/domian.com/domian.com_gunicorn.sock
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
User=www-data
# Optionally restrict the socket permissions even more.
# Mode=600

[Install]
WantedBy=sockets.target

nginxdomian.conf,其它配置不写,主要是 / 代理这部分:

location / {
    # 放弃原始 ip 端口形式,改为代理到 sock 文件
    # proxy_pass http://127.0.0.1:3002; 
    # unix 后面的路径就是前面文件中的 sock 文件的完整路径,注意格式。
      proxy_pass http://unix:/data/wwwroot/domian.com/domian.com_gunicorn.sock;
    }

操作命令

重启 nginx 后,会自动生成 domian_gunicorn.sock,然后打开域名确认 fastapi 应用是否正常启动:

systemctl reload nginx.service
systemctl restart nginx.service

开机启动并立即启动 gonicorn.socket

systemctl enable gunicorn.socket --now

不同的操作命令:

启动: systemctl start gunicorn.service
状态:systemctl status gunicorn.service
停止:systemctl stop gunicorn.service
重启:systemctl restart gunicorn.service
查看原文

赞 1 收藏 0 评论 4

飘雪的浮云 关注了标签 · 2020-11-30

gunicorn

Gunicorn 绿色独角兽'是一个Python WSGI UNIX的HTTP服务器。这是一个预先叉工人模式,从Ruby的独角兽(Unicorn )项目移植。该Gunicorn服务器大致与各种Web框架兼容,只需非常简单的执行,轻量级的资源消耗,以及相当迅速。

特点:
本身支持WSGI、Django、Paster
自动辅助进程管理
简单的 Python配置
允许配置多个工作环境
各种服务器的可扩展钩子
与Python 2.x > = 2.5 兼容

关注 16

飘雪的浮云 回答了问题 · 2020-11-30

Starting gunicorn的日志为何打在errorlog中

accesslog 是访问日志,errorloggunicorn 系统日志。
loglevel 可以设置 errorlog 的记录日志级别:

# debug:调试级别,记录的信息最多;
# info:普通级别;
# warning:警告消息;
# error:错误消息;
# critical:严重错误消息;

启动日志属于 info 级别的信息。
你可以看下官方配置文档里的 loglevelcapture_output
https://docs.gunicorn.org/en/...

debug 日志和 info 日志好像不能分别设置文件。

关注 2 回答 1

飘雪的浮云 收藏了文章 · 2020-09-27

pure.css框架源码详细解析

一篇文章包你学会使用pure.css框架,理解其原理,并学会其包含css知识,学会自己写css组件

前提知识

选择器介绍


优先级就是分配给指定css声明的一个权重,它由匹配的选择器中的每一种选择器类型的数值决定。而当优先级与多个css声明中任何一个声明的优先级相等时,css中最后的那个声明将会被应用到元素上。

  • 选择器是用于定位文档中的元素以便设定相应的样式代码

  • 选择器分类

基础选择器

选择器含义实例
*通用选择器,匹配任何元素*{font-size:16px}
E标签选择器,匹配所有使用E标签的元素a{font-size:16px}
.errorclass选择器,匹配所有class属性中包含error的元素.error{font-weight:bold;}
#correctid选择器,匹配所有id属性值为correct的元素#correct{font-style:italic;}

​ 组合选择器

选择器含义实例
E,F多元素选择器,同时匹配所有E元素或F元素div,p{background-attachment:fixed;}
E F后代元素选择器,匹配所有属于E元素的后代F元素div a{background-color:blue;}
E>F子元素选择器,匹配所有E元素的子元素F
E+F毗邻元素选择器,匹配所有紧随E元素之后的同级元素F

属性选择器

选择器含义实例
E[att]匹配所有具有att属性的E元素p[style]{background-repeatrepeat-y;}
E[att=val]匹配所有att属性等于"val"的E元素div[class="c1"]
E[att~=val]匹配所有att属性具有多个空格分隔的值、其中一个值等于"val"的E元素div[class~=c2]
E[att=val]匹配所有att属性具有多个连字号分隔(hyphen-separated)的值、其中一个值以"val"开头的E元素p[lang =en]

​ 伪类选择器

选择器含义实例
E:first-child匹配父元素E下的第一个子元素div:first-child{text-align:center;}
E:link匹配所有未被点击的链接
E:visited匹配所有已被点击的链接
E:active匹配鼠标悬停其上的E元素
E:hover匹配鼠标悬停其上的E元素
E:focus匹配获得焦点的E
E:lang(c)匹配lang属性等于c的E元素

​ 伪元素

选择器含义实例
E:first-line匹配E元素的第一行p:first-line{color:red;}
E:first-letter匹配E元素的第一个字母.c1:first-letter{color:blue;}
E:before在E元素之前插入生成的内容.ctn before{}
E:after在E元素之后插入生成的内容.ctn after{}

优先级的计算


(解释了众多css样式被覆盖的问题)

首先!important的css定义是拥有最高的优先级

优先级计算分为a,b,c,d四个位数,这四个位数的优先级依次递减。

内联样式:a=1;

ID选择器:b=1;

属性选择器和类选择器:c=1;

元素选择器和伪类选择器: d=1;

li            {}  /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
li:first-line {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul li         {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul ol+li      {}  /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
h1 + *[rel=up]{}  /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
ul ol li.red  {}  /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
li.red.level  {}  /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
#x34y         {}  /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
style=""          /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

文档流


(主要应用于menu中,垂直和水平导航栏)

css文档流(document flow)和普通流(normal flow)实际上指的是同一个概念。

文档流 指的是元素按照在HTML中为的位置顺序决定排布的过程,在排布过程中,将窗体自上而下分为一行行,并在每行中从左至右的顺序排放元素。

非浮动的块级元素(block)独占一行,行内元素(inline)不会独占一行。

块级元素的效果

<div style=" width:100px; height:100px; border: 1px solid">div1</div>
<div style=" width:100px; height:100px; border: 1px solid">div2</div>

%E5%9D%97%E7%BA%A7%E5%85%83%E7%B4%A0_ogskld.png

内联元素的效果

<a href="http:">超链接1</a>
<a href="http:">超链接2</a>

%E5%86%85%E8%81%94_by35cr.png

绝对定位


(主要是用于含有重叠菜单的子菜单定位问题)

绝对定位其实是相对了某个东西的,而这个东西就是元素的第一个有position且position不能为static的祖先元素。就是这个东西必须是有一定地位的(position:absolute或position:relative),不能是一个穷鬼(position:static)或者没有地位的(position).这个时候,绝对定位,它才能以之为标杆。

给他爸爸加上相对定位,然后他是绝对定位

  <div style=" border:1px solid Red; padding:10px; width: 340px; height: 400px"">
    红色:太公
        <div style="border:1px solid Green; padding:10px; width: 320px; height: 360px;">
        绿色:爷爷
            <div style="border:1px solid Yellow; padding:10px; width: 300px; height: 320px;position:relative; ">
            黄色:老爸
                <div style="width: 100px; height: 100px;border:1px solid">
                    div1</div>
                <div style="width: 100px; height: 100px;border:1px solid;position:absolute;left:120px; top:100px;">
                    div2</div>
                <div style="width: 100px; height: 100px;border:1px solid">
                    div3</div>
            </div>
        </div>
    </div>

%E7%9B%B8%E5%AF%B92_tsb9ms.png

基础

所有pure模块都是基于normalize.css构建,对比base.css详细normalize.css内容请查看《Normalize.css》

<link rel="stylesheet" href="https://unpkg.com/purecss@0.6.1/build/base-min.css">

Normalize.css是一个小的CSS文件,为HTML元素样式提供跨浏览器的一致性。它是一个现代的、支持HTML5的、传统CSS重置的替代。

html {
  font-family: sans-serif; /* 1 */
  //无衬线体,字的比划开始及结束地方没有额外装饰
  -ms-text-size-adjust: 100%; /* 2 */
  -webkit-text-size-adjust: 100%; /* 2 */
  //iPhone 和 Android 的浏览器纵向 (Portrate mode) 和橫向 (Landscape mode) 模式皆有自动调整字体大小的功能。控制它的就是 CSS 中的 -webkit-text-size-adjust。text-size-adjust 设为 none 或者 100% 关闭字体大小自动调整功能.
}
abbr[title] {
  border-bottom: 1px dotted;
}
//缩略词显示详情,含有title属性的abbr标签缩略词的底部边线

abbr_wmhguu.png

svg:not(:root){
  overflow: hidden;
}
//svg(可缩放矢量图形),是基于可扩展标记语言(XML),用于描述二维矢量图形
:root,匹配文档的根元素,在HTML中,根元素永远是HTML
:not(selector)选择器匹配非指定元素
则以上是svg非根元素的元素

隐藏元素


[hidden],
template {
//template模板标签
  display: none;
}
.hidden,
[hidden] {
//!important最高优先级
    display: none !important;
}

html元素添加hidden属性,可以实现display:none !important;

<input type="text" name="_csrf" hidden>

响应式图片


<img>添加class .pure-img,配合viewport可以实现图片伸缩

.pure-img {
//最小宽度(min-width)与最大宽度(max-width)用于设置图片最小最大宽度限制比较多。
比如一个图片为主列表,对象里图片大小不定时候,为了不想让他太小不统一这个时候我们可以使用css最小宽度样式。再如,一个盒子里有文章有图片混排的时候,有时图片宽度不能确定,这个时候如果html img图片宽度超出了盒子宽度,可能图片就会撑破div盒子造成图片混乱。
    max-width: 100%;
    height: auto;
    display: block;
}

max-width详细情况可以查看《CSS max-width 属性》

<img class="pure-img" data-original="...">

栅格

.pure-g的样式


letter-spacing: -0.31em;

1em == 16px,因为浏览器默认的字体大小是16px,em可以在浏览器改变字体大小时作出相应的放大和缩小,弹性布局

*word-spacing: -0.43em

在样式属性名前加*,这样的样式可以被IE6和IE7所识别,而其它浏览器则会当做错误忽略,所以,这样的样式写法只对IE6/7生效.
而_开头的属性只有IE6才能识别.

关于letter-spacing和word-spacing的区别

图片描述

word-spacing属性增加或减少单词之间的空白

letter-spacing属性增加或减少字符之间的空白

text-rendering: optimizespeed;

text-rendering属性常被用在windows和linux系统中,用来给渲染引擎提供信息,让文本在速度和可读性方面得到优化,控制在线字体的微妙细节,目前只有firefos和google支持。

optimizespeed取值 Gecko内核的浏览器将强调可读性和几何精度,同时绘制文本渲染速度,禁用字距和连写

font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;

常用的字体

display: -webkit-box;/ Chrome 4+, Safari 3.1, iOS Safari 3.2+ /

display: -webkit-flex;/ Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 /

display: -ms-flexbox;/ IE 10 /

display: flex; / Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ /

webkit是一个开源的浏览器引擎,与之对应的有Gecko和Trident,加上之后表示私有属性

-moz代表firefox浏览器私有属性
-ms代表IE浏览器私有属性
-webkit代表chrome、safari私有属性

关于display:box和display:flex的区别

flex是2012年以后的标准语法,大部分浏览器已经实现了无前缀版本,box是2009年语法,需要加上前缀

以上其实是该属性的兼容性代码

flex布局,弹性布局,用来为盒装模型提供最大的灵活性
图片描述

通过添加.pure-g和未添加进行对比,可以发现,.pure-g的效果主要就是flex属性,而flex属性在此处的重要作用是给.pure-u元素添加float浮动属性

-webkit-flex-flow: row wrap;

-ms-flex-flow: row wrap;

flex-flow: row wrap;

flex-flow:<flex-direction>||<flex-wrap>

row表示行内方向,即弹性项目在弹性容器中的起始放置方向,flex-wrap表示需要拆行以使得弹性项目能被容器包含

-webkit-align-content: flex-start;

-ms-flex-line-pack: start;

align-content: flex-start;

多行项目时,让弹性元素始终排在头部,中间没有间距,详细flex教程请查看《Flex布局教程:语法篇》

@media all and (min-width:xxx) and (max-width:xxx){   
/*这段查询的all是针对所有设备(有些设备不一定是屏幕,也许是打字机,盲人阅读器)*/ 
        table .pure-g {
        display: block;
    }
}   

写这一行是因为flex在ie10中的table时不起作用

.pure-g [class *= "pure-u"] {font-family: sans-serif;}

表示的是设置class属性值包含有pure-u 字符串的所有pure-g元素的样式

div[class^="something"] { }表示以之开始
div[class$="something"] { }表示以之结尾

.pure-u的样式


.pure-u {
display: inline-block;
*display: inline; /* IE < 8: fake inline-block */
zoom: 1;
letter-spacing: normal;
word-spacing: normal;
vertical-align: top;
text-rendering: auto;
}

zoom: normal | <number> | <percentage>

​ normal:使用对象的实际尺寸

​ <number>:用浮点数来定义缩放比例

​ <percentage>:用百分比来定义缩放比例

vertical-align垂直对齐属性

.pure-u-x-y{
     display: inline-block;
    *display: inline;
    zoom: 1;
    letter-spacing: normal;
    word-spacing: normal;
    vertical-align: top;
    text-rendering: auto;
}

这个样式和.pure-u是相同的

pure栅格默认支持5列和24列

x/y表示的是列数所占的比重

.pure-u-1-24 {
    width: 4.1667%;
    *width: 4.1357%;
}

可以发现IE67和其他浏览器之间的宽度存在细微差别,微调后可修复

图片描述

表单

.pure-form样式


.pure-form input[type="text"]

不同的表单类型

    padding: 0.5em 0.6em;
    //设置表单内部填充
    display: inline-block;
    //显示为行内元素
    border: 1px solid #ccc;
    //边界线
    box-shadow: inset 0 1px 3px #ddd;
    //盒子阴影,inset设置在内边框
    border-radius: 4px;
    //圆框边角
    vertical-align: middle;
    //让行内元素居中显示,主要是表单
    box-sizing: border-box;
    //设置盒子尺寸

input:not([type]) //这个属性需要分离出来,因为ie8在一堆css2.1中包含一个css3属性的时候不会执行

:not()否定选择器,可以让你定位不该匹配该选择器的元素,IE6-8浏览器不支持:not()选择器

.pure-form input[type="color"]{

​ padding: 0.2em 0.5em;

} //chrome显示色彩选择器需要额外的空间

input[type="text"]:focus {

outline:0;

border-color:#129FEA;

}

为聚焦的时候添加样式

outline和boder区别

outline是不占空间的,既不会增加额外的width或者height

图片描述

border可应用于几乎所有有形的html元素,而outline是针对链接、表单控件和imageMap等元素,outline会随元素focus出现,随blur而消失

图片描述

详细的情况可以查看《深入浅析border和outline区别》

input[type="text"][disabled]
input[readonly]

这两种写法都会使显示出来的文本框不能输入文字

但disabled会使文本框变灰,而且通过request.getParameter("name")得不到文本框中的内容(如果有的话)

而readonly只是使文本框不能输入,外观没有变化,而且通过request.getParameter("name")可以得到内容,可以复制

input:focus:invalid

同类型的方法

:required必须,要求input不能为空

:valid有效,即当填写内容符合要求时触发

:invalid无效,即当填写内容不符合要求时触发

图片描述

可以看到符合要求时,显示的边框颜色为蓝,右边的没有添加:focus选择器的表单在无效的时候一直都是红色

疑问:

input:focus:invalid和input:focus:invalid:focus差别并没有试验出来

.pure-form fieldset

.pure-form legend

fieldset和legend标签的组合使用

图片描述

实现的手段是添加border:0和border-bottom

.pure-form-stacked样式


可以生成堆叠式表单,即为同一列

图片描述

实现的手段是添加display:block将它变成块级元素,独占整行和margin: 0.25em 0;

.pure-form-aligned样式


clipboard.png

可以生成对齐式表单,label显示在input左边末端对齐
nline-block显示成行内元素,然后设置width使之可以撑满,再设置text-align:right使之向右对齐,此时与表单过于靠近,添加margin属性,使和表单之间间距变大。考虑到字数过长产生换行,使用vertical-align让行内元素居中显示

.pure-group样式


可以为表单标签分组,使用方法是为fieldset添加该class

clipboard.png

区别不大,主要是阴影部分,以及结束部分相连r-radius:0将圆角样式去除,然后使用:first-child和:last-child选择器,重新设置这两个元素的圆角等样式,达到此效果

.pure-form .pure-group input:first-child:last-child

通过伪类选择器设置第一个和最后一个同类标签的样式

.pure-form .pure-input-2-3

设置表单大小

按钮

.pure-button样式


    //这个样式应该主要是运用在移动端
    display: inline-block;
    //行内元素
    zoom: 1;
    //缩放比例
    line-height: normal;
    //默认行高
    white-space: nowrap;
    //如何处理元素内的空白,normal空白会被浏览器忽略,nowrap文本不会换行
    vertical-align: middle;
    //实现行内元素的水平居中
    text-align: center;
    //使文本水平居中
    cursor: pointer;
    -webkit-user-drag: none;
    //user-drag:auto | element | none设置和检索一个元素能否被拖拽
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    //user-select:none | text | all | element设置和检索是否允许选中文本
    box-sizing: border-box;
    //设置的内边距和边框不会增加宽度
//网页端主要样式
.pure-button {
    font-family: inherit;
    font-size: 100%;
    padding: 0.5em 1em;
    color: #444; /* rgba not supported (IE 8) */
    color: rgba(0, 0, 0, 0.80); /* rgba supported */
    border: 1px solid #999;  /*IE 6/7/8*/ 
    border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/
    background-color: #E6E6E6;
    text-decoration: none;
    border-radius: 2px;
}

伪类选择器样式


//设置鼠标在上和焦点在上时的样式
.pure-button-hover,
.pure-button:hover,
.pure-button:focus {
    /* csslint ignore:start */
    filter: alpha(opacity=90);
    //透明度使用
    /* csslint ignore:end */
    background-image: -webkit-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
    background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
}
//用线性渐变创建图像 rgba(0,0,0, 0.05) 40%和rgba(0,0,0, 0.10));分别为起始颜色和终止颜色,第一个参数一般是渐变方向,top 是从上到下、left 是从左到右,如果定义成 left top,那就是从左上角到右下角

clipboard.png

线性渐变

linear-gradient([ [<angle>|to<side-or-cornor>],]?<color-stop>[,<color-stop>]+)

<color-stop> 用于指定渐变的起止颜色

详细情况可以查看《css参考手册》.htm)

疑问:

background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));

transparent这个参数的作用和效果

表格

.pure-table的样式


.pure-table {
    /* Remove spacing between table cells (from Normalize.css) */
    border-collapse: collapse;
    //为表格设置合并边框模型
    //collapse边框会合并成一个单一边框,忽略border-spacing和empty-cells属性,而separate会使边框分开,inherit规定应该从父元素继承border-collapse属性
    border-spacing: 0;
    //设置相邻单元格边框间的距离,不过仅用于边框分离模式
    empty-cells: show;
    //设置是否显示表格中的空单元格,仅适用于边框分离模式
    border: 1px solid #cbcbcb;
}

clipboard.png

.pure-table caption表格标题

.pure-table td,.pure-table th,.pure-table thead

th:表头单元格-包含表头信息

td: 标准单元格-包含数据

thead:结合tbody和tfoot元素结合使用

.pure-table-odd td{

​ background-color: #f2f2f2;

}

隔行添加可以实现斑马纹的效果或者直接加上pure-table-striped

clipboard.png

.pure-table-striped tr:nth-child(2n-1) td{

​ background-color: #f2f2f2;

}

:nth-child(n)选择器 规定属于其父元素的第n格子元素,不论元素类型

:nth-of-type() 选择器的意思是“规定属于其父元素的第二个 p 元素”,这个需要从同类元素开始机选

.pure-table-bordered tbody > tr:last-child > td

有边框的表格,>选择器,可以缩小范围,只选择某个元素的子元素

菜单

.pure-menu的样式


纵向菜单的实现

clipboard.png

//设置盒子大小不因为boder变化
.pure-menu {
    box-sizing: border-box;
}
//清除列表原有样式
.pure-menu-list{
    list-style: none;
    margin: 0;
    padding: 0;    
} 
//清除a标签原有样式,填充a标签,并变为块级元素
.pure-menu-link{
    display: block;
    text-decoration: none;
    white-space: nowrap;
    color: #777;
    padding: .5em 1em;    
}
//在父级元素使用inline-block将之变为行级元素并同一高度
.custom-restricted-width {
    /* To limit the menu width to the content of the menu: */
    display: inline-block;
    /* Or set the width explicitly: */
    /* width: 10em; */
}
//添加:hover,:link等样式
.pure-menu-link:hover,
.pure-menu-link:focus {
    background-color: #eee;
}

疑问之处:

inline-block怎样自动确定并统一行级元素的宽度

横向菜单的实现

![clipboard.png](/img/bVNrDC)

.pure-menu-heading{
  padding: .5em 1em;
  display: block;
  text-decoration: none;
  white-space: nowrap;
  text-transform: uppercase;
  color: #565d64;
}
//给a标签的父级标签li标签添加display:inline-block,使三个a标签同行
.pure-menu-horizontal .pure-menu-item,
.pure-menu-horizontal .pure-menu-heading,
.pure-menu-horizontal .pure-menu-separator {
    display: inline-block;
    *display: inline;
    zoom: 1;
    vertical-align: middle;
}
//为li的父级ul标签添加display:inline-block,使所有标签同行
.pure-menu-horizontal .pure-menu-list {
    display: inline-block;
}
//清除列表原有样式,统一间距
.pure-menu-list{
    list-style: none;
    margin: 0;
    padding: 0;    
} 

关键样式

  • 清除列表原有样式

  • 使用padding: .5em 1em填充a标签

  • 清除a标签原有样式

  • 为a标签的父级标签li标签添加display:inline-block,使三个a标签同行

  • 为标题的a标签和li的父级ul标签添加display:inline-block,使所有标签同行

  • 为ul标签添加margin:0和padding:0清除ul原有样式

含有子菜单的横向菜单的实现


clipboard.png

//样式整合
.pure-menu-link{
    display: block;
    text-decoration: none;
    white-space: nowrap;
    //可自定义部分
    color: #777;
    padding: .5em 1em;    
}
.pure-menu-list{
    list-style: none;
    margin: 0;
    padding: 0;    
}     
//实现横向菜单
.pure-menu-horizontal .pure-menu-list{
    display: inline-block;
}    
//实现下拉菜单符号
.pure-menu-horizontal .pure-menu-has-child > .pure-menu-lin:after{
    content: "\25BE";
}
//子菜单的样式
.pure-menu-children{
    display: none;
    position: absolute;
    left: 100%;
    top:0;
    margin: 0;
    padding: 0;
    z-index: 3;
    background-color: #fff;
}
//鼠标移动显示下拉菜单
.pure-menu-allow-hover:hover > .pure-menu-child{
    display: block;
    position: absolute;
}
//子菜单移动至下方
.pure-menu-horizontal .pure-menu-children {
    left: 0;
    top: auto;
    width: inherit;
}    

content属性与:before和:after伪元素配合使用,来插入生成内容

特殊字符对应号码
9658 25BA
9650 25B2
9660 25BC
9668 25C4

含有子菜单的纵向菜单的实现


menu-has-children > .pure-menu-link:after {
    padding-left: 0.5em;
    content: "\25B8";
    font-size: small;
}
//显示隐藏的子元素
.pure-menu-allow-hover:hover > .pure-menu-children{
    display: block;
    position: absolute;
}

滚动菜单的实现

clipboard.png

//限制了边框才显示滚动条
.custom-restricted {
    height: 160px;
    width: 150px;
    border: 1px solid gray;
    border-radius: 4px;
}
//y轴可滚动,x轴溢出隐藏
.pure-menu-scrollable {
    overflow-y: scroll;
    overflow-x: hidden;
}
//将li标签设为块级元素
.pure-menu-scrollable .pure-menu-list {
    display: block;
}
//水平菜单时,显示为行级元素
.pure-menu-horizontal.pure-menu-scrollable .pure-menu-list {
    display: inline-block;
}
//水平菜单针对的只是移动端,触摸横向滚动
.pure-menu-horizontal.pure-menu-scrollable {
    white-space: nowrap;
    overflow-y: hidden;
    overflow-x: auto;
  
   //指示元素不显示滚动条或者筛选指标,即使内容溢出
    -ms-overflow-style: none;
  
   //可以让页面在native端滚动时模拟原生的弹性滚动
    -webkit-overflow-scrolling: touch;
    /* a little extra padding for this style to allow for scrollbars */
    padding: .5em 0;
}
//存在疑问
.pure-menu-horizontal .pure-menu-scrollable::-webkit-scrollbar {
    display: none;
}
查看原文

飘雪的浮云 赞了文章 · 2020-09-27

pure.css框架源码详细解析

一篇文章包你学会使用pure.css框架,理解其原理,并学会其包含css知识,学会自己写css组件

前提知识

选择器介绍


优先级就是分配给指定css声明的一个权重,它由匹配的选择器中的每一种选择器类型的数值决定。而当优先级与多个css声明中任何一个声明的优先级相等时,css中最后的那个声明将会被应用到元素上。

  • 选择器是用于定位文档中的元素以便设定相应的样式代码

  • 选择器分类

基础选择器

选择器含义实例
*通用选择器,匹配任何元素*{font-size:16px}
E标签选择器,匹配所有使用E标签的元素a{font-size:16px}
.errorclass选择器,匹配所有class属性中包含error的元素.error{font-weight:bold;}
#correctid选择器,匹配所有id属性值为correct的元素#correct{font-style:italic;}

​ 组合选择器

选择器含义实例
E,F多元素选择器,同时匹配所有E元素或F元素div,p{background-attachment:fixed;}
E F后代元素选择器,匹配所有属于E元素的后代F元素div a{background-color:blue;}
E>F子元素选择器,匹配所有E元素的子元素F
E+F毗邻元素选择器,匹配所有紧随E元素之后的同级元素F

属性选择器

选择器含义实例
E[att]匹配所有具有att属性的E元素p[style]{background-repeatrepeat-y;}
E[att=val]匹配所有att属性等于"val"的E元素div[class="c1"]
E[att~=val]匹配所有att属性具有多个空格分隔的值、其中一个值等于"val"的E元素div[class~=c2]
E[att=val]匹配所有att属性具有多个连字号分隔(hyphen-separated)的值、其中一个值以"val"开头的E元素p[lang =en]

​ 伪类选择器

选择器含义实例
E:first-child匹配父元素E下的第一个子元素div:first-child{text-align:center;}
E:link匹配所有未被点击的链接
E:visited匹配所有已被点击的链接
E:active匹配鼠标悬停其上的E元素
E:hover匹配鼠标悬停其上的E元素
E:focus匹配获得焦点的E
E:lang(c)匹配lang属性等于c的E元素

​ 伪元素

选择器含义实例
E:first-line匹配E元素的第一行p:first-line{color:red;}
E:first-letter匹配E元素的第一个字母.c1:first-letter{color:blue;}
E:before在E元素之前插入生成的内容.ctn before{}
E:after在E元素之后插入生成的内容.ctn after{}

优先级的计算


(解释了众多css样式被覆盖的问题)

首先!important的css定义是拥有最高的优先级

优先级计算分为a,b,c,d四个位数,这四个位数的优先级依次递减。

内联样式:a=1;

ID选择器:b=1;

属性选择器和类选择器:c=1;

元素选择器和伪类选择器: d=1;

li            {}  /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
li:first-line {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul li         {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul ol+li      {}  /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
h1 + *[rel=up]{}  /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
ul ol li.red  {}  /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
li.red.level  {}  /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
#x34y         {}  /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
style=""          /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

文档流


(主要应用于menu中,垂直和水平导航栏)

css文档流(document flow)和普通流(normal flow)实际上指的是同一个概念。

文档流 指的是元素按照在HTML中为的位置顺序决定排布的过程,在排布过程中,将窗体自上而下分为一行行,并在每行中从左至右的顺序排放元素。

非浮动的块级元素(block)独占一行,行内元素(inline)不会独占一行。

块级元素的效果

<div style=" width:100px; height:100px; border: 1px solid">div1</div>
<div style=" width:100px; height:100px; border: 1px solid">div2</div>

%E5%9D%97%E7%BA%A7%E5%85%83%E7%B4%A0_ogskld.png

内联元素的效果

<a href="http:">超链接1</a>
<a href="http:">超链接2</a>

%E5%86%85%E8%81%94_by35cr.png

绝对定位


(主要是用于含有重叠菜单的子菜单定位问题)

绝对定位其实是相对了某个东西的,而这个东西就是元素的第一个有position且position不能为static的祖先元素。就是这个东西必须是有一定地位的(position:absolute或position:relative),不能是一个穷鬼(position:static)或者没有地位的(position).这个时候,绝对定位,它才能以之为标杆。

给他爸爸加上相对定位,然后他是绝对定位

  <div style=" border:1px solid Red; padding:10px; width: 340px; height: 400px"">
    红色:太公
        <div style="border:1px solid Green; padding:10px; width: 320px; height: 360px;">
        绿色:爷爷
            <div style="border:1px solid Yellow; padding:10px; width: 300px; height: 320px;position:relative; ">
            黄色:老爸
                <div style="width: 100px; height: 100px;border:1px solid">
                    div1</div>
                <div style="width: 100px; height: 100px;border:1px solid;position:absolute;left:120px; top:100px;">
                    div2</div>
                <div style="width: 100px; height: 100px;border:1px solid">
                    div3</div>
            </div>
        </div>
    </div>

%E7%9B%B8%E5%AF%B92_tsb9ms.png

基础

所有pure模块都是基于normalize.css构建,对比base.css详细normalize.css内容请查看《Normalize.css》

<link rel="stylesheet" href="https://unpkg.com/purecss@0.6.1/build/base-min.css">

Normalize.css是一个小的CSS文件,为HTML元素样式提供跨浏览器的一致性。它是一个现代的、支持HTML5的、传统CSS重置的替代。

html {
  font-family: sans-serif; /* 1 */
  //无衬线体,字的比划开始及结束地方没有额外装饰
  -ms-text-size-adjust: 100%; /* 2 */
  -webkit-text-size-adjust: 100%; /* 2 */
  //iPhone 和 Android 的浏览器纵向 (Portrate mode) 和橫向 (Landscape mode) 模式皆有自动调整字体大小的功能。控制它的就是 CSS 中的 -webkit-text-size-adjust。text-size-adjust 设为 none 或者 100% 关闭字体大小自动调整功能.
}
abbr[title] {
  border-bottom: 1px dotted;
}
//缩略词显示详情,含有title属性的abbr标签缩略词的底部边线

abbr_wmhguu.png

svg:not(:root){
  overflow: hidden;
}
//svg(可缩放矢量图形),是基于可扩展标记语言(XML),用于描述二维矢量图形
:root,匹配文档的根元素,在HTML中,根元素永远是HTML
:not(selector)选择器匹配非指定元素
则以上是svg非根元素的元素

隐藏元素


[hidden],
template {
//template模板标签
  display: none;
}
.hidden,
[hidden] {
//!important最高优先级
    display: none !important;
}

html元素添加hidden属性,可以实现display:none !important;

<input type="text" name="_csrf" hidden>

响应式图片


<img>添加class .pure-img,配合viewport可以实现图片伸缩

.pure-img {
//最小宽度(min-width)与最大宽度(max-width)用于设置图片最小最大宽度限制比较多。
比如一个图片为主列表,对象里图片大小不定时候,为了不想让他太小不统一这个时候我们可以使用css最小宽度样式。再如,一个盒子里有文章有图片混排的时候,有时图片宽度不能确定,这个时候如果html img图片宽度超出了盒子宽度,可能图片就会撑破div盒子造成图片混乱。
    max-width: 100%;
    height: auto;
    display: block;
}

max-width详细情况可以查看《CSS max-width 属性》

<img class="pure-img" data-original="...">

栅格

.pure-g的样式


letter-spacing: -0.31em;

1em == 16px,因为浏览器默认的字体大小是16px,em可以在浏览器改变字体大小时作出相应的放大和缩小,弹性布局

*word-spacing: -0.43em

在样式属性名前加*,这样的样式可以被IE6和IE7所识别,而其它浏览器则会当做错误忽略,所以,这样的样式写法只对IE6/7生效.
而_开头的属性只有IE6才能识别.

关于letter-spacing和word-spacing的区别

图片描述

word-spacing属性增加或减少单词之间的空白

letter-spacing属性增加或减少字符之间的空白

text-rendering: optimizespeed;

text-rendering属性常被用在windows和linux系统中,用来给渲染引擎提供信息,让文本在速度和可读性方面得到优化,控制在线字体的微妙细节,目前只有firefos和google支持。

optimizespeed取值 Gecko内核的浏览器将强调可读性和几何精度,同时绘制文本渲染速度,禁用字距和连写

font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;

常用的字体

display: -webkit-box;/ Chrome 4+, Safari 3.1, iOS Safari 3.2+ /

display: -webkit-flex;/ Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 /

display: -ms-flexbox;/ IE 10 /

display: flex; / Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ /

webkit是一个开源的浏览器引擎,与之对应的有Gecko和Trident,加上之后表示私有属性

-moz代表firefox浏览器私有属性
-ms代表IE浏览器私有属性
-webkit代表chrome、safari私有属性

关于display:box和display:flex的区别

flex是2012年以后的标准语法,大部分浏览器已经实现了无前缀版本,box是2009年语法,需要加上前缀

以上其实是该属性的兼容性代码

flex布局,弹性布局,用来为盒装模型提供最大的灵活性
图片描述

通过添加.pure-g和未添加进行对比,可以发现,.pure-g的效果主要就是flex属性,而flex属性在此处的重要作用是给.pure-u元素添加float浮动属性

-webkit-flex-flow: row wrap;

-ms-flex-flow: row wrap;

flex-flow: row wrap;

flex-flow:<flex-direction>||<flex-wrap>

row表示行内方向,即弹性项目在弹性容器中的起始放置方向,flex-wrap表示需要拆行以使得弹性项目能被容器包含

-webkit-align-content: flex-start;

-ms-flex-line-pack: start;

align-content: flex-start;

多行项目时,让弹性元素始终排在头部,中间没有间距,详细flex教程请查看《Flex布局教程:语法篇》

@media all and (min-width:xxx) and (max-width:xxx){   
/*这段查询的all是针对所有设备(有些设备不一定是屏幕,也许是打字机,盲人阅读器)*/ 
        table .pure-g {
        display: block;
    }
}   

写这一行是因为flex在ie10中的table时不起作用

.pure-g [class *= "pure-u"] {font-family: sans-serif;}

表示的是设置class属性值包含有pure-u 字符串的所有pure-g元素的样式

div[class^="something"] { }表示以之开始
div[class$="something"] { }表示以之结尾

.pure-u的样式


.pure-u {
display: inline-block;
*display: inline; /* IE < 8: fake inline-block */
zoom: 1;
letter-spacing: normal;
word-spacing: normal;
vertical-align: top;
text-rendering: auto;
}

zoom: normal | <number> | <percentage>

​ normal:使用对象的实际尺寸

​ <number>:用浮点数来定义缩放比例

​ <percentage>:用百分比来定义缩放比例

vertical-align垂直对齐属性

.pure-u-x-y{
     display: inline-block;
    *display: inline;
    zoom: 1;
    letter-spacing: normal;
    word-spacing: normal;
    vertical-align: top;
    text-rendering: auto;
}

这个样式和.pure-u是相同的

pure栅格默认支持5列和24列

x/y表示的是列数所占的比重

.pure-u-1-24 {
    width: 4.1667%;
    *width: 4.1357%;
}

可以发现IE67和其他浏览器之间的宽度存在细微差别,微调后可修复

图片描述

表单

.pure-form样式


.pure-form input[type="text"]

不同的表单类型

    padding: 0.5em 0.6em;
    //设置表单内部填充
    display: inline-block;
    //显示为行内元素
    border: 1px solid #ccc;
    //边界线
    box-shadow: inset 0 1px 3px #ddd;
    //盒子阴影,inset设置在内边框
    border-radius: 4px;
    //圆框边角
    vertical-align: middle;
    //让行内元素居中显示,主要是表单
    box-sizing: border-box;
    //设置盒子尺寸

input:not([type]) //这个属性需要分离出来,因为ie8在一堆css2.1中包含一个css3属性的时候不会执行

:not()否定选择器,可以让你定位不该匹配该选择器的元素,IE6-8浏览器不支持:not()选择器

.pure-form input[type="color"]{

​ padding: 0.2em 0.5em;

} //chrome显示色彩选择器需要额外的空间

input[type="text"]:focus {

outline:0;

border-color:#129FEA;

}

为聚焦的时候添加样式

outline和boder区别

outline是不占空间的,既不会增加额外的width或者height

图片描述

border可应用于几乎所有有形的html元素,而outline是针对链接、表单控件和imageMap等元素,outline会随元素focus出现,随blur而消失

图片描述

详细的情况可以查看《深入浅析border和outline区别》

input[type="text"][disabled]
input[readonly]

这两种写法都会使显示出来的文本框不能输入文字

但disabled会使文本框变灰,而且通过request.getParameter("name")得不到文本框中的内容(如果有的话)

而readonly只是使文本框不能输入,外观没有变化,而且通过request.getParameter("name")可以得到内容,可以复制

input:focus:invalid

同类型的方法

:required必须,要求input不能为空

:valid有效,即当填写内容符合要求时触发

:invalid无效,即当填写内容不符合要求时触发

图片描述

可以看到符合要求时,显示的边框颜色为蓝,右边的没有添加:focus选择器的表单在无效的时候一直都是红色

疑问:

input:focus:invalid和input:focus:invalid:focus差别并没有试验出来

.pure-form fieldset

.pure-form legend

fieldset和legend标签的组合使用

图片描述

实现的手段是添加border:0和border-bottom

.pure-form-stacked样式


可以生成堆叠式表单,即为同一列

图片描述

实现的手段是添加display:block将它变成块级元素,独占整行和margin: 0.25em 0;

.pure-form-aligned样式


clipboard.png

可以生成对齐式表单,label显示在input左边末端对齐
nline-block显示成行内元素,然后设置width使之可以撑满,再设置text-align:right使之向右对齐,此时与表单过于靠近,添加margin属性,使和表单之间间距变大。考虑到字数过长产生换行,使用vertical-align让行内元素居中显示

.pure-group样式


可以为表单标签分组,使用方法是为fieldset添加该class

clipboard.png

区别不大,主要是阴影部分,以及结束部分相连r-radius:0将圆角样式去除,然后使用:first-child和:last-child选择器,重新设置这两个元素的圆角等样式,达到此效果

.pure-form .pure-group input:first-child:last-child

通过伪类选择器设置第一个和最后一个同类标签的样式

.pure-form .pure-input-2-3

设置表单大小

按钮

.pure-button样式


    //这个样式应该主要是运用在移动端
    display: inline-block;
    //行内元素
    zoom: 1;
    //缩放比例
    line-height: normal;
    //默认行高
    white-space: nowrap;
    //如何处理元素内的空白,normal空白会被浏览器忽略,nowrap文本不会换行
    vertical-align: middle;
    //实现行内元素的水平居中
    text-align: center;
    //使文本水平居中
    cursor: pointer;
    -webkit-user-drag: none;
    //user-drag:auto | element | none设置和检索一个元素能否被拖拽
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    //user-select:none | text | all | element设置和检索是否允许选中文本
    box-sizing: border-box;
    //设置的内边距和边框不会增加宽度
//网页端主要样式
.pure-button {
    font-family: inherit;
    font-size: 100%;
    padding: 0.5em 1em;
    color: #444; /* rgba not supported (IE 8) */
    color: rgba(0, 0, 0, 0.80); /* rgba supported */
    border: 1px solid #999;  /*IE 6/7/8*/ 
    border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/
    background-color: #E6E6E6;
    text-decoration: none;
    border-radius: 2px;
}

伪类选择器样式


//设置鼠标在上和焦点在上时的样式
.pure-button-hover,
.pure-button:hover,
.pure-button:focus {
    /* csslint ignore:start */
    filter: alpha(opacity=90);
    //透明度使用
    /* csslint ignore:end */
    background-image: -webkit-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
    background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
}
//用线性渐变创建图像 rgba(0,0,0, 0.05) 40%和rgba(0,0,0, 0.10));分别为起始颜色和终止颜色,第一个参数一般是渐变方向,top 是从上到下、left 是从左到右,如果定义成 left top,那就是从左上角到右下角

clipboard.png

线性渐变

linear-gradient([ [<angle>|to<side-or-cornor>],]?<color-stop>[,<color-stop>]+)

<color-stop> 用于指定渐变的起止颜色

详细情况可以查看《css参考手册》.htm)

疑问:

background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));

transparent这个参数的作用和效果

表格

.pure-table的样式


.pure-table {
    /* Remove spacing between table cells (from Normalize.css) */
    border-collapse: collapse;
    //为表格设置合并边框模型
    //collapse边框会合并成一个单一边框,忽略border-spacing和empty-cells属性,而separate会使边框分开,inherit规定应该从父元素继承border-collapse属性
    border-spacing: 0;
    //设置相邻单元格边框间的距离,不过仅用于边框分离模式
    empty-cells: show;
    //设置是否显示表格中的空单元格,仅适用于边框分离模式
    border: 1px solid #cbcbcb;
}

clipboard.png

.pure-table caption表格标题

.pure-table td,.pure-table th,.pure-table thead

th:表头单元格-包含表头信息

td: 标准单元格-包含数据

thead:结合tbody和tfoot元素结合使用

.pure-table-odd td{

​ background-color: #f2f2f2;

}

隔行添加可以实现斑马纹的效果或者直接加上pure-table-striped

clipboard.png

.pure-table-striped tr:nth-child(2n-1) td{

​ background-color: #f2f2f2;

}

:nth-child(n)选择器 规定属于其父元素的第n格子元素,不论元素类型

:nth-of-type() 选择器的意思是“规定属于其父元素的第二个 p 元素”,这个需要从同类元素开始机选

.pure-table-bordered tbody > tr:last-child > td

有边框的表格,>选择器,可以缩小范围,只选择某个元素的子元素

菜单

.pure-menu的样式


纵向菜单的实现

clipboard.png

//设置盒子大小不因为boder变化
.pure-menu {
    box-sizing: border-box;
}
//清除列表原有样式
.pure-menu-list{
    list-style: none;
    margin: 0;
    padding: 0;    
} 
//清除a标签原有样式,填充a标签,并变为块级元素
.pure-menu-link{
    display: block;
    text-decoration: none;
    white-space: nowrap;
    color: #777;
    padding: .5em 1em;    
}
//在父级元素使用inline-block将之变为行级元素并同一高度
.custom-restricted-width {
    /* To limit the menu width to the content of the menu: */
    display: inline-block;
    /* Or set the width explicitly: */
    /* width: 10em; */
}
//添加:hover,:link等样式
.pure-menu-link:hover,
.pure-menu-link:focus {
    background-color: #eee;
}

疑问之处:

inline-block怎样自动确定并统一行级元素的宽度

横向菜单的实现

![clipboard.png](/img/bVNrDC)

.pure-menu-heading{
  padding: .5em 1em;
  display: block;
  text-decoration: none;
  white-space: nowrap;
  text-transform: uppercase;
  color: #565d64;
}
//给a标签的父级标签li标签添加display:inline-block,使三个a标签同行
.pure-menu-horizontal .pure-menu-item,
.pure-menu-horizontal .pure-menu-heading,
.pure-menu-horizontal .pure-menu-separator {
    display: inline-block;
    *display: inline;
    zoom: 1;
    vertical-align: middle;
}
//为li的父级ul标签添加display:inline-block,使所有标签同行
.pure-menu-horizontal .pure-menu-list {
    display: inline-block;
}
//清除列表原有样式,统一间距
.pure-menu-list{
    list-style: none;
    margin: 0;
    padding: 0;    
} 

关键样式

  • 清除列表原有样式

  • 使用padding: .5em 1em填充a标签

  • 清除a标签原有样式

  • 为a标签的父级标签li标签添加display:inline-block,使三个a标签同行

  • 为标题的a标签和li的父级ul标签添加display:inline-block,使所有标签同行

  • 为ul标签添加margin:0和padding:0清除ul原有样式

含有子菜单的横向菜单的实现


clipboard.png

//样式整合
.pure-menu-link{
    display: block;
    text-decoration: none;
    white-space: nowrap;
    //可自定义部分
    color: #777;
    padding: .5em 1em;    
}
.pure-menu-list{
    list-style: none;
    margin: 0;
    padding: 0;    
}     
//实现横向菜单
.pure-menu-horizontal .pure-menu-list{
    display: inline-block;
}    
//实现下拉菜单符号
.pure-menu-horizontal .pure-menu-has-child > .pure-menu-lin:after{
    content: "\25BE";
}
//子菜单的样式
.pure-menu-children{
    display: none;
    position: absolute;
    left: 100%;
    top:0;
    margin: 0;
    padding: 0;
    z-index: 3;
    background-color: #fff;
}
//鼠标移动显示下拉菜单
.pure-menu-allow-hover:hover > .pure-menu-child{
    display: block;
    position: absolute;
}
//子菜单移动至下方
.pure-menu-horizontal .pure-menu-children {
    left: 0;
    top: auto;
    width: inherit;
}    

content属性与:before和:after伪元素配合使用,来插入生成内容

特殊字符对应号码
9658 25BA
9650 25B2
9660 25BC
9668 25C4

含有子菜单的纵向菜单的实现


menu-has-children > .pure-menu-link:after {
    padding-left: 0.5em;
    content: "\25B8";
    font-size: small;
}
//显示隐藏的子元素
.pure-menu-allow-hover:hover > .pure-menu-children{
    display: block;
    position: absolute;
}

滚动菜单的实现

clipboard.png

//限制了边框才显示滚动条
.custom-restricted {
    height: 160px;
    width: 150px;
    border: 1px solid gray;
    border-radius: 4px;
}
//y轴可滚动,x轴溢出隐藏
.pure-menu-scrollable {
    overflow-y: scroll;
    overflow-x: hidden;
}
//将li标签设为块级元素
.pure-menu-scrollable .pure-menu-list {
    display: block;
}
//水平菜单时,显示为行级元素
.pure-menu-horizontal.pure-menu-scrollable .pure-menu-list {
    display: inline-block;
}
//水平菜单针对的只是移动端,触摸横向滚动
.pure-menu-horizontal.pure-menu-scrollable {
    white-space: nowrap;
    overflow-y: hidden;
    overflow-x: auto;
  
   //指示元素不显示滚动条或者筛选指标,即使内容溢出
    -ms-overflow-style: none;
  
   //可以让页面在native端滚动时模拟原生的弹性滚动
    -webkit-overflow-scrolling: touch;
    /* a little extra padding for this style to allow for scrollbars */
    padding: .5em 0;
}
//存在疑问
.pure-menu-horizontal .pure-menu-scrollable::-webkit-scrollbar {
    display: none;
}
查看原文

赞 7 收藏 8 评论 1

飘雪的浮云 回答了问题 · 2020-09-12

写了一个基于flask的web应用程序,通过前端获取url下载某网站的视频,如何让浏览器下载,并让用户选择保存的路径?

页面用一个按钮,按钮跳转视频下载地址就可以了。
把后端获取到的视频下载地址返回给模板页面内中,然后用a标签渲染在那个按钮里。。

关注 2 回答 1

飘雪的浮云 回答了问题 · 2020-09-12

flask的修改,在云服务器重启服务才能更新?

这个需要贴出来nginx和wsgi的配置才可以定位问题。
如果配置正常,可以实现保存代码时自动重启flask服务。

关注 2 回答 1

飘雪的浮云 回答了问题 · 2020-09-12

云服务器的使用

在阿里云上传图片到华为云,这个也是要占带宽的。
华为云的机子可以做热备机,实现多机房双机热备。

关注 2 回答 3

飘雪的浮云 回答了问题 · 2020-09-12

Flask多个Post,@api.route('/')正常,('/analysis/orderstruct')只有key

你代码里路由写的是

/analysis/orderstruct/

修改一下请求的接口地址试试

关注 2 回答 1

飘雪的浮云 发布了文章 · 2020-09-11

debian10 更新apt-get源

debian版本

执行以下命令,查看当前debian版本号:

cat /etc/issue

结果如下:

root@l:~# cat /etc/issue
Debian GNU/Linux 10 \n \l

更新源

备份sources.list文件:

mv /etc/apt/sources.list /etc/apt/sources.list.bak

修改sources.list文件内容,删除默认的内容,改成国内源:

deb http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib
deb http://mirrors.aliyun.com/debian-security/ buster/updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian-security/ buster/updates main non-free contrib

然后执行更新命令:

apt-get update
apt-get upgrade
查看原文

赞 0 收藏 0 评论 0

认证与成就

  • 获得 8 次点赞
  • 获得 14 枚徽章 获得 1 枚金徽章, 获得 3 枚银徽章, 获得 10 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2013-10-21
个人主页被 977 人浏览