Stellar代码块个人向美化

Posted on 2026-03-03 16:59  笔名钟意  阅读(1)  评论(0)    收藏  举报

前言

增加主题控制后代码块样式有些唐突, 遂改之.

思路

不改变主题代码情况下思路的主旋律按以下走:

  1. 代码块随主题颜色变更
  2. 增加复制代码功能 (来源whbbit)
  3. 增加代码过长折叠

代码

下面直接成品, 有需求自定义修改

代码块样式

:root{
    --code-autor: '© 钟意博客🌙';
    --code-tip: "优雅借鉴";
} 

 /*语法高亮*/
 .hljs {
     position: relative;
     display: block;
     overflow-x: hidden;
     /*背景跟随Stellar*/
     background: var(--block);
     color: #9c67a1;
     padding: 30px 5px 2px 5px;
     box-shadow: 0 10px 30px 0px rgb(0 0 0 / 40%)
 }

 .hljs::before {
     content: var(--code-tip);
     position: absolute;
     left: 15px;
     top: 10px;
     overflow: visible;
     width: 12px;
     height: 12px;
     border-radius: 16px;
     box-shadow: 20px 0 #a9a6a1, 40px 0 #999;
     -webkit-box-shadow: 20px 0 #999, 40px 0 #999;
     background-color: #999;
     white-space: nowrap;
     text-indent: 75px;
     font-size: 16px;
     line-height: 12px;
     font-weight: 700;
     color: #999
 }

 .highlight:hover .hljs::before {
     color: #35cd4b;
     box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b;
     -webkit-box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b;
     background-color: #fc625d;
 }

 .hljs-ln {
     display: inline-block;
     overflow-x: auto;
     padding-bottom: 5px
 }

 .hljs-ln td {
     padding: 0;
     background-color: var(--block)
 }

 .hljs-ln::-webkit-scrollbar {
     height: 10px;
     border-radius: 5px;
     background: #333;
 }

 .hljs-ln::-webkit-scrollbar-thumb {
     background-color: #bbb;
     border-radius: 5px;
 }

 .hljs-ln::-webkit-scrollbar-thumb:hover {
     background: #ddd;
 }

 .hljs table tbody tr {
     border: none
 }

 .hljs .hljs-ln-line {
     padding: 1px 10px;
     border: none
 }

 td.hljs-ln-line.hljs-ln-numbers {
     border-right: 1px solid #666;
 }

 .hljs-keyword,
 .hljs-literal,
 .hljs-symbol,
 .hljs-name {
     color: #c78300
 }

 .hljs-link {
     color: #569cd6;
     text-decoration: underline
 }

 .hljs-built_in,
 .hljs-type {
     color: #4ec9b0
 }

 .hljs-number,
 .hljs-class {
     color: #2094f3
 }

 .hljs-string,
 .hljs-meta-string {
     color: #4caf50
 }

 .hljs-regexp,
 .hljs-template-tag {
     color: #9a5334
 }

 .hljs-subst,
 .hljs-function,
 .hljs-title,
 .hljs-params,
 .hljs-formula {
     color: #c78300
 }

 .hljs-property {
     color: #9c67a1;
 }

 .hljs-comment,
 .hljs-quote {
     color: #57a64a;
     font-style: italic
 }

 .hljs-doctag {
     color: #608b4e
 }

 .hljs-meta,
 .hljs-meta-keyword,
 .hljs-tag {
     color: #9b9b9b
 }

 .hljs-variable,
 .hljs-template-variable {
     color: #bd63c5
 }

 .hljs-attr,
 .hljs-attribute,
 .hljs-builtin-name {
     color: #d34141
 }

 .hljs-section {
     color: gold
 }

 .hljs-emphasis {
     font-style: italic
 }

 .hljs-strong {
     font-weight: bold
 }

 .hljs-bullet,
 .hljs-selector-tag,
 .hljs-selector-id,
 .hljs-selector-class,
 .hljs-selector-attr,
 .hljs-selector-pseudo {
     color: #c78300
 }

 .hljs-addition {
     background-color: #144212;
     display: inline-block;
     width: 100%
 }

 .hljs-deletion {
     background-color: #600;
     display: inline-block;
     width: 100%
 }

 .hljs.language-html::before,
 .hljs.language-xml::before {
     content: "HTML/XML"
 }

 .hljs.language-javascript::before {
     content: "JavaScript"
 }

 .hljs.language-c::before {
     content: "C"
 }

 .hljs.language-cpp::before {
     content: "C++"
 }

 .hljs.language-java::before {
     content: "Java"
 }

 .hljs.language-asp::before {
     content: "ASP"
 }

 .hljs.language-actionscript::before {
     content: "ActionScript/Flash/Flex"
 }

 .hljs.language-bash::before {
     content: "Bash"
 }

 .hljs.language-css::before {
     content: "CSS"
 }

 .hljs.language-asp::before {
     content: "ASP"
 }

 .hljs.language-cs::before,
 .hljs.language-csharp::before {
     content: "C#"
 }

 .hljs.language-d::before {
     content: "D"
 }

 .hljs.language-golang::before,
 .hljs.language-go::before {
     content: "Go"
 }

 .hljs.language-json::before {
     content: "JSON"
 }

 .hljs.language-lua::before {
     content: "Lua"
 }

 .hljs.language-less::before {
     content: "LESS"
 }

 .hljs.language-md::before,
 .hljs.language-markdown::before,
 .hljs.language-mkdown::before,
 .hljs.language-mkd::before {
     content: "Markdown"
 }

 .hljs.language-mm::before,
 .hljs.language-objc::before,
 .hljs.language-obj-c::before,
 .hljs.language-objective-c::before {
     content: "Objective-C"
 }

 .hljs.language-php::before {
     content: "PHP"
 }

 .hljs.language-perl::before,
 .hljs.language-pl::before,
 .hljs.language-pm::before {
     content: "Perl"
 }

 .hljs.language-python::before,
 .hljs.language-py::before,
 .hljs.language-gyp::before,
 .hljs.language-ipython::before {
     content: "Python"
 }

 .hljs.language-r::before {
     content: "R"
 }

 .hljs.language-ruby::before,
 .hljs.language-rb::before,
 .hljs.language-gemspec::before,
 .hljs.language-podspec::before,
 .hljs.language-thor::before,
 .hljs.language-irb::before {
     content: "Ruby"
 }

 .hljs.language-sql::before {
     content: "SQL"
 }

 .hljs.language-sh::before,
 .hljs.language-shell::before,
 .hljs.language-Session::before,
 .hljs.language-shellsession::before,
 .hljs.language-console::before {
     content: "Shell"
 }

 .hljs.language-swift::before {
     content: "Swift"
 }

 .hljs.language-vb::before {
     content: "VB/VBScript"
 }

 .hljs.language-yaml::before {
     content: "YAML"
 }

 /*stellar主题补偿*/
 .md-text pre>.hljs {
     padding-top: 2rem !important;
 }

 .md-text pre {
     padding: 0 !important;
 }

 code {
     background-image: linear-gradient(90deg, rgba(60, 10, 30, .04) 3%, transparent 0), linear-gradient(1turn, rgba(60, 10, 30, .04) 3%, transparent 0) !important;
     background-size: 20px 20px !important;
     background-position: 50% !important;
 }

 figure::after {
     content: var(--code-autor);
     text-align: right;
     font-size: 10px;
     float: right;
     margin-top: 3px;
     padding-right: 15px;
     padding-bottom: 8px;
     color: #999
 }

 figcaption span {
     border-radius: 0px 0px 12px 12px !important;
 }


 /* 复制代码按钮 */
 .highlight {
     position: relative;
 }

 .highlight .code .copy-btn {
     position: absolute;
     top: 0;
     right: 0;
     padding: 4px 0.5rem;
     opacity: 0.25;
     font-weight: 700;
     color: var(--theme);
     cursor: pointer;
     transination: opacity 0.3s;
 }

 .highlight .code .copy-btn:hover {
     color: var(--text-code);
     opacity: 0.75;
 }

 .highlight .code .copy-btn.success {
     color: var(--swiper-theme-color);
     opacity: 0.75;
 }

 /* 描述 */
 .md-text .highlight figcaption span {
     font-size: small;
 }

 /* 折叠 */
 code.hljs {
     display: -webkit-box;
     overflow: hidden;
     text-overflow: ellipsis;
     -webkit-box-orient: vertical;
     /*-webkit-line-clamp: 6;*/
     padding: 1rem 1rem 0 1rem; /* chino建议 */
 }

 .hljsOpen {
     -webkit-line-clamp: 99999 !important;
 }
 .CodeCloseDiv {
    color: #999;
    background: var(--block);
    display: flex;
    justify-content: center;
    margin-top: inherit;
    margin-bottom: -18px;
 }
 .CodeClose {
     color: #999;
     margin-top: 3px;
     background: var(--block);
 }

 .highlight button:hover,
 .highlight table:hover+button {
     color: var(--swiper-theme-color);
     opacity: 0.75;
 }

执行函数

原作者复制代码
会因为tabs这种标签的display:none而与代码语言重合, 已修复(也不算修复, 我把它写死了)

// 这四个常量是复制,复制成功,展开,收缩
// 我使用的是 https://fontawesome.com/ 图标, 不用可以改为文字.
const copyText = '<i class="fa-regular fa-copy"  style="color: #aa69ec;"></i>';
const copySuccess = '<i class="fa-regular fa-circle-check"  style="color: limegreen;"></i>';
const openText = '<i class="fa-solid fa-angles-down  fa-beat-fade"></i>';
const closeText = '<i class="fa-solid fa-angles-up  fa-beat-fade"></i>';

const codeElements = document.querySelectorAll('td.code');

codeElements.forEach((code, index) => {
    const preCode = code.querySelector('pre');

    // 设置id和样式
    preCode.id = `ZYCode${index+1}`;
    preCode.style.webkitLineClamp = '6';

    // 添加展开/收起按钮
    if (preCode.innerHTML.split('<br>').length > 6) {
        const codeCopyDiv = document.createElement('div');
        codeCopyDiv.classList.add('CodeCloseDiv');
        code.parentNode.parentNode.parentNode.parentNode.appendChild(codeCopyDiv);

        const codeCopyOver = document.createElement('button');
        codeCopyOver.classList.add('CodeClose');
        codeCopyOver.innerHTML = openText;

        const parent = code.parentNode.parentNode.parentNode.parentNode;
        const description = parent.childNodes.length === 3 ? parent.children[2] : parent.children[1];
        description.appendChild(codeCopyOver);

        codeCopyOver.addEventListener('click', () => {
            if (codeCopyOver.innerHTML === openText) {
                const scrollTop = document.documentElement.scrollTop;
                const codeHeight = code.clientHeight;

                if (scrollTop < codeHeight) {
                    document.documentElement.scrollTop += codeHeight - scrollTop;
                }

                preCode.style.webkitLineClamp = '99999';
                codeCopyOver.innerHTML = closeText;
            } else {
                preCode.style.webkitLineClamp = '6';
                codeCopyOver.innerHTML = openText;
            }
        });
    }

    // 添加复制按钮
    const codeCopyBtn = document.createElement('div');
    codeCopyBtn.classList.add('copy-btn');
    codeCopyBtn.innerHTML = copyText;
    code.appendChild(codeCopyBtn);

    // 添加复制功能
    codeCopyBtn.addEventListener('click', async () => {
        const currentCodeElement = code.querySelector('pre')?.innerText;
        await copyCode(currentCodeElement);

        codeCopyBtn.innerHTML = copySuccess;
        codeCopyBtn.classList.add('success');

        setTimeout(() => {
            codeCopyBtn.innerHTML = copyText;
            codeCopyBtn.classList.remove('success');
        }, 3000);
    });
});

async function copyCode(currentCode) {
    if (navigator.clipboard) {
        try {
            await navigator.clipboard.writeText(currentCode);
        } catch (error) {
            console.error(error);
        }
    } else {
        console.error('当前浏览器不支持此API');
    }
}

引入函数

# 自定义引入css,js
inject:
  script:
    - <script type="text/javascript" src="/custom/js/ZYCode.js"></script>

引入样式

style:
  codeblock:
    highlightjs_theme: /custom/css/ZYCode.css

结语

你备份了吗?