js+css实现好看的文章段落滚动指示器导航效果代码
代码语言:html
所属分类:加载滚动
代码描述:js+css实现好看的文章段落滚动指示器导航效果代码,显示当前阅读文章的总体进度和位置,还可以打开段落导航条进行滚动跳转到相关段落。
代码标签: js css 好看 文章 段落 滚动 指示器 导航
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/normalize.5.0.css"> <style> @layer normalize, base, demo, scroll; @layer popover { :root { --bottom: 2rem; --speed: 0.3s; --power-in: linear( 0 0%, 0.0039 6.25%, 0.0156 12.5%, 0.0352 18.75%, 0.0625 25%, 0.0977 31.25%, 0.1407 37.5%, 0.1914 43.74%, 0.2499 49.99%, 0.3164 56.25%, 0.3906 62.5%, 0.5625 75%, 0.7656 87.5%, 1 100% ); --power-in-out: linear( 0 0%, 0.0012 14.95%, 0.0089 22.36%, 0.0297 28.43%, 0.0668 33.43%, 0.0979 36.08%, 0.1363 38.55%, 0.2373 43.07%, 0.3675 47.01%, 0.5984 52.15%, 0.7121 55.23%, 0.8192 59.21%, 0.898 63.62%, 0.9297 66.23%, 0.9546 69.06%, 0.9733 72.17%, 0.9864 75.67%, 0.9982 83.73%, 1 100% ); --power-out: linear( 0 0%, 0.2342 12.49%, 0.4374 24.99%, 0.6093 37.49%, 0.6835 43.74%, 0.7499 49.99%, 0.8086 56.25%, 0.8593 62.5%, 0.9023 68.75%, 0.9375 75%, 0.9648 81.25%, 0.9844 87.5%, 0.9961 93.75%, 1 100% ); --ease: var(--power-in); --trigger-width: 190px; --trigger-height: 44px; } :root:has(:popover-open) { --ease: var(--power-out); } [popover]:popover-open .backdrop-blur { scale: 1; opacity: 1; } @starting-style { [popover]:popover-open .backdrop-blur { scale: 0; opacity: 0; } } .trigger { width: var(--trigger-width); height: var(--trigger-height); border-radius: 22px; color: light-dark(canvas, canvasText); border: 0; outline-color: white; } :root:has(.trigger:focus-visible) [popover] { outline: 2px solid white; } .trigger, .contents { background: light-dark(hsl(0 0% 8%), hsl(0 0% 14%)); } .contents { display: flex; overflow: hidden; height: 100%; width: 100%; flex-direction: column-reverse; border-radius: 22px; padding: 0 6px; transition: padding var(--speed); transform: translate3d(0, 0, 0); @starting-style { padding: 1rem; } } @starting-style { [popover]:popover-open .contents { padding: 0 6px; } } [popover] { border: 0px; border-radius: 22px; background: transparent; padding-block: 0; overflow: visible; } [popover] .trigger__details { min-height: 44px; flex-basis: 44px; } .trigger__details { display: flex; align-items: center; gap: 0.5rem; padding-left: 0.5rem; padding-right: 0.25rem; width: 100%; } .trigger__details svg { width: 24px; } .trigger__details .lines { -webkit-animation: draw both linear; animation: draw both linear; animation-timeline: --content; } .trigger__details > span:first-of-type { flex: 1; display: flex; align-items: center; text-align: left; gap: 0.25rem; svg { width: 18px; } } @-webkit-keyframes draw { to { stroke-dashoffset: 0; } } @keyframes draw { to { stroke-dashoffset: 0; } } [popovertargetaction] { anchor-name: --opener; } [popover]:popover-open { display: flex; } [popover]:popover-open .contents { padding: 1rem; } @starting-style { [popover]:popover-open .contents { padding: 0 6px; } } [data-alignment='left'] .trigger, [data-alignment='left'] [popover] { left: 1rem; } [data-alignment='right'] .trigger, [data-alignment='right'] [popover] { right: 1rem; } [data-alignment='center'] .trigger, [data-alignment='center'] [popover] { left: 50%; translate: -50% 0; } [popover] { flex-direction: column-reverse; position-anchor: --opener; transition-property: display, overlay, width, height; transition-duration: var(--speed); transition-behavior: allow-discrete; transition-timing-function: var(--ease); color: white; margin: unset; inset: unset; bottom: var(--bottom); width: var(--trigger-width); height: var(--trigger-height); z-index: 99999999; padding: 0; interpolate-size: allow-keywords; @starting-style { width: var(--trigger-width); height: var(--trigger-height); } } [popover] ol { padding-inline: 0.5rem; padding-left: 2.5rem; list-style: pad-it; display: flex; width: -webkit-max-content; width: -moz-max-content; width: max-content; margin: 0; flex-direction: column; filter: blur(4px); opacity: 0; transition: filter var(--speed), opacity var(--speed); transition-timing-function: var(--ease); } [popover]:popover-open ol { filter: blur(0px); opacity: 1; } @starting-style { [popover]:popover-open ol { filter: blur(4px); opacity: 0; } } [popover]:popover-open { width: var(--content-width, -webkit-fit-content); width: var(--content-width, -moz-fit-content); width: var(--content-width, fit-content); height: var(--content-height, -webkit-fit-content); height: var(--content-height, -moz-fit-content); height: var(--content-height, fit-content); } li::marker { color: #999; } li:has(a:is(:hover, :focus-visible))::marker { color: #fff; } ol li a { color: inherit; white-space: nowrap; padding-block: 0.5rem; text-decoration: none; display: inline-block; color: #999; flex: 1; width: 100%; &:is(:hover, :focus-visible) { color: #fff; } } @starting-style { [popover]:popover-open { width: var(--trigger-width); height: var(--trigger-height); } } [popover]::-webkit-backdrop { -webkit-transition-property: overlay, display, opacity; transition-property: overlay, display, opacity; transition-duration: var(--speed); transition-behavior: allow-discrete; transition-timing-function: var(--ease); background: hsl(0 0% 0% / 0.25); opacity: 0; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); } [popover]::backdrop { transition-property: overlay, display, opacity; transition-duration: var(--speed); transition-behavior: allow-discrete; transition-timing-function: var(--ease); background: hsl(0 0% 0% / 0.25); opacity: 0; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); } [popover] button { background: #0000; border: none; padding: 0; color: inherit; cursor: pointer; } [data-alignment='right'] [popover]::-webkit-backdrop { -webkit-mask: linear-gradient(135deg, #0000 0%, #fff 100%); mask: linear-gradient(135deg, #0000 0%, #fff 100%); } [data-alignment='right'] [popover]::backdrop { -webkit-mask: linear-gradient(135deg, #0000 0%, #fff 100%); mask: linear-gradient(135deg, #0000 0%, #fff 100%); } [data-alignment='center'] [popover]::-webkit-backdrop { -webkit-mask: linear-gradient(180deg, #0000 0%, #fff 100%); mask: linear-gradient(180deg, #0000 0%, #fff 100%); } [data-alignment='center'] [popover]::backdrop { -webkit-mask: linear-gradient(180deg, #0000 0%, #fff 100%); mask: linear-gradient(180deg, #0000 0%, #fff 100%); } [data-alignment='left'] [popover]::-webkit-backdrop { -webkit-mask: linear-gradient(225deg, #0000 0%, #fff 100%); mask: linear-gradient(225deg, #0000 0%, #fff 100%); } [data-alignment='left'] [popover]::backdrop { -webkit-mask: linear-gradient(225deg, #0000 0%, #fff 100%); mask: linear-gradient(225deg, #0000 0%, #fff 100%); } [popover]:popover-open::-webkit-backdrop { opacity: 1; } [popover]:popover-open::backdrop { opacity: 1; } @starting-style { [popover]:popover-open::-webkit-backdrop { opacity: 0; } [popover]:popover-open::backdrop { opacity: 0; } } } @layer scroll { :root { timeline-scope: --content; } @property --progress { initial-value: 0; syntax: '<integer>'; inherits: true; } .trigger { anchor-name: --opener; position: fixed; bottom: var(--bottom); z-index: 9999999; view-transition-name: trigger; cursor: pointer; } :root { -webkit-animation: scroll-progress both linear; animation: scroll-progress both linear; animation-timeline: --content; } .content { scroll-timeline: --content; } @-webkit-keyframes scroll-progress { to { --progress: 100; } } @keyframes scroll-progress { to { --progress: 100; } } :root { counter-reset: progress var(--progress); } .progress { border-radius: 100px; background: light-dark(hsl(0 0% 35%), hsl(0 0% 0%)); padding: 0.25rem 0.5rem; } .progress::before { font-variant-numeric: tabular-nums; content: counter(progress) '%'; } } @layer demo { @media (prefers-reduced-motion: no-preference) { .content { scroll-behavior: smooth; } } body { height: 100svh; overflow: hidden; } @counter-style pad-it { system: extends decimal; pad: 2 '0'; } .content { width: 100vw; height: 100svh; overflow: auto; padding-block: 80px; -webkit-mask: linear-gradient(#0000, #fff 80px calc(100% - 80px), #0000); mask: linear-gradient(#0000, #fff 80px calc(100% - 80px), #0000); @media (max-width: 680px) { -webkit-mask: linear-gradient(#0000 60px, #fff 80px calc(100% - 80px), #0000); mask: linear-gradient(#0000 60px, #fff 80px calc(100% - 80px), #0000); } scrollbar-color: hsl(0 100% 40%) #0000; scrollbar-width: thin; } body { --font-level: 0; } h1 { --font-level: 4; text-wrap: balance; line-height: 1; margin: 0; margin-bottom: 2rem; span { font-size: 0.35em; } } header, main { width: 60ch; max-width: calc(100vw - 2rem); margin: 0 auto; } footer { padding: 1rem; font-size: 0.875rem; opacity: 0.875; text-align: center; } main { counter-reset: section; } section { counter-increment: section 1; } h2::before { content: counter(section, pad-it) '. '; } header p { font-size: 1.125rem; } section:not(:last-of-type) { margin-bottom: 6rem; } section { scroll-margin-top: 80px; } p { margin: 0; } h2 { margin: 0; text-wrap: balance; } h2 { margin-bottom: 1.25rem; } p:not(:last-of-type) { margin-bottom: 1rem; } main p { color: color-mix(in hsl, canvasText, canvas 10%); font-weight: 300; } hr { opacity: 0.5; } hr, header, main { margin-bottom: 6rem; } .heading { position: relative; display: flex; &:is(:hover, :focus-within) a { opacity: 1; } a { opacity: 0; width: 24px; aspect-ratio: 1; position: absolute; color: inherit; right: calc(100% + 0.5rem); top: 0; display: grid; place-items: center; transition: opacity 0.2s; outline-color: transparent; border-radius: 6px; &:focus-visible { background: color-mix(in hsl, canvasText, #0000 75%); } svg { width: 20px; } } } } @layer base { :root { --font-size-min: 14; --font-size-max: 16; --font-ratio-min: 1.2; --font-ratio-max: 1.33; --font-width-min: 375; --font-width-max: 1280; } html { color-scheme: light dark; } [data-theme='light'] { color-scheme: light only; } [data-theme='dark'] { color-scheme: dark only; } :where(.fluid) { --fluid-min: calc( var(--font-size-min) * pow(var(--font-ratio-min), var(--font-level, 0)) ); --fluid-max: calc( var(--font-size-max) * pow(var(--font-ratio-max), var(--font-level, 0)) ); --fluid-preferred: calc( (var(--fluid-max) - var(--fluid-min)) / (var(--font-width-max) - var(--font-width-min)) ); --fluid-type: clamp( (var(--fluid-min) / 16) * 1rem, ((var(--fluid-min) / 16) * 1rem) - (((var(--fluid-preferred) * var(--font-width-min)) / 16) * 1rem) + (var(--fluid-preferred) * var(--variable-unit, 100vi)), (var(--fluid-max) / 16) * 1rem ); font-size: var(--fluid-type); } *, *:after, *:before { box-sizing: border-box; } body { display: grid; place-items: center; min-height: 100vh; background: light-dark(white, black); font-family: 'SF Pro Text', 'SF Pro Icons', 'AOS Icons', 'Helvetica Neue', Helvetica, Arial, sans-serif, system-ui; } body::before { --size: 45px; --line: color-mix(in lch, canvasText, transparent 70%); content: ''; height: 100vh; width: 100vw; position: fixed; background: linear-gradient( 90deg, var(--line) 1px, transparent 1px var(--size) ) 50% 50% / var(--size) var(--size), linear-gradient(var(--line) 1px, transparent 1px var(--size)) 50% 50% / var(--size) var(--size); -webkit-mask: linear-gradient(-20deg, transparent 50%, white); mask: linear-gradient(-20deg, transparent 50%, white); top: 0; transform-style: flat; pointer-events: none; z-index: -1; } .bear-link { color: canvasText; position: fixed; top: 1rem; left: 1rem; width: 48px; aspect-ratio: 1; display: grid; place-items: center; opacity: 0.8; } :where(.x-link, .bear-link):is(:hover, :focus-visible) { opacity: 1; } .bear-link svg { width: 75%; } /* Utilities */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } } div.tp-dfwv { position: fixed; } @counter-style pad-example { system: extends decimal; suffix: ' '; pad: 2 ' '; } </style> </head> <body translate="no"> <button class="trigger" popovertarget="index" popovertargetaction="toggle"> <div class="trigger__details"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" > <mask id="mask0_3000_5" maskUnits="userSpaceOnUse" x="0" y="2" width="24" height="20" > <path d="M3 6.75L19.0541 6.75L21.027 6.75H23.0135L23 3.5L1 3.5L1 12L23 12L23.0135 21L1 21L1 17.25L13 17.25" stroke-width="2.5" stroke="gray" /> </mask> <g mask="url(#mask0_3000_5)"> <rect x="3" y="6" width="18" height="12" fill="gray" /> </g> <mask id="mask1_3000_5" maskUnits="userSpaceOnUse" x="0" y="2" width="24" height="20" > <path class="lines" d="M3 6.75L19.0541 6.75L21.027 6.75H23.0135L23 3.5L1 3.5L1 12L23 12L23.0135 21L1 21L1 17.25L13 17.25" stroke="white" stroke-width="2.5" pathLength="1.025" stroke-dasharray="1.025" stroke-dashoffset="1.025" /> </mask> <g mask="url(#mask1_3000_5)"> <rect x="3" y="6" width="18" height="12" fill="white" /> </g> </svg> <span> <span>Index</span ><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6" > <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9" /> </svg> </span> <span class="progress"></span> </div> </button> <div popover="auto" id="index"> <div class="contents"> <button popovertarget="index" popovertargetaction="hide"> <div class="trigger__details"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" > <mask id="mask0_3000_5" maskUnits="userSpaceOnUse" x="0" y="2" width="24" height="20" > <path d="M3 6.75L19.0541 6.75L21.027 6.75H23.0135L23 3.5L1 3.5L1 12L23 12L23.0135 21L1 21L1 17.25L13 17.25" stroke-width="2.5" stroke="gray" /> </mask> <g mask="url(#mask0_3000_5)"> <rect x="3" y="6" width="18" height="12" fill="gray" /> </g> <mask id="mask1_3000_5" maskUnits="userSpaceOnUse" x="0" y="2" width="24" height="20" > <path class="lines" d="M3 6.75L19.0541 6.75L21.027 6.75H23.0135L23 3.5L1 3.5L1 12L23 12L23.0135 21L1 21L1 17.25L13 17.25" stroke="white" stroke-width="2.5" pathLength="1.025" stroke-dasharray="1.025" stroke-dashoffset="1.025" /> </mask> <g mask="url(#mask1_3000_5)"> <rect x="3" y="6" width="18" height="12" fill="white" /> </g> </svg> <span> <span>Index</span ><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6" > <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9" /> </svg> </span> <span class="progress"></span> </div> </button> <ol> <li><a href="#user-centered-design">User-Centered Design</a></li> <li> <a href="#responsive-layouts" >Responsive Layouts and Visual Hierarchy</a > </li> <li> <a popovertarget="index" popovertargetaction="hide" href="#typography" .........完整代码请登录后点击上方下载按钮下载查看
网友评论0