1. 开发目标
图片新闻是门户网站最能吸引用户眼球的内容之一。许多栏目都有大量的图文内容需要展示,比如明星八卦、体育竞技、数码科技等。本文将通过实现一个图片新闻栏目来继续探讨内容布局以及CSS 3的动画效果。
当鼠标悬停在图片上时,图片显示放大的动画。
2. 结构分析
这是一个处于浏览器水平居中,宽度为960像素的模块,一共包含5篇图文内容。其中第一个图片的大小为480x241像素,其它为238x120像素。大图位于整个模块的左半部,其余4张图片呈田字格显示在模块右侧。每篇文章都有一个叠放在图片上的标题,标题背景为渐变色,增加标题的对比度。
根据上面的描述,我们用一个模块容器div
来实现整体内容宽度和居中。由于图片很明显的分成左右两个部分,最直观的做法是将5篇新闻分成左右两组。为了加深对CSS选择器的理解和使用,我们只用一个包含所有5张图片的无序列表。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片新闻列表</title>
</head>
<body>
<div class="container">
<ul class="slide">
<li class="slide-item">
<img class="slide-img" src="assets/image/zgnl_1.webp" alt="中国男篮" srcset="">
<h3 class="slide-title">中国男篮惜败黎巴嫩 无缘亚洲杯4强</h3>
</li>
<li class="slide-item">
<img class="slide-img" src="assets/image/hhh_2.webp" alt="" srcset="">
<h3 class="slide-title">“使劲活,好好活”|赵丽颖就是何幸福</h3>
</li>
<li class="slide-item">
<img class="slide-img" src="assets/image/dyb_3.webp" alt="" srcset="">
<h3 class="slide-title">东亚杯-全场仅1射门!国足0-3韩国</h3>
</li>
<li class="slide-item">
<img class="slide-img" src="assets/image/ycl_4.webp" alt="" srcset="">
<h3 class="slide-title">杨丞琳拍封面大片 造型时髦有个性</h3>
</li>
<li class="slide-item">
<img class="slide-img" src="assets/image/lss_5.webp" alt="" srcset="">
<h3 class="slide-title">刘诗诗慵懒悠然风生活照 穿搭时髦气质优雅</h3>
</li>
</ul>
</div>
</body>
</html>
3. 样式分析
根据惯例,我们还是从遵循“先整后零,从上到下,由外而内”的原则。首先设置模块的总宽度,并设置水平居中。同时将body
、ul
、p
等元素的内外边距重置为0,去除默认列表样式。
body, ul, p, h3 {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.container {
width: 960px;
margin: 0 auto;
}
利用浮动属性使列表元素能够水平排列,同时记得利用overflow
可以清除浮动对父元素高度的影响。
.slide {
overflow: hidden;
}
.slide-item {
float: left;
}
由于图片大小和文字长度问题,单纯运用浮动并不能实现设计图的效果。多个浮动元素的总宽度大于父元素宽度时,会自动换行。每条新闻的图片和文字都处于一个li
标签中,我们可以通过设置li
标签的尺寸来影响布局。
.slide-item {
float: left;
width: 238px;
height: 120px;
}
.slide-item:first-child {
width: 480px;
height: 241px;
}
添加必要的外边距使图片之间适当留白。 这里需要注意两个地方:
- 图片尺寸大于容器尺寸时,默认会溢出容器边界。可以通过设置
img
标签大小或者容器的溢出属性(overflow: hidden
)避免图片覆盖外边距,从而不显示留白。 nth-child
伪类根据括号内的数值或计算公式选择子元素。n
从0开始。因此2n+3
表示选择第3
、5
个子元素,也就是最右侧显示的图片,不添加右外边距。
img {
width: 100%;
height: 100%;
}
.slide-item {
margin-right: 2px;
margin-bottom: 1px;
overflow: hidden;
}
.slide-item:nth-child(2n+3) {
margin-right: 0;
}
新闻标题需要显示在图片上,发生元素的重叠现象。在HTML中,默认布局会避免内容重叠,一般能够通过两种方式实现元素叠放:
- 利用负外边距(
margin
),一般用于两个模块需要发生部分重叠的情况。 - 运用
position
属性,同一个容器内的元素进行布局时使用较多。
这里的新闻图片和标题,都位于同一个li
标签内,并且标题位置处于整个容器下半部。这种情况下,利用绝对定位(absolute
)十分方便。使用绝对定位时,需要注意参照物的选取。
注意:
absolute
定位的元素,会由内而外地寻找第一个position
属性不为static
的父元素(祖先),并相对它进行定位。如果没有找到,则相对html
标签定位。
.slide-item {
position: relative;
}
.slide-title {
position: absolute;
width: 100%;
padding-top: 20px;
padding-left: 12px;
left: 0;
bottom: 0;
}
接下来就是设置标题的字体大小、颜色等。最重要的是如何让标题不换行,并且当文字太多时自动用省略号(...)。
.slide-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
注意:默认情况下使用
padding
,元素实际大小为padding
+width
。因此当width
设置为100%
时,一定要设置box-sizing: border-box
,将padding
纳入width
中。
设计图上还有文字大小和渐变的透明背景:
.slide-title {
color: #fff;
background-image: linear-gradient(transparent, #000);
line-height: 50px;
font-size: 16px;
font-weight: normal;
}
.slide-item:first-child .slide-title {
padding-left: 25px;
font-size: 20px;
}
到目前为止,从表面上看已经实现了设计稿的要求。不过这还只是静态效果,很多时候为了让用户感知到自己的操作,会添加一些具有指示效果的动画。对于图片来说,平缓的大小缩放动画可以做到这一点。CSS 3支持transition
、transform
、keyframe
等三种动画。
transition
为元素的状态变化添加过渡动画。transform
对元素进行缩放(scale
)、平移(translate
)、旋转(rotate
)等变换。keyframe
添加关键帧动画。
我们希望在鼠标移动到图片上时,图片会有一个平滑放大的效果。结合transform
和transition
可以轻松实现该动画。
.slide-img {
transition: all 0.3s;
}
.slide-img:hover {
transform: scale(1.2);
}
.slide-img:hover
选择鼠标悬停的图片。transform: scale(1.2)
表示放大为初始状态的1.2倍,默认围绕元素中心放大。transition
使得放大时执行平滑的动画,而不是突变。
4. 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片新闻列表</title>
<style>
ul, p, h3 {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
img {
width: 100%;
}
.container {
width: 960px;
margin: 0 auto;
}
.slide {
overflow: hidden;
}
.slide-item {
position: relative;
float: left;
width: 238px;
height: 120px;
margin-right: 2px;
margin-bottom: 1px;
overflow: hidden;
}
.slide-item:first-child {
width: 480px;
height: 241px;
}
.slide-item:nth-child(2n+3) {
margin-right: 0;
}
.slide-title {
position: absolute;
width: 100%;
padding-top: 20px;
padding-left: 12px;
left: 0;
bottom: 0;
color: #fff;
background-image: linear-gradient(transparent, #000);
line-height: 50px;
font-size: 16px;
font-weight: normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
box-sizing: border-box;
}
.slide-item:first-child .slide-title {
padding-left: 25px;
font-size: 20px;
}
.slide-img {
transition: all 0.3s;
}
.slide-img:hover {
transform: scale(1.2);
}
</style>
</head>
<body>
<div class="container">
<ul class="slide">
<li class="slide-item">
<img class="slide-img" src="assets/image/zgnl_1.webp" alt="中国男篮" srcset="">
<h3 class="slide-title">中国男篮惜败黎巴嫩 无缘亚洲杯4强</h3>
</li>
<li class="slide-item">
<img class="slide-img" src="assets/image/hhh_2.webp" alt="" srcset="">
<h3 class="slide-title">“使劲活,好好活”|赵丽颖就是何幸福</h3>
</li>
<li class="slide-item">
<img class="slide-img" src="assets/image/dyb_3.webp" alt="" srcset="">
<h3 class="slide-title">东亚杯-全场仅1射门!国足0-3韩国</h3>
</li>
<li class="slide-item">
<img class="slide-img" src="assets/image/ycl_4.webp" alt="" srcset="">
<h3 class="slide-title">杨丞琳拍封面大片 造型时髦有个性</h3>
</li>
<li class="slide-item">
<img class="slide-img" src="assets/image/lss_5.webp" alt="" srcset="">
<h3 class="slide-title">刘诗诗慵懒悠然风生活照 穿搭时髦气质优雅</h3>
</li>
</ul>
</div>
</body>
</html>
5. 待解问题
nth-child
伪类选择器- CSS 3动画
position
详解- 文本属性