今天我们来添加一些组件,这一期的是导航栏组件
准备结构
.control 里面放置的是 logo 和 控制按钮,在大屏模式下,只显示 logo,在小屏幕模式将全部显示。 .content 则是大屏模式的内容,当小屏模式将链接堆叠显示
<nav class="nav">
<div class="control">
<a href="#" class="logo"><img src="https://nodelover.me/public/img/logo.png" width="42" height="42"></a>
<div class="list">
<a class="link">探索</a>
<a class="link">分类</a>
</div>
<a role="button" class="nav-control close">
<span></span>
<span></span>
<span></span>
</a>
</div>
<div class="content">
<div class="left">
<div class="list">
<a class="link">探索</a>
<a class="link">分类</a>
</div>
</div>
<div class="right">
<div class="list">
<a class="link">登录</a>
<a class="link">注册</a>
</div>
</div>
</div>
</nav>
复制代码
设置变量
left-right-padding 链接的左右内边距,其他都是颜色与高度
$nav-height: 60px !default
$hover-bg: #f7fbff !default
$default-bg: #fff !default
$link-color: $blue !default
$left-right-padding: 1rem !default
复制代码
大屏默认样式
使用 flex 布局,便于垂直居中,禁用掉用户选择,使用 margin-left auto 可以让 flex 布局实现 block 布局中 float right 类似的效果。
一定要禁用掉 .control 的 flex 缩小即 flex-shrink ,要不然 logo 会发生变形。
.nav
height: $nav-height
display: flex
align-items: center
user-select: none
// 默认只显示 logo
.control
display: flex
background: $default-bg
align-items: center
flex-shrink: 0
z-index: 2
.list
display: none
a.link
display: inline-block
line-height: $nav-height
height: $nav-height
padding: 0 $left-right-padding
color: $link-color
cursor: pointer
&:hover
background: $hover-bg
color: $link-color
.logo
background: transparent
line-height: 0
margin-right: $left-right-padding
.content
display: flex
width: 100%
.right
margin-left: auto
复制代码
控制按钮
使用 css 动画创建按钮,默认隐藏,对于伪类选择器,使用 nth 可以达到同样的效果。
// 控制按钮
.nav-control
display: none
line-height: $nav-height
height: $nav-height
width: $nav-height
text-align: center
padding: 0 $left-right-padding
position: relative
margin-left: auto
cursor: pointer
span
height: 2px
width: 15px
background: #333
position: absolute
transition: transform ease-out .086s
top: calc(50% - 1px)
&:first-of-type
top: calc(50% - 6px)
&:last-of-type
top: calc(50% + 4px)
// 按钮变形
.nav.active
.nav-control
span
display: none
&:first-of-type
transform: translateY(5px) rotate(45deg)
display: block
&:last-of-type
transform: translateY(-5px) rotate(-45deg)
display: block
transform-origin: center;
复制代码
移动端样式
用 flex-basis: 100% 控制内容的宽度,跟 width:100% 差不多,且使用了 translateY 与 css 动画,让堆叠的按钮出现向下滑出的特效。使用 visibility 和 z-index 是为了避免遮罩住原来的导航栏。
@media screen and (max-width: $media-size-3)
.nav
position: relative
.control
flex-basis: 100%
.list,
.nav-control
display: block
.content
display: block
z-index: 1
position: absolute
background: $default-bg
padding: .5rem 0
top: 100%
left: 0
right: 0
transform: translateY(-10%)
transition: transform ease-out .09s, opacity .07s
visibility: hidden
opacity: 0
&.active
.content
transform: translateY(0%)
visibility: visible
opacity: 1
.link
display: block
复制代码
在最后,我们添加一点简单的 js 代码来实现,点击切换样式,新建 index.ts 并在 index.html 导入
const toggleClass = (
clickSelector: string,
addClassSelector: string,
className?: string
) => {
const $cDom = document.querySelector<HTMLElement>(clickSelector)
const $aDom = document.querySelector<HTMLElement>(addClassSelector)
$cDom.onclick = () => {
$aDom.classList.toggle(className)
}
}
toggleClass('.nav .nav-control', '.nav', 'active')
复制代码