实现Ant Design Pro
flex布局,默认左右是拉伸的,高度等于最高的一边的高度
左边固定,右边滚动
在左边sider内加一个div,position设置为absolute
<div class="g-ant">
<div class="g-ant__sider g-ant-sider--fixed">
<div class="g-ant-sider__wrapper g-ant-sider__wrapper--fixed">
<p>qqqqqqqqqqqqqqqqqqqqq</p>
</div>
</div>
<div class="g-ant__main">
<p>pppppppppppppppppp</p>
</div>
</div>
.g-ant {
display: flex;
}
.g-ant__sider {
width: 208px;
background: #00152a;
min-height: 100vh;
flex-shrink: 0;
color: white;
}
.g-ant__main {
flex-grow: 1;
}
.g-ant-sider__wrapper--fixed {
position: fixed;
}
侧边栏折叠
侧边栏父容器修改宽度,子容器继承width
.g-ant-sider__wrapper--fixed {
position: fixed;
left: 0;
top: 0;
width: inherit;
overflow: hidden;
}
.g-ant__sider--closed {
width: 48px;
overflow: hidden;
}
position:fixed时,设置height:100%; 是视口高度的100%;
重复的模块命名用m-开头
<ul class="g-ant-sider__main">
<li class="m-menu m-menu--selected">
<div class="m-menu__title">
<i class="iconfont icon-car"></i>
<span>Dashboard</span>
<i class="iconfont icon-arrowup"></i>
</div>
<ul class="m-menu__sub">
<li>分析页</li>
<li class="m-menu__sub--selected">监控页</li>
<li>工作台</li>
</ul>
</li>
</ul>
内联元素只能设置左右的padding和margin
侧边栏列表交互
使用原生JS实现侧边栏标题的点击显示和隐藏
const menuTitles = document.querySelectorAll('.m-menu__title')
for (let i = 0; i < menuTitles.length; i++) {
menuTitles[i].onclick = function () {
const menu = this.parentElement
menu.classList.toggle('m-menu--selected')
const arrow = this.querySelector('[class*="icon-arrow"]')
if (menu.className.includes('m-menu--selected')) {
arrow.className = 'iconfont icon-arrowup'
} else {
arrow.className = 'iconfont icon-arrowdown'
}
}
}
修改滚动条样式
.g-ant-sider__main {
flex-grow: 1;
overflow: hidden auto; /* 分别设置x和y轴 */
}
.g-ant-sider__main::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.g-ant-sider__main::-webkit-scrollbar-thumb {
background: #51606d;
border-radius: 3px;
}
.g-ant-sider__main::-webkit-scrollbar-track {
background: #263849;
border-radius: 3px;
}
折叠交互
querySelector还可以在元素上使用
element = baseElement.querySelector(selectors);
const bar = document.querySelector('.u-bar')
const sider = document.querySelector('.g-ant__sider')
const menus = document.querySelectorAll('.m-menu')
bar.onclick = function () {
sider.classList.toggle('g-ant__sider--closed')
menus[0].classList.add('m-menu--selected');
menus[0].querySelector('[class*="icon-arrow"]').className = 'iconfont icon-arrowup'
for (let i = 1; i < menus.length; i++) {
menus[i].classList.remove('m-menu--selected');
menus[i].querySelector('[class*="icon-arrow"]').className = 'iconfont icon-arrowdown'
}
}
主体内容
主题内容部分采用grid布局
background背景图片相关属性
.index-main__bg6 {
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
width: 100%;
height: 100%;
}
当图片填不满父元素时,应让父元素的背景色与图片相同
设置模块
主题色, li标签里加上iconfont实现
<div class="m-setting__item">
<h3>主题色</h3>
<ul class="m-setting-item__theme">
<li class="u-foxiaolan"><i class="iconfont icon-check"></i></li>
<li class="u-bomu"></li>
<li class="u-huoshan"></li>
<li class="u-rimu"></li>
<li class="u-mingqing"></li>
<li class="u-jiguanglv"></li>
<li class="u-jikelan"></li>
<li class="u-jiangzi"></li>
</ul>
</div>
用变量控制主题色
:root {
--theme: #53c41a;
}
.m-menu__sub > .m-menu__sub--selected {
background: var(--theme);
}
toggle按钮
<div class="u-switch">
<div class="u-switch__handle"></div>
</div>
.u-switch {
width: 28px;
height: 16px;
border-radius: 100px;
background: var(--theme);
position: relative;
}
.u-switch > .u-switch__handle {
width: 14px;
height: 14px;
position: absolute;
background: white;
border-radius: 100%;
left: 1px;
top: 1px;
}
主题颜色切换
- window.getComputedStyle 获取CSS属性
document.documentElement.style.setProperty 设置根元素的属性
const themes = document.querySelectorAll('.m-setting-item__theme > li')
for (let i=0; i<themes.length; i++){
themes[i].onclick = function(){
for(let i=0; i<themes.length; i++){
themes[i].innerHTML=""
}
this.innerHTML = '<i class="iconfont icon-check"></i>'
const color = getComputedStyle(this).backgroundColor;
document.documentElement.style.setProperty('--theme', color);
}
}
让绝对定位撑满视口宽度
left和right都设为0
.g-ant-main__head--fixed {
position: fixed;
left: 0;
right: 0;
z-index: 2;
}
反选伪类 :not()
/* 选择所有不是段落(p)的元素 */
:not(p) {
color: blue;
}
.g-ant-main__head--fixed:not(.hide) + .g-ant-main__main {
margin-top: 48px;
}
:is() 选择器
```css / 选择header, main, footer里的任意一个悬浮状态的段落(p标签) / :is(header, main, footer) p:hover { color: red; cursor: pointer; }
/ 以上内容相当于以下内容 / header p:hover, main p:hover, footer p:hover { color: red; cursor: pointer; }
```css
.g-ant__sider:is(.show) + .u-mask {
display: block;
}
includes VS contains
includes是String或Array原型上的方法
xxx.className.includes('hide')
contians是classList上的函数
xxx.classList.contains('hide')