From c58fc191e8baf58080458e19cbd9c79c9782c52f Mon Sep 17 00:00:00 2001 From: xaoxuu Date: Tue, 6 Feb 2024 23:39:51 +0800 Subject: [PATCH] [opt] layout --- _config.yml | 8 +- layout/_partial/sidebar/index_rightbar.ejs | 13 ++- layout/_partial/widgets/tree.ejs | 15 ++-- source/css/_common/device.styl | 19 +++-- source/css/_custom.styl | 17 ++-- source/css/_layout/layout.styl | 12 ++- source/css/_layout/sidebar/logo.styl | 4 +- source/css/_layout/sidebar/sidebar.styl | 9 +- source/css/_layout/widgets/ghuser.styl | 3 +- source/css/_layout/widgets/toc.styl | 98 ++++++++++++---------- source/css/_layout/widgets/widgets.styl | 9 +- source/js/main.js | 2 +- 12 files changed, 121 insertions(+), 88 deletions(-) diff --git a/_config.yml b/_config.yml index 0f1649a..e8f5485 100755 --- a/_config.yml +++ b/_config.yml @@ -63,7 +63,7 @@ site_tree: # 主页配置 home: leftbar: welcome, recent - rightbar: welcome + rightbar: # 博客列表页配置 index_blog: base_dir: blog # 只影响自动生成的页面路径 @@ -80,7 +80,7 @@ site_tree: index_wiki: base_dir: wiki # 只影响自动生成的页面路径 menu_id: wiki # 未在 front-matter 中指定 menu_id 时,layout 为 wiki 的页面默认使用这里配置的 menu_id - leftbar: ghissues, related, recent # for wiki + leftbar: related, recent # for wiki rightbar: nav_tabs: # 'more': https://github.com/xaoxuu @@ -88,7 +88,7 @@ site_tree: # 博客文章内页配置 post: menu_id: post # 未在 front-matter 中指定 menu_id 时,layout 为 post 的页面默认使用这里配置的 menu_id - leftbar: related, ghrepo, ghissues, recent # for pages using 'layout:post' + leftbar: related, recent # for pages using 'layout:post' rightbar: ghrepo, toc # 博客专栏文章内页配置 topic: @@ -96,7 +96,7 @@ site_tree: # 文档内页配置 wiki: menu_id: wiki # 未在 front-matter 中指定 menu_id 时,layout 为 wiki 的页面默认使用这里配置的 menu_id - leftbar: tree, ghissues, related, recent # for wiki + leftbar: tree, related, recent # for wiki rightbar: ghrepo, toc # 作者信息配置 author: diff --git a/layout/_partial/sidebar/index_rightbar.ejs b/layout/_partial/sidebar/index_rightbar.ejs index b94436e..96152e5 100644 --- a/layout/_partial/sidebar/index_rightbar.ejs +++ b/layout/_partial/sidebar/index_rightbar.ejs @@ -49,8 +49,10 @@ if (typeof page.rightbar == 'string') { } function layoutWidgets() { - var el = ''; - el += '
'; + if (page.rightbar == null || page.rightbar.length == 0) { + return '' + } + var el = '' if (page.rightbar) { page.rightbar.forEach((w, i) => { let name = '' @@ -71,8 +73,11 @@ function layoutWidgets() { } }); } - el += '
'; - return el; + if (el.trim().length > 0) { + return `
${el}
` + } else { + return '' + } } %> diff --git a/layout/_partial/widgets/tree.ejs b/layout/_partial/widgets/tree.ejs index 897d4fd..afcd5de 100644 --- a/layout/_partial/widgets/tree.ejs +++ b/layout/_partial/widgets/tree.ejs @@ -47,7 +47,6 @@ function layoutDiv(fallback) { return '' } var el = '' - el += `` for (let sec of proj.sections) { if (sec.pages.length == 0) { continue @@ -55,12 +54,16 @@ function layoutDiv(fallback) { if (sec.title?.length > 0) { el += layoutTocHeader(sec.title) } - el += `
` - el += layoutDocTree(sec.pages) - el += `
` + const docTree = layoutDocTree(sec.pages) + if (docTree.trim().length > 0) { + el += `
${docTree}
` + } + } + if (el.trim().length > 0) { + return `${el}` + } else { + return '' } - el += `
` - return el } %> diff --git a/source/css/_common/device.styl b/source/css/_common/device.styl index de6c7ad..e5fb2f0 100644 --- a/source/css/_common/device.styl +++ b/source/css/_common/device.styl @@ -16,9 +16,11 @@ z-index: 10 display: flex flex-direction: column - border-radius: 0.5rem + border-radius: $border-bar margin-left: auto margin-right: 1rem + @media screen and (min-width: $device-mobile-max) + margin-right: 2rem overflow: hidden --blur-px: 16px --blur-bg: alpha(#fff, .4) @@ -47,9 +49,10 @@ // 侧边栏弹出后 .l_body[leftbar] .float-panel, .l_body[rightbar] .float-panel - box-shadow: 0 0 4px -2px $color-theme, 0 0 16px -8px $color-theme, 0 0 32px -16px $color-theme -.l_body[leftbar] .float-panel button - background: var(--card) + box-shadow: 0 0 4px -1px $color-theme, 0 0 16px -4px $color-theme, 0 0 32px -12px $color-theme, 0 0 128px -32px $color-theme + +.l_body[leftbar] .float-panel button.leftbar-toggle + background: var(--alpha100) .l_body[leftbar] .float-panel button.leftbar-toggle color: $color-theme @@ -61,8 +64,12 @@ transform: translateX(2px) -.l_body[rightbar] .float-panel button - background: var(--card) +// 侧边栏有内容时才显示弹出按钮 +.l_body .l_right:empty+.float-panel button.rightbar-toggle + display: none !important + +.l_body[rightbar] .float-panel button.rightbar-toggle + background: var(--alpha100) .l_body[rightbar] .float-panel button.rightbar-toggle color: $color-theme diff --git a/source/css/_custom.styl b/source/css/_custom.styl index 0c6eea7..f1676cf 100644 --- a/source/css/_custom.styl +++ b/source/css/_custom.styl @@ -67,32 +67,35 @@ $border-button = 4px // 可以动态变化的属性 :root - --width-sidebar: 288px --width-main: 720px --fsp: $fs-body --fsh2: 'calc(%s + 11px)' % var(--fsp) --fsh3: 'calc(%s + 7px)' % var(--fsp) --fsh4: 'calc(%s + 4px)' % var(--fsp) + // 侧边栏文字内容宽度 + --side-content-width: 224px + // 元素轮廓到容器边缘的间距 --gap-margin: 16px + // 元素文本内容到元素自身的轮廓的间距 --gap-padding: 16px - --gap-max: calc(var(--gap-margin) + var(--gap-padding)) --gap-p: 'calc(%s + 4px)' % $fs-body // gap for paragraph --gap-p-compact: 'calc(%s * 0.75)' % $fs-body // desktop 2k or larger @media screen and (min-width: $device-2k) - --width-sidebar: 352px --width-main: 780px // desktop 4k or larger @media screen and (min-width: $device-4k) --width-main: 860px // iPad 竖屏 @media screen and (max-width: $device-tablet) - --width-sidebar: 252px - // iPad 竖屏 - @media screen and (max-width: $device-mobile-max) - --width-sidebar: 288px + --side-content-width: 188px + +// 动态计算值 +:root + // 元素文本内容到容器边缘的间距 + --gap-max: calc(var(--gap-margin) + var(--gap-padding)) // 文章布局风格 .l_body.story diff --git a/source/css/_layout/layout.styl b/source/css/_layout/layout.styl index 18ff1a9..983f70f 100644 --- a/source/css/_layout/layout.styl +++ b/source/css/_layout/layout.styl @@ -7,21 +7,27 @@ .l_body aside z-index: 8 - width: var(--width-sidebar) flex-shrink: 0 position: sticky position: -webkit-sticky + // 侧边栏容器宽度 + --width-sidebar: calc(var(--gap-margin) * 2 + var(--gap-padding) * 2 + var(--side-content-width)) + width: var(--width-sidebar) .l_body .l_left + justify-self: right top: 8px .l_body .l_right - width: calc(var(--width-sidebar) - var(--gap-max) + var(--gap-padding)) + justify-self: left + --gap-margin: 0px .widgets height: 100% overflow visible // 平板布局 @media screen and (max-width: $device-laptop) + .l_body .l_right + --gap-margin: 16px .laptop-only display: block !important .l_body @@ -43,7 +49,7 @@ .l_right transform: translateX(0px) .main-mask - opacity 1 + // opacity 1 pointer-events: inherit // 手机布局 diff --git a/source/css/_layout/sidebar/logo.styl b/source/css/_layout/sidebar/logo.styl index 828853e..2e013a0 100644 --- a/source/css/_layout/sidebar/logo.styl +++ b/source/css/_layout/sidebar/logo.styl @@ -3,8 +3,10 @@ align-items: center overflow: hidden min-height: 48px - img + img.avatar object-fit: cover + img.icon + object-fit: contain .icon width: 48px height: 48px diff --git a/source/css/_layout/sidebar/sidebar.styl b/source/css/_layout/sidebar/sidebar.styl index 4079e82..6cde837 100644 --- a/source/css/_layout/sidebar/sidebar.styl +++ b/source/css/_layout/sidebar/sidebar.styl @@ -1,18 +1,15 @@ .l_left - margin: 8px 0 8px 8px + margin: 8px height: 'calc(%s - 16px)' % 100vh border-radius: $border-card-l overflow: hidden .header margin: var(--gap-max) var(--gap-margin) 0 - // @media screen and (min-width: $device-mobile-max) - // >.widgets:first-child>.widget-wrapper:first-child - // margin-top: calc(2 * var(--gap-max)) .l_right - margin: 8px 8px 8px 0 + margin: 8px border-radius: $border-card-l -@media screen and (min-width: 1400px) +@media screen and (min-width: $device-2k) .l_left margin-left: auto margin-right: calc(2 * var(--gap-max)) diff --git a/source/css/_layout/widgets/ghuser.styl b/source/css/_layout/widgets/ghuser.styl index 1dc861b..fca7ee2 100644 --- a/source/css/_layout/widgets/ghuser.styl +++ b/source/css/_layout/widgets/ghuser.styl @@ -6,7 +6,7 @@ background: var(--card) border-radius: $border-card padding: 1rem - hoverable-card() + box-shadow: $boxshadow-card .widgets .widget-wrapper.user-card .avatar @@ -17,6 +17,7 @@ overflow: hidden img display: block + aspect-ratio: 1 @media screen and (max-width: $device-tablet) max-width: 50% diff --git a/source/css/_layout/widgets/toc.styl b/source/css/_layout/widgets/toc.styl index 8b1d222..bd6e4ad 100644 --- a/source/css/_layout/widgets/toc.styl +++ b/source/css/_layout/widgets/toc.styl @@ -1,10 +1,17 @@ .widget-wrapper.toc background: var(--site-bg) z-index 1 - -.l_right .widgets .widget-wrapper.toc .widget-header - padding-left: var(--gap-max) - padding-right: var(--gap-max) + .widget-body + position relative + &:before + content: '' + position absolute + top: 4px + bottom: 4px + left: 0 + width: 4px + background: var(--block) + border-radius: 4px // 目录基本样式 .widget-wrapper.toc .toc @@ -13,46 +20,42 @@ margin: 0 position relative list-style: none - .toc-child - padding-left: 1em li - margin: 2px 0 + margin: 0 list-style: none - a - padding: 4px var(--gap-max) + a + --padding: calc(var(--gap-padding) / 2) + --padding-offset: calc(0 - var(--padding)) + padding: 6px var(--padding) + margin: 0 var(--padding) color: var(--text-p3) display: block - overflow: hidden - text-overflow: ellipsis - white-space: nowrap position relative - &:before,&:after - position: absolute - left: 'calc(%s * 0.5)' % var(--gap-max) - width: 8px - height: 8px - top: 'calc(%s - 4px)' % 50% - border-radius: 8px - background: var(--block) + border-radius: $border-bar + trans1 all + &.active:before + content: '' + position absolute + top: 4px + bottom: 4px + left: -8px + width: 4px background: $color-theme - &:after - opacity 0 - animation: wave 1s linear infinite - @keyframes wave - from - transform: scale(1) - opacity 1 - to - transform: scale(2) - opacity 0 + border-radius: 4px + &:hover + background: var(--block-hover) + color: var(--text) // 固定位置 .l_right .widgets .widget-wrapper.toc + margin-top: 0 position: sticky position: -webkit-sticky top: 0 - margin-top: 0 padding: 16px 0 + &:first-child + top: 8px + padding-top: 8px .widget-body .toc max-height: 70vh @media screen and (max-width: $device-laptop) @@ -67,14 +70,23 @@ .toc-item font-weight: 500 --fsp: $fsp1 - .toc-item .toc-item + .toc-item .toc-item font-weight: 400 --fsp: $fsp2 + ol + padding-left: 0 + .toc-child .toc-link + padding-left: 1.5rem + .toc-child .toc-child .toc-link + padding-left: 2.5rem + .toc-child .toc-child .toc-child .toc-link + padding-left: 3.5rem + .toc-child .toc-child .toc-child .toc-child .toc-link + padding-left: 4.5rem + .toc-child .toc-child .toc-child .toc-child .toc-child .toc-link + padding-left: 5rem // 高亮样式 -.widget-wrapper.toc .toc a.toc-link:hover - color: $color-theme - .widget-wrapper.toc .toc a.toc-link.active color: var(--text) &:before,&:after @@ -127,8 +139,8 @@ background: var(--block-border) top: 0 height: 1px - left: var(--gap-max) - right: var(--gap-max) + left: var(--gap-padding) + right: var(--gap-padding) .widget-wrapper.toc .widget-footer margin-top: 8px color: var(--text-p2) @@ -139,9 +151,9 @@ align-items: center color: inherit font-size: $fs-14 - padding: 8px 16px - margin: 0 calc(var(--gap-max) - 16px) - border-radius: 4px + padding: 8px var(--gap-padding) + border-radius: $border-bar + trans1 all svg,img height: 16px width: auto @@ -157,14 +169,14 @@ .l_right blur-effect() .widgets - padding: 8px .widget-wrapper.toc - background: var(--alpha100) + position: static + background: none .widget-wrapper.toc .toc a color: var(--text-p2) .widget-wrapper.toc .widget-footer a - background: var(--block) + background: var(--alpha100) a+a margin-top: 4px \ No newline at end of file diff --git a/source/css/_layout/widgets/widgets.styl b/source/css/_layout/widgets/widgets.styl index 8b2096e..2c5ea5c 100644 --- a/source/css/_layout/widgets/widgets.styl +++ b/source/css/_layout/widgets/widgets.styl @@ -10,6 +10,7 @@ scrollbar(0, 0) z-index: 1 line-height: 1.2 + margin: 0 var(--gap-margin) .widget-wrapper .widget-header padding-left: var(--gap-padding) @@ -61,21 +62,17 @@ padding-bottom: 32px .l_left .widgets - margin: 0 var(--gap-margin) .widget-wrapper &:first-child margin-top: 32px -.l_right - --gap-margin: 0 .l_right .widgets + &:empty + display: none .widget-wrapper .widget-header padding-left: var(--gap-padding) padding-right: var(--gap-padding) - &:not(.toc) - margin-left: var(--gap-margin) - margin-right: var(--gap-margin) @media screen and (max-width: $device-laptop) .widget-wrapper margin-top: var(--gap-margin) diff --git a/source/js/main.js b/source/js/main.js index b108422..41909e9 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -159,7 +159,7 @@ const init = { if(timeout !== null) clearTimeout(timeout); timeout = setTimeout(function() { scrollTOC(); - }.bind(this), 300); + }.bind(this), 50); }); }) },