前言 #
這個程式碼區塊是模仿 macOS 的視窗外觀(左上角的紅黃綠三個點),首先我參考了 Blog|自定義Hugo Blowfish主題
這篇文章,該作者是參考另一篇文章 Hugo Stack 主题装修笔记 Part 3
去修改,而這篇的作者則是從 hugo stack 主题美化
這篇文章發現的,原始的代碼來自於 linsnow.cn 的 Stack主题的自定义
(但這篇文章似乎進不去了),總之在文章開始前先感謝這4位作者的分享,讀者可以先去閱讀這幾篇文章。
我在上述的基礎上做了一點小更改,具體的外觀請見本文中的程式碼區塊,另外我在某個部落格看到折疊的樣式,忘記是哪個主題了,它預設只顯示上半部的內容,高度若是超過則需要點擊展開,我蠻喜歡的,於是請 Perplexity 幫我重現了這個樣式。
macOS 視窗樣式 #
編輯/assets/css路徑下的custom.css,添加:
/* 程式碼區塊容器樣式 */
.highlight {
max-width: 100%;
position: relative;
border-radius: 10px;
margin-left: -5px;
margin-right: -10px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
/* 添加 macOS 風格的標題欄 */
.highlight::before {
content: '';
height: 30px;
width: 100%;
background-color: rgba(var(--color-neutral-50));
display: block;
position: relative;
}
/* 深色模式下的标题栏样式 */
.dark .highlight::before {
background-color: rgba(var(--color-neutral-700));
}
/* 添加控制按钮 */
.highlight::after {
content: '';
position: absolute;
top: 9px;
left: 13px;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #ff5f56;
box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f;
z-index: 1;
}
/* 程式碼内容區塊樣式 */
.highlight pre {
margin: 0;
padding: 1.5rem;
width: auto;
}
.prose .chroma {
border-radius: 0;
}
折疊功能 #
這邊提供兩個樣式,如果你不使用上面的 macOS 樣式的話,直接使用第一種,如果你也使用我上面提供的 macOS 視窗樣式,請使用第二種
不使用 macOS 視窗樣式時 #
編輯 custom.css #
編輯/assets/css下的custom.css:
/* 程式碼區塊容器 */
.highlight {
position: relative;
margin: 1.5rem 0;
}
/* 折疊狀態 */
.highlight.collapsible {
max-height: 400px;
overflow: hidden;
transition: max-height 0.3s ease;
}
/* 展開狀態 */
.highlight.expanded {
max-height: none;
}
/* 漸層遮罩 */
.highlight.collapsible::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 80px;
background: linear-gradient(to bottom, transparent, var(--color-background));
pointer-events: none;
}
.highlight.expanded::after {
display: none;
}
/* 展開按鈕 */
.code-expand-btn {
display: block;
width: 100%;
padding: 0.5rem;
margin-top: 0.5rem;
background: var(--color-secondary);
border: 1px solid var(--color-border);
border-radius: var(--radius-base);
cursor: pointer;
font-size: 0.875rem;
text-align: center;
transition: background 0.2s;
}
.code-expand-btn:hover {
background: var(--color-secondary-hover);
}
新增 collapsible-code.js #
在 /static/js下創建collapsible-code.js
document.addEventListener('DOMContentLoaded', function() {
const codeBlocks = document.querySelectorAll('.highlight');
codeBlocks.forEach(function(block) {
// 檢查高度是否超過 400px
if (block.scrollHeight > 400) {
// 加上折疊樣式
block.classList.add('collapsible');
// 創建展開按鈕
const btn = document.createElement('button');
btn.className = 'code-expand-btn';
btn.innerHTML = '<span class="expand-text">展開完整程式碼 ▼</span><span class="collapse-text" style="display:none;">折疊程式碼 ▲</span>';
// 插入按鈕到程式碼區塊後面
block.parentNode.insertBefore(btn, block.nextSibling);
// 按鈕點擊事件
btn.addEventListener('click', function() {
const expandText = btn.querySelector('.expand-text');
const collapseText = btn.querySelector('.collapse-text');
if (block.classList.contains('collapsible')) {
block.classList.remove('collapsible');
block.classList.add('expanded');
expandText.style.display = 'none';
collapseText.style.display = 'inline';
} else {
block.classList.remove('expanded');
block.classList.add('collapsible');
expandText.style.display = 'inline';
collapseText.style.display = 'none';
block.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
}
});
});
使用 macOS 視窗樣式時 #
編輯 custom.css #
先將創建 macOS 視窗樣式時新增的 CSS 樣式刪除,在這邊會合併。
編輯/assets/css下的custom.css:
/* 程式碼區塊容器樣式 */
.highlight {
max-width: 100%;
position: relative;
border-radius: 10px;
margin-left: -5px;
margin-right: -10px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
/* 添加 macOS 風格標題欄 */
.highlight::before {
content: '';
height: 30px;
width: 100%;
background-color: rgba(var(--color-neutral-50));
display: block;
position: relative;
}
/* 深色模式下的標題欄樣式 */
.dark .highlight::before {
background-color: rgba(var(--color-neutral-700));
}
/* 添加控制按钮 */
.highlight::after {
content: '';
position: absolute;
top: 9px;
left: 13px;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #ff5f56;
box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f;
z-index: 1;
}
/* 程式碼區塊內容區域樣式 */
.highlight pre {
margin: 0;
padding: 1.5rem;
width: auto;
}
.prose .chroma {
border-radius: 0;
}
/* ===== 折疊功能樣式 ===== */
/* 折疊狀態 */
.highlight.collapsible {
max-height: 430px; /* 400px 內容 + 30px 標題欄 */
overflow: hidden;
transition: max-height 0.3s ease;
}
/* 展開狀態 */
.highlight.expanded {
max-height: none;
}
/* 漸層遮罩 - 使用獨立元素而非偽元素 */
.code-gradient {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 80px;
background: linear-gradient(to bottom, transparent, var(--color-background));
pointer-events: none;
z-index: 2;
}
/* 深色模式的漸層 */
.dark .code-gradient {
background: linear-gradient(to bottom, transparent, var(--color-charcoal-800));
}
/* 展開按鈕 */
.code-expand-btn {
display: block;
width: 100%;
padding: 0.5rem;
margin-top: 0.5rem;
background: var(--color-secondary);
border: 1px solid var(--color-border);
border-radius: var(--radius-base);
cursor: pointer;
font-size: 0.875rem;
text-align: center;
transition: background 0.2s;
}
.code-expand-btn:hover {
background: var(--color-secondary-hover);
}
新增 collapsible-code.js #
在 /static/js下創建collapsible-code.js
document.addEventListener('DOMContentLoaded', function() {
const codeBlocks = document.querySelectorAll('.highlight');
codeBlocks.forEach(function(block) {
// 檢查高度是否超過 400px (不含標題欄的30px)
const contentHeight = block.scrollHeight - 30;
if (contentHeight > 400) {
// 加上折疊樣式
block.classList.add('collapsible');
// 創建漸層遮罩
const gradient = document.createElement('div');
gradient.className = 'code-gradient';
block.appendChild(gradient);
// 創建展開按鈕
const btn = document.createElement('button');
btn.className = 'code-expand-btn';
btn.innerHTML = '<span class="expand-text">Expand Code ▼</span><span class="collapse-text" style="display:none;">Collapse Code ▲</span>';
// 插入按鈕到程式碼區塊後面
block.parentNode.insertBefore(btn, block.nextSibling);
// 按鈕點擊事件
btn.addEventListener('click', function() {
const expandText = btn.querySelector('.expand-text');
const collapseText = btn.querySelector('.collapse-text');
if (block.classList.contains('collapsible')) {
block.classList.remove('collapsible');
block.classList.add('expanded');
gradient.style.display = 'none';
expandText.style.display = 'none';
collapseText.style.display = 'inline';
} else {
block.classList.remove('expanded');
block.classList.add('collapsible');
gradient.style.display = 'block';
expandText.style.display = 'inline';
collapseText.style.display = 'none';
block.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
}
});
});
引入 JavaScript #
複製/themes/blowfish/layouts/_default/single.html到/layouts/_default/single.html並編輯,找到下面這段:
{{/* Body */}}
<section class="flex flex-col max-w-full mt-0 prose dark:prose-invert lg:flex-row">
<!-- 內容省略 -->
</section>
並在</section>下面一行插入:
<script src="{{ "js/collapsible-code.js" | relURL }}"></script>
single.html,並重新編輯。
折疊按鈕多語言設定 #
如果網站有多語言設定,要將展開(折疊)按鈕顯示為不同語言,可按照下方步驟更改。
編輯 JavaScript #
更改collapsible-code.js為:
document.addEventListener('DOMContentLoaded', function() {
const codeBlocks = document.querySelectorAll('.highlight');
// 從 HTML 讀取翻譯文字,預設為英文
const expandText = document.documentElement.dataset.expandText || 'Expand Code ▼';
const collapseText = document.documentElement.dataset.collapseText || 'Collapse Code ▲';
codeBlocks.forEach(function(block) {
const contentHeight = block.scrollHeight - 30;
if (contentHeight > 400) {
block.classList.add('collapsible');
const gradient = document.createElement('div');
gradient.className = 'code-gradient';
block.appendChild(gradient);
const btn = document.createElement('button');
btn.className = 'code-expand-btn';
btn.innerHTML = '<span class="expand-text">' + expandText + '</span><span class="collapse-text" style="display:none;">' + collapseText + '</span>';
block.parentNode.insertBefore(btn, block.nextSibling);
btn.addEventListener('click', function() {
const expandSpan = btn.querySelector('.expand-text');
const collapseSpan = btn.querySelector('.collapse-text');
if (block.classList.contains('collapsible')) {
block.classList.remove('collapsible');
block.classList.add('expanded');
gradient.style.display = 'none';
expandSpan.style.display = 'none';
collapseSpan.style.display = 'inline';
} else {
block.classList.remove('expanded');
block.classList.add('collapsible');
gradient.style.display = 'block';
expandSpan.style.display = 'inline';
collapseSpan.style.display = 'none';
block.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
}
});
});
引入 JavaScript #
一樣編輯single.html,在剛剛加入:
<script src="{{ "js/collapsible-code.js" | relURL }}"></script>
的上面一行加入:
<script>
document.documentElement.dataset.expandText = "{{ i18n "shortcode.collapsible-code.expand" }}";
document.documentElement.dataset.collapseText = "{{ i18n "shortcode.collapsible-code.collapse" }}";
</script>
編輯 i18n 設定檔 #
這邊以繁中為例,我的檔名為zh-TW.yaml。
在檔案中找到加入:
shortcode:
collapsible-code:
expand: "展開完整程式碼 ▼"
collapse: "折疊程式碼 ▲"
按照上方的步驟編輯後,你就可以得到「macOS 視窗樣式」並且「限制高度、可折疊」的程式碼區塊。
透過郵件回覆