实现Ant Design Pro
image.pngflex布局,默认左右是拉伸的,高度等于最高的一边的高度

左边固定,右边滚动

在左边sider内加一个div,position设置为absolute

  1. <div class="g-ant">
  2. <div class="g-ant__sider g-ant-sider--fixed">
  3. <div class="g-ant-sider__wrapper g-ant-sider__wrapper--fixed">
  4. <p>qqqqqqqqqqqqqqqqqqqqq</p>
  5. </div>
  6. </div>
  7. <div class="g-ant__main">
  8. <p>pppppppppppppppppp</p>
  9. </div>
  10. </div>
  1. .g-ant {
  2. display: flex;
  3. }
  4. .g-ant__sider {
  5. width: 208px;
  6. background: #00152a;
  7. min-height: 100vh;
  8. flex-shrink: 0;
  9. color: white;
  10. }
  11. .g-ant__main {
  12. flex-grow: 1;
  13. }
  14. .g-ant-sider__wrapper--fixed {
  15. position: fixed;
  16. }

侧边栏折叠

侧边栏父容器修改宽度,子容器继承width

  1. .g-ant-sider__wrapper--fixed {
  2. position: fixed;
  3. left: 0;
  4. top: 0;
  5. width: inherit;
  6. overflow: hidden;
  7. }
  8. .g-ant__sider--closed {
  9. width: 48px;
  10. overflow: hidden;
  11. }

position:fixed时,设置height:100%; 是视口高度的100%;
重复的模块命名用m-开头

  1. <ul class="g-ant-sider__main">
  2. <li class="m-menu m-menu--selected">
  3. <div class="m-menu__title">
  4. <i class="iconfont icon-car"></i>
  5. <span>Dashboard</span>
  6. <i class="iconfont icon-arrowup"></i>
  7. </div>
  8. <ul class="m-menu__sub">
  9. <li>分析页</li>
  10. <li class="m-menu__sub--selected">监控页</li>
  11. <li>工作台</li>
  12. </ul>
  13. </li>
  14. </ul>

内联元素只能设置左右的padding和margin

侧边栏列表交互

使用原生JS实现侧边栏标题的点击显示和隐藏

  1. const menuTitles = document.querySelectorAll('.m-menu__title')
  2. for (let i = 0; i < menuTitles.length; i++) {
  3. menuTitles[i].onclick = function () {
  4. const menu = this.parentElement
  5. menu.classList.toggle('m-menu--selected')
  6. const arrow = this.querySelector('[class*="icon-arrow"]')
  7. if (menu.className.includes('m-menu--selected')) {
  8. arrow.className = 'iconfont icon-arrowup'
  9. } else {
  10. arrow.className = 'iconfont icon-arrowdown'
  11. }
  12. }
  13. }

修改滚动条样式

  1. .g-ant-sider__main {
  2. flex-grow: 1;
  3. overflow: hidden auto; /* 分别设置x和y轴 */
  4. }
  5. .g-ant-sider__main::-webkit-scrollbar {
  6. width: 6px;
  7. height: 6px;
  8. }
  9. .g-ant-sider__main::-webkit-scrollbar-thumb {
  10. background: #51606d;
  11. border-radius: 3px;
  12. }
  13. .g-ant-sider__main::-webkit-scrollbar-track {
  14. background: #263849;
  15. border-radius: 3px;
  16. }

折叠交互

querySelector还可以在元素上使用

  1. element = baseElement.querySelector(selectors);
  1. const bar = document.querySelector('.u-bar')
  2. const sider = document.querySelector('.g-ant__sider')
  3. const menus = document.querySelectorAll('.m-menu')
  4. bar.onclick = function () {
  5. sider.classList.toggle('g-ant__sider--closed')
  6. menus[0].classList.add('m-menu--selected');
  7. menus[0].querySelector('[class*="icon-arrow"]').className = 'iconfont icon-arrowup'
  8. for (let i = 1; i < menus.length; i++) {
  9. menus[i].classList.remove('m-menu--selected');
  10. menus[i].querySelector('[class*="icon-arrow"]').className = 'iconfont icon-arrowdown'
  11. }
  12. }

主体内容

主题内容部分采用grid布局

background背景图片相关属性

  1. .index-main__bg6 {
  2. background-repeat: no-repeat;
  3. background-position: center center;
  4. background-size: contain;
  5. width: 100%;
  6. height: 100%;
  7. }

当图片填不满父元素时,应让父元素的背景色与图片相同

设置模块

主题色, li标签里加上iconfont实现
image.png

  1. <div class="m-setting__item">
  2. <h3>主题色</h3>
  3. <ul class="m-setting-item__theme">
  4. <li class="u-foxiaolan"><i class="iconfont icon-check"></i></li>
  5. <li class="u-bomu"></li>
  6. <li class="u-huoshan"></li>
  7. <li class="u-rimu"></li>
  8. <li class="u-mingqing"></li>
  9. <li class="u-jiguanglv"></li>
  10. <li class="u-jikelan"></li>
  11. <li class="u-jiangzi"></li>
  12. </ul>
  13. </div>

用变量控制主题色
  1. :root {
  2. --theme: #53c41a;
  3. }
  4. .m-menu__sub > .m-menu__sub--selected {
  5. background: var(--theme);
  6. }

toggle按钮
  1. <div class="u-switch">
  2. <div class="u-switch__handle"></div>
  3. </div>
  1. .u-switch {
  2. width: 28px;
  3. height: 16px;
  4. border-radius: 100px;
  5. background: var(--theme);
  6. position: relative;
  7. }
  8. .u-switch > .u-switch__handle {
  9. width: 14px;
  10. height: 14px;
  11. position: absolute;
  12. background: white;
  13. border-radius: 100%;
  14. left: 1px;
  15. top: 1px;
  16. }

主题颜色切换

  • window.getComputedStyle 获取CSS属性
  • document.documentElement.style.setProperty 设置根元素的属性

    1. const themes = document.querySelectorAll('.m-setting-item__theme > li')
    2. for (let i=0; i<themes.length; i++){
    3. themes[i].onclick = function(){
    4. for(let i=0; i<themes.length; i++){
    5. themes[i].innerHTML=""
    6. }
    7. this.innerHTML = '<i class="iconfont icon-check"></i>'
    8. const color = getComputedStyle(this).backgroundColor;
    9. document.documentElement.style.setProperty('--theme', color);
    10. }
    11. }

    让绝对定位撑满视口宽度

    left和right都设为0

    1. .g-ant-main__head--fixed {
    2. position: fixed;
    3. left: 0;
    4. right: 0;
    5. z-index: 2;
    6. }

    反选伪类 :not()

    参考

    1. /* 选择所有不是段落(p)的元素 */
    2. :not(p) {
    3. color: blue;
    4. }
    1. .g-ant-main__head--fixed:not(.hide) + .g-ant-main__main {
    2. margin-top: 48px;
    3. }

    :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; }

  1. ```css
  2. .g-ant__sider:is(.show) + .u-mask {
  3. display: block;
  4. }

includes VS contains

includes是String或Array原型上的方法

  1. xxx.className.includes('hide')

contians是classList上的函数

  1. xxx.classList.contains('hide')