50 Projects 50 Days - Expanding Cards 学习记录

50 Projects 50 Days不使用任何前端框架,适合初学者练手,巩固前端基础,在这里记录一下学习过程,尤其是一些细节上的问题。

项目地址

Expanding Cards

展示效果

Expanding Cards

实现思路

其实很简单,就是利用flex布局中设置不同的拉伸比例来实现展开效果,通过设置一个特殊的class,这个class的拉伸比例设置为较大的值,再通过JavaScript将该class的设置与点击事件进行绑定即可实现。

实现细节

HTML结构

使用container包裹作用只是为了限制左右宽度而已,去掉container结构对样式影响不大。
container内,每个div只包含一个H3标题子元素,图片部分通过背景样式填充。

<div class="container">
     <div class="panel active" id="World">
         <h3>Worldh3>
     div>
     <div class="panel" id="Forest">
         <h3>Foresth3>
     div>
     <div class="panel" id="Beach">
         <h3>Beachh3>
     div>
     <div class="panel" id="City">
         <h3>Cityh3>
     div>
     <div class="panel" id="Mountains">
         <h3>Mountainsh3>
     div>
 div>

跟原项目有一些区别的是我并没有把背景图片链接直接写在div里,而是通过id在css中设置,两者其实效果一致,无非就是这样看起来HTML文件更简洁一些。

CSS样式

body部分
1. 设置flex主要是为了让元素在整个页面中都是居中显示
2. margin清零则是为了消除浏览器的用户代理样式表对显示效果的影响。
3. height设置100%视高可以让网页全屏显示,实际本地调试发现不设置也OK。

body {
	height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 0;
}

container部分利用flex布局来控制下面的卡片伸缩,这里需要设置一个宽度,否则子元素卡片由于父级没有设置宽度不能撑开盒子尺寸。

.container{
    display: flex;
    width: 90vw;
}

panel部分就是卡片主体
1. 设置高度,可以在这里设置,也可以再container统一设置,差别就是有margin的时候在外面设置高度要纳入计算
2. 设置flex拉伸比例flex: 0.5这里如果不设置拉伸比例默认是flex: 0 1 auto,表示不会拉伸,同时由于卡片自身没有设置宽度,子元素又因为绝对定位并不会撑开尺寸,flex布局将会使卡片尺寸缩小至0
3. 背景图片需要调整,background-size: cover表示优先考虑卡片自身尺寸将背景图覆盖,background-position: center将背景图片中心和卡片中心对齐,background-repeat: no-repeat在这里可设可不设,表示不会重复
4. 设置为相对定位是为了给子元素标题绝对定位使用
5. 设置一个特殊class,只改变flex的拉伸比例

.panel{
    height:80vh;
    flex: 0.5;
    margin: 10px;
    border-radius: 50px;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    position:relative;
    transition:all 0.7s ease-in;
    cursor: pointer;
}

.panel.active{
    flex: 5;
}

不设置拉伸比例的结果,所有元素都会缩到一起,因为尺寸是0:
50 Projects 50 Days - Expanding Cards 学习记录_第1张图片

panel h3卡片子元素
1. 改为绝对定位,将标题设置到卡片的左下角,这样之后脱离文档流,父元素将不再拥有基本尺寸,需要注意设置其拉伸比例。
2. 默认透明,特殊class时显示。

.panel h3{
    position: absolute;
    bottom: 20px;
    left: 20px;
    color: #fff;
    opacity: 0;
}

.panel.active h3{
    opacity: 1;
    transition:opacity 0.4s ease-in 0.3s;
}

JavaScript逻辑

将所有panel卡片绑定点击事件,回调函数中先是遍历所有元素清楚掉active的class,再给响应事件的对应卡片再加上active。

const panels = document.querySelectorAll('.panel');

const removeActiveClass = () => {
    panels.forEach(panel => panel.classList.remove('active'));
}

panels.forEach(panel => {
    panel.addEventListener('click', ()=>{
        removeActiveClass();
        panel.classList.add('active');
    })
});

最后要提醒的是,这段脚本要想生效,必须是在body内部引入,因为绑定事件的程序需要再页面加载时就要执行,而如果放在head部分,dom还没有加载出来就已经装载,也不会立即执行,只有在调用的地方才会执行,因此并不能成功给卡片绑定事件。

<body>
    <div class="container">
        
    div>
    <script src="script.js">script>
body>

你可能感兴趣的:(前端基础,javascript,前端,css,css3,html)