起笔于 

Stellar代码块个人向美化

前言

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

思路

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

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

代码

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

代码块样式

ZYCode.css
: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而与代码语言重合, 已修复(也不算修复, 我把它写死了)

ZYCode.js
// 这四个常量是复制,复制成功,展开,收缩
// 我使用的是 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');
}
}

引入函数

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

引入样式

根目录/_config.stellar.yml
style:
codeblock:
highlightjs_theme: /custom/css/ZYCode.css

结语

你备份了吗?


本站由 @钟意 使用 Stellar 主题创建

本页面被看光 次 | 全站看光 次 | 总接客