MProjectsNDays之1:可伸展的卡片

375 阅读2分钟

这是MProjectsNDays的第1个项目,可点击体验,效果如图:

探索世界

晴朗的海滩

该项目主要效果就是用户点击哪个卡片,哪个卡片就伸展开来。实现思路也很简单,被点击到的卡片添加一个特定的类名,其余卡片移除这个类名,这个类选择器的核心功能就是使卡片的宽度占比加大

html布局很简单,这里不再赘述,仅展示出核心代码:

<body>
    <div class="container">
        <div class="panel active" style="background-image: url(./img/1.jfif);">
            <h3>探索世界</h3>
        </div>
        <div class="panel" style="background-image: url(./img/2.jfif);">
            <h3>原始森林</h3>
        </div>
        <div class="panel" style="background-image: url(./img/3.jfif);">
            <h3>晴朗的海滩</h3>
        </div>
        <div class="panel" style="background-image: url(./img/4.jfif);">
            <h3>冬天的城市</h3>
        </div>
        <div class="panel" style="background-image: url(./img/5.jfif);">
            <h3>云山</h3>
        </div>
    </div>
    <script src="script.js"></script>
</body>

下面进行css核心代码的讲解:

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

display: flex——将body设置为flex布局。关于flex的知识点很多,但是在这个项目里就只用到两个,一个是居中,一个就是flex元素占比来实现卡片宽度的变化。

justify-content: center——定义元素在主轴(这里为横轴)上的对齐方式为居中

align-items: center——定义元素在竖轴上的对齐方式为居中

以上两个属性一起使用可以轻松实现水平和垂直居中。

height: 100vh——vh是相对视图窗口的长度单位,与之相对的还有vw。100vh就是整个视图窗口的高。

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

有了上面的基础,对于container就可以很容易的理解了。值得注意的是container使用flex才是卡片宽度变化的关键,body使用flex仅仅是为了实现居中效果。

.panel{
    position: relative;
    flex: 0.5;
}

.panel.active {
    flex: 5;
}

注意其中的flex属性,panel中占比0.5,active的panel占比5,这里就可以通过active类的添加和移除实现卡片的伸展了,js代码如下:

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

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

function removeActiveClasses() {
    panels.forEach(panel => {
        panel.classList.remove('active')
    })
}

至此,其实核心功能就已经完成了!


当然了,如果仅仅这样做会显得非常生硬,因此项目中还有其他一些锦上添花的操作!

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

transition: all 700ms ease-in——transition的完整语法为:

transition: property duration timing-function delay;

以上四个属性分别为:过渡效果的CSS属性名(all则为所有属性都需要过渡)、完成过渡效果的时间、过渡的速度曲线和过渡效果延时执行的时间

.panel h3 {
    font-size: 24px;
    position: absolute;
    bottom: 20px;
    left: 20px;
    margin: 0;
    opacity: 0;
    color: white;
  }
  
  .panel.active h3{
    opacity: 1;
    transition: opacity 0.3s ease-in 0.4s;
}

opacity: 0——不透明度。从 0.0 (完全透明)到 1.0(完全不透明)。因此默认状态下,不展开的卡片,其文字是不可见的;伸展之后文字可见,两个状态之间有过渡效果。

至此,整个项目就完成了!

完整源码可在此查看