Web前端实战经验(CSS及页面布局)


float及image问题

<img>元素默认情况下底部会有空白,这样会导致页面排版时出现错乱问题。
代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bug问题汇总</title>
<style type="text/css">
*{margin: 0;padding: 0}
.wrap{margin: 0 auto;width: 1000px;}
.top{height: 80px;background-color: #fff;}
.top-left{float: left;width: 200px;background: grey}
.top-right{width:800px;height: 80px; float: right;}
.mid{width: 1000px;height:40px;background-color: yellow;}
.mid p{float: left;width: 300px;}
.mid div{width: 800px}
</style>

</head>
<body>
<div class="wrap">
<div class="top">
<div class="top-left">
<img src="logo.jpg" >
</div>
<div class="top-right"></div>
</div>
<div class="mid">
<p>我是大明星</p>
<div>我是大明星</div>
</div>
</div>
</body>
</html>

页面布局图如下:
bug分析
分析:div.top-left这个div元素的尺寸为:20080px;
图片logo.jpg尺寸为200
80px.
但实际上div.top-left这个div元素的尺寸为:200*83px;

原因分析:
img作为内联元素,会和文字一样具有行高和字号属性,默认对齐baseline,因此会溢出,导致p元素排版混乱。

inline 的图片下面那一道空白(3px左右)正是 baseline 和 bottom 之间的这段距离。即使只有图片没有文字,只要是 inline 的图片这段空白都会存在。
要去掉这段空白,最直接的办法是将图片的 vertical-align 设置为其他值。

解法方法:

  1. 对img元素进行设置,二选一皆可。
    img { display:block; }
    img { vertical-align:top/bottom/middle; }
  2. 对.top这个div元素设置overflow:hidden;或是对.mid这个div元素设置clear:both皆可。
  3. 对img元素的父元素设置line-height:0(在没有设置 line-height 的情况下把 font-size 设为0也可以达到同样的效果。)

参考资源:
https://www.zhihu.com/question/21558138

图片水平垂直居中于DIV

问题:如何实现一张未知宽高的图片在一个Div里面水平垂直居中呢?
解决方法:(三种方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片</title>
<style>
.box{width: 200px; height: 200px;border: solid 1px red;text-align: center;}
.box1 i{display: inline-block;vertical-align: middle;height: 100%;}
.box1 img{ vertical-align: middle;}

.box2{display: table;}
.box2 a{display:table-cell;vertical-align:middle;}
.box2 img{vertical-align: middle;}

.box3{position: relative;}
.box3 img{position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);}
</style>

</head>
<body>
<div class=" box box1">
<i></i><img src="http://img.mukewang.com/user/53796b7f0001d38801200120-40-40.jpg" alt="">
</div>
<div class="box box2">
<a href=""><img src="http://img.mukewang.com/user/53796b7f0001d38801200120-40-40.jpg" alt=""></a>
</div>
<div class="box box3">
<img src="http://img.mukewang.com/user/53796b7f0001d38801200120-40-40.jpg" alt="">
</div>
</body>
</html>

第4种方法:flex伸缩布局:

1
2
3
4
5
.parent{
display:flex;
justify-content:center;
align-items:center;
}

扩展阅读:垂直居中任何元素:https://css-tricks.com/centering-css-complete-guide/

纯CSS绘制三角形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//正三角:
#triangle-up {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
或者:
.triangle{
width: 0;
height: 0;
border: 50px solid transparent;
border-bottom: 100px solid red;
}
下面的也能绘制三角形,但不是正三角。
.triangle{
width: 0;
height: 0;
border: 100px solid transparent;
border-bottom-color:red;
}
//倒三角:
#triangle-down {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 100px solid red;
}
//左三角
#triangle-left {
width: 0;
height: 0;
border-top: 50px solid transparent;
border-right: 100px solid red;
border-bottom: 50px solid transparent;
}
//右三角
#triangle-right {
width: 0;
height: 0;
border-top: 50px solid transparent;
border-left: 100px solid red;
border-bottom: 50px solid transparent;
}
//左上三角:
#triangle-topleft {
width: 0;
height: 0;
border-top: 100px solid red;
border-right: 100px solid transparent;
}

更多纯CSS实现图形案例:https://css-tricks.com/examples/ShapesOfCSS/

line-height与font-size的关系

对于P元素,当文字超出一行时,决定每行之间的间隙的css是line-height和font-size
解释:P元素中有两行文字,每一行是一个inlineBox,其高对应的css是line-height。在inlineBox里有一个区域叫做contentArea,这里显示的是文字,其高对应的css是font-size。
浏览器自动将contentArea区域设置在inlineBox区域的垂直居中位置。
所以,当inlineBox的高大于contentArea的高,在视图里展现的样子是两行文字之间有一定的间隙,间隙的大小取决于两者高度的差值。

css属性中line-height继承问题。

当在css中要继承父元素的line-height时,有几种写法:
1、px
2、%
3、num
4、normal(1.2)
px 当在父元素上使用px时,其子元素都会不顾自己的font-size而继承px的确切值。
这样造成的影响是子元素的inlineBox的高度都是相同,而子元素的font-size不同的话就会造成各个文字区块的行间距不同,影响美观。
%是将此时元素的font-size乘以%得到现有的line-hight,同px,子元素继承固定值。
normal相当于数字1.2 ,子元素同样继承固定的line-height。
num子元素只继承num这个数值,但具体line-height数值会跟每个子元素的自身font-size相乘得出line-height。

element font-size line-height after line-height
body 14 1.2 28px
p 30 1.2 36
h1 24 1.2 28

这样的效果是每个文字区块中的文字段落的行间距都是根据自己的font-size得出的,整体文字排版的行间距很统一。

宽度设置100%或固定值(比如960px),窗口缩小出现bug(底部出现横向的滚动条,但看起来内容并没有超出。)

有时候我们想让页面导航能100%在窗口中显示,页面主内容设置固定宽度如960px,窗口全屏的情况下能正常显示,但缩小窗口的时候我们发现,右边会出现一片空白,即导航的宽度小于主内容的宽度,导航并没有100%显示。

解决方法:
div元素中添加:

1
2
min-width:1000px;
width: expression((document.documentElement.clientWidth||document.body.clientWidth)<1000?"1000px":""); //IE6兼容方案

另一种方法:
宽度设置max-width,比如:
max-width:960px.
当浏览器窗口缩小时,会自动调整宽度值,从而避免滚动条出现。

参考链接:http://vod.sjtu.edu.cn/help/Article_Show.asp?ArticleID=2224

使用 :not() 选择器来决定表单是否显示边框/列表最后一个元素是否加边框

与其加上边框……

1
2
3
4
/* 添加边框 */
.nav li {
border-right: 1px solid #666;
}

……然后去掉最后一个元素的边框……

1
2
3
4
/* 去掉边框 */
.nav li:last-child {
border-right: none;
}

……不如使用 :not() 伪类来达成同样的效果:

1
2
3
.nav li:not(:last-child) {
border-right: 1px solid #666;
}

当然,也可以使用 .nav li + li 或者 .nav li:first-child ~ li 来达成,但是 :not() 选择器的方式更清晰明了,一目了然。

使用负的 nth-child 来选择元素

使用负的 nth-child 可以选择 1 至 n 个元素。

1
2
3
4
5
6
7
8
li {
display: none;
}

/* 选择第 1 至第 3 个元素并显示出来 */
li:nth-child(-n+3) {
display: block;
}

或许你已经掌握了如何使用 :not(),试下这个:

1
2
3
4
/* 选择第 1 至第 3 个元素并显示出来 */
li:not(:nth-child(-n+3)) {
display: none;
}

用 rem 来调整全局大小;用 em 来调整局部大小

在根设置基本字体大小后 (html { font-size: 16px; }), 请设置为文本元素的字体大小 em:

1
2
3
4
5
6
7
h2 { 
font-size: 2em;
}

p {
font-size: 1em;
}

然后设置字体大小的模块 rem:

1
2
3
4
5
6
7
article {
font-size: 1.25rem;
}

aside .module {
font-size: .9rem;
}

现在,每个模块变得条块分割,更容易、灵活的样式,以便于维护。

rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。
em(font size of the element)是指相对于父元素的字体大小的单位。
它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。

多行文本溢出

单行文本溢出

1
2
3
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;

多行文本溢出

1、WebKit浏览器或移动端的页面
在WebKit浏览器或移动端(绝大部分是WebKit内核的浏览器)的页面实现比较简单,可以直接使用WebKit的CSS扩展属性(WebKit是私有属性)-webkit-line-clamp 。
-webkit-line-clamp用来限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他的WebKit属性。
常见结合属性:

  • display: -webkit-box; 必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。
  • -webkit-box-orient 必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 。
  • text-overflow:ellipsis;,可以用来多行文本的情况下,用省略号“…”隐藏超出范围的文本 。
    1
    2
    3
    4
    5
    6
    display: -webkit-box !important;
    overflow: hidden;
    text-overflow: ellipsis;

    -webkit-box-orient: vertical; // 方向垂直
    -webkit-line-clamp: 2; // 自动截断显示2行

2、跨浏览器兼容的方案:
设置相对定位的容器高度,用包含省略号(…)的元素模拟实现;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.tab-paragraph {
position: relative;
line-height: 1.4em;
height: 4.2em;//高度=行高*行数
overflow: hidden;
.tab-paragraph::after {
content: "...";
position: absolute;
bottom: 0;
right: 0;
font-weight: 600;
padding: 0 1px 1px 5px;
background: linear-gradient(to right,transparent,#fff 55%);
}

参考链接:多行文本溢出显示省略号(…)全攻略

坚持原创技术分享,您的支持将鼓励我继续创作!