Khung Chứa Code Pro UX Giao Diện Highlight.js Đẹp Cho Blogger

Chia sẻ khung chứa code Pro UX với Highlight.js, giao diện đẹp, hỗ trợ copy, tải xuống, mở CodePen, tối ưu cho Blogger.

Chào anh em, mình là một sinh viên IT đang xây dựng blog cá nhân và thường xuyên chia sẻ những thủ thuật nhỏ cho cộng đồng Blogger. Khi viết bài có chèn code, mình luôn băn khoăn làm sao để có một khung chứa code vừa đẹp, vừa tiện dụng mà lại dễ tích hợp. Sau nhiều lần thử nghiệm, mình đã tìm ra một giải pháp cực kỳ ưng ý đó là khung chứa code Pro UX dựa trên Highlight.js.

Điều khiến mình muốn chia sẻ là không chỉ làm cho code nổi bật, dễ đọc hơn, mà khung này còn mang lại trải nghiệm rất "xịn sò" cho người dùng. Blog có khung chứa code gọn gàng, hiện đại sẽ giúp anh em nhìn chuyên nghiệp hơn hẳn. Và tất nhiên, mình sẽ để lại full code để mọi người có thể copy-paste vào Blogger và dùng ngay. Bài viết này được viết bởi TruongDevs, hi vọng sẽ hữu ích cho anh em đang tìm một giải pháp hiển thị code tối ưu.

khung chua code blogger
Khung chứa code đẹp mắt cho Blogger mới nhất

Khung chứa code là gì?

Trong quá trình viết blog, chắc hẳn nhiều anh em từng cần chèn một đoạn code để minh họa. Nếu chỉ dùng thẻ <pre><code> mặc định của HTML thì đoạn code sẽ hiển thị khá đơn giản, đôi khi khó đọc và không bắt mắt. Đây là lúc khung chứa code phát huy tác dụng.

Hiểu một cách dễ nhất, khung chứa code chính là một phần tử giao diện được thiết kế để bao bọc đoạn code, giúp nó hiển thị rõ ràng, đẹp mắt và dễ thao tác hơn. Thay vì để người đọc phải copy thủ công từng dòng, một khung chứa code hiện đại có thể kèm sẵn nút Copy, Download hoặc thậm chí mở code trực tiếp trên CodePen. Điều này không chỉ cải thiện trải nghiệm người dùng mà còn làm cho blog trông chuyên nghiệp và đáng tin cậy hơn.

Vì sao Blogger nên dùng khung chứa code Pro UX

Khi bắt đầu viết blog, mình từng nghĩ chỉ cần chèn code vào bài là đủ. Nhưng sau một thời gian, mình nhận ra rằng cách hiển thị code ảnh hưởng rất nhiều đến trải nghiệm của người đọc. Một khung chứa code được tối ưu không chỉ làm đoạn code dễ theo dõi hơn, mà còn giúp blog trở nên chuyên nghiệp, gọn gàng và tạo ấn tượng tốt ngay từ lần xem đầu tiên.

Điểm đặc biệt của khung chứa code Pro UX nằm ở chỗ nó không chỉ dừng lại ở phần giao diện. Khung này được tích hợp sẵn nhiều tính năng hữu ích như nút Copy để sao chép nhanh, nút Download để tải file, và cả khả năng mở code trực tiếp trên CodePen. Nhờ vậy, người đọc không chỉ xem mà còn có thể tương tác và thử nghiệm ngay lập tức. Đây chính là yếu tố giúp blog của bạn khác biệt và ghi điểm trong mắt cộng đồng.

Những ngôn ngữ lập trình được hỗ trợ

Một ưu điểm lớn của khung chứa code Pro UX chính là khả năng hỗ trợ rất nhiều ngôn ngữ lập trình khác nhau. Nhờ đó, anh em có thể thoải mái chia sẻ code từ HTML, CSS, JavaScript cho tới Python, Java, PHP, C++, và nhiều ngôn ngữ khác. Bảng bên dưới hiển thị danh sách đầy đủ các ngôn ngữ được hỗ trợ. Nếu bạn thấy thiếu ngôn ngữ hoặc danh sách chưa cập nhật, hãy liên hệ với mình để bổ sung nhé.

Language Key Class
Markup markup language-markup
CSS css language-css
C-like clike language-clike
JavaScript javascript language-javascript
ABAP abap language-abap
ActionScript actionscript language-actionscript
Ada ada language-ada
Apache Configuration apacheconf language-apacheconf
APL apl language-apl
AppleScript applescript language-applescript
Arduino arduino language-arduino
ARFF arff language-arff
AsciiDoc asciidoc language-asciidoc
6502 Assembly asm6502 language-asm6502
ASP.NET (C#) aspnet language-aspnet
AutoHotkey autohotkey language-autohotkey
AutoIt autoit language-autoit
Bash bash language-bash
BASIC basic language-basic
Batch batch language-batch
Bison bison language-bison
Brainfuck brainfuck language-brainfuck
Bro bro language-bro
C c language-c
C# csharp language-csharp
C++ cpp language-cpp
CoffeeScript coffeescript language-coffeescript
Clojure clojure language-clojure
Crystal crystal language-crystal
Content-Security-Policy csp language-csp
CSS Extras css-extras language-css-extras
D d language-d
Dart dart language-dart
Diff diff language-diff
Django/Jinja2 django language-django
Docker docker language-docker
Eiffel eiffel language-eiffel
Elixir elixir language-elixir
Elm elm language-elm
ERB erb language-erb
Erlang erlang language-erlang
F# fsharp language-fsharp
Flow flow language-flow
Fortran fortran language-fortran
GEDCOM gedcom language-gedcom
Gherkin gherkin language-gherkin
Git git language-git
GLSL glsl language-glsl
GameMaker Language gml language-gml
Go go language-go
GraphQL graphql language-graphql
Groovy groovy language-groovy
Haml haml language-haml
Handlebars handlebars language-handlebars
Haskell haskell language-haskell
Haxe haxe language-haxe
HTTP http language-http
HTTP Public-Key-Pins hpkp language-hpkp
HTTP Strict-Transport-Security hsts language-hsts
IchigoJam ichigojam language-ichigojam
Icon icon language-icon
Inform 7 inform7 language-inform7
Ini ini language-ini
Io io language-io
J j language-j
Java java language-java
Jolie jolie language-jolie
JSON json language-json
Julia julia language-julia
Keyman keyman language-keyman
Kotlin kotlin language-kotlin
LaTeX latex language-latex
Less less language-less
Liquid liquid language-liquid
Lisp lisp language-lisp
LiveScript livescript language-livescript
LOLCODE lolcode language-lolcode
Lua lua language-lua
Makefile makefile language-makefile
Markdown markdown language-markdown
Markup templating markup-templating language-markup-templating
MATLAB matlab language-matlab
MEL mel language-mel
Mizar mizar language-mizar
Monkey monkey language-monkey
N4JS n4js language-n4js
NASM nasm language-nasm
nginx nginx language-nginx
Nim nim language-nim
Nix nix language-nix
NSIS nsis language-nsis
Objective-C objectivec language-objectivec
OCaml ocaml language-ocaml
OpenCL opencl language-opencl
Oz oz language-oz
PARI/GP parigp language-parigp
Parser parser language-parser
Pascal pascal language-pascal
Perl perl language-perl
PHP php language-php
PHP Extras php-extras language-php-extras
PL/SQL plsql language-plsql
PowerShell powershell language-powershell
Processing processing language-processing
Prolog prolog language-prolog
.properties properties language-properties
Protocol Buffers protobuf language-protobuf
Pug pug language-pug
Puppet puppet language-puppet
Pure pure language-pure
Python python language-python
Q (kdb+ database) q language-q
Qore qore language-qore
R r language-r
React JSX jsx language-jsx
React TSX tsx language-tsx
Ren'py renpy language-renpy
Reason reason language-reason
reST (reStructuredText) rest language-rest
Rip rip language-rip
Roboconf roboconf language-roboconf
Ruby ruby language-ruby
Rust rust language-rust
SAS sas language-sas
Sass (Sass) sass language-sass
Sass (Scss) scss language-scss
Scala scala language-scala
Scheme scheme language-scheme
Smalltalk smalltalk language-smalltalk
Smarty smarty language-smarty
SQL sql language-sql
Soy (Closure Template) soy language-soy
Stylus stylus language-stylus
Swift swift language-swift
TAP tap language-tap
Tcl tcl language-tcl
Textile textile language-textile
Template Toolkit 2 tt2 language-tt2
Twig twig language-twig
TypeScript typescript language-typescript
VB.Net vbnet language-vbnet
Velocity velocity language-velocity
Verilog verilog language-verilog
VHDL vhdl language-vhdl
vim vim language-vim
Visual Basic visual-basic language-visual-basic
WebAssembly wasm language-wasm
Wiki markup wiki language-wiki
Xeora xeora language-xeora
Xojo (REALbasic) xojo language-xojo
XQuery xquery language-xquery
YAML yaml language-yaml
Thông tin! Danh sách trên chỉ là một phần. Khung chứa code Pro UX còn hỗ trợ hàng trăm ngôn ngữ khác như Kotlin, Swift, Scala, Haskell, Dockerfile, LaTeX, v.v. Nếu bạn muốn tìm hiểu thêm hoặc cần bổ sung ngôn ngữ cụ thể, đừng ngần ngại liên hệ với mình nhé.

Cách tích hợp khung chứa code Pro UX vào Blogger

Để thêm khung chứa code Pro UX vào Blogger, bạn chỉ cần làm theo một vài bước đơn giản. Không cần cài đặt plugin phức tạp, chỉ cần copy và dán đoạn mã là có thể dùng ngay.

  1. Mở Blogger, vào phần Chủ đề (Theme) và chọn Chỉnh sửa HTML.
  2. Kéo xuống cuối trang, tìm thẻ </body>.
  3. Dán toàn bộ đoạn mã CSS + JavaScript của khung chứa code Pro UX ngay trước thẻ </body>, rồi lưu lại.
    <!-- Highlight.js theme (có thể đổi sang theme khác của HLJS) -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css" />
    
    <style>
      :root {
        --cbg: #0f1117;
        --ring: rgba(0, 0, 0, .08);
        --border: rgba(255, 255, 255, .10);
        --muted: #8b93a7;
        --acc: #0ea5e9;
        --text: #e6edf3;
        --btn-bg: rgba(255, 255, 255, .06);
        --btn-br: rgba(255, 255, 255, .12);
        --btn-bg-h: rgba(255, 255, 255, .10);
        /* tone scrollbar siêu nhẹ */
        --sb-thumb: rgba(255, 255, 255, .22);
        --sb-thumb-h: rgba(255, 255, 255, .32);
        --sb-track: transparent;
      }
    
      .td-codeblock {
        margin: 1rem 0;
        border: 1px solid var(--border);
        border-radius: 14px;
        background: var(--cbg);
        box-shadow: 0 6px 24px var(--ring);
        overflow: hidden;
      }
    
      /* Header / Toolbar */
      .td-codebar {
        display: grid;
        grid-template-columns: 1fr auto;
        gap: .5rem;
        align-items: center;
        padding: .6rem .75rem;
        background: linear-gradient(180deg, rgba(255, 255, 255, .06), transparent);
        border-bottom: 1px solid var(--border);
      }
    
      .td-filemeta {
        display: flex;
        align-items: center;
        gap: .55rem;
        font: 600 12px/1.2 ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto;
        color: var(--muted)
      }
    
      .td-dot {
        width: .55rem;
        height: .55rem;
        border-radius: 999px;
        background: #ff6b6b;
        box-shadow: .9rem 0 0 #ffd93d, 1.8rem 0 0 #6bcB77;
        margin-right: 1.4rem;
        opacity: .95
      }
    
      .td-lang {
        color: var(--acc);
        font-weight: 700
      }
    
      .td-fname {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: var(--muted)
      }
    
      .td-actions {
        display: flex;
        align-items: center;
        gap: .5rem;
      }
    
      .td-btn {
        display: inline-flex;
        align-items: center;
        gap: .45rem;
        padding: .5rem .65rem;
        border: 1px solid var(--btn-br);
        background: var(--btn-bg);
        color: var(--text);
        border-radius: 12px;
        cursor: pointer;
        user-select: none;
        font: 600 12px/1 ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto;
        transition: background .15s ease, transform .1s ease;
      }
    
      .td-btn:hover {
        background: var(--btn-bg-h)
      }
    
      .td-btn:active {
        transform: translateY(1px)
      }
    
      .td-btn svg {
        width: 15px;
        height: 15px;
        display: block
      }
    
      @media (max-width:640px) {
        .td-btn .td-label {
          display: none
        }
    
        /* di động: chỉ icon */
        .td-fname {
          display: none
        }
      }
    
      /* Code area (auto height theo nội dung) */
      .td-code {
        position: relative;
        overflow: auto
      }
    
      .td-code pre {
        margin: 0;
        padding: 1rem 1.1rem 1.25rem;
        background: transparent
      }
    
      /* Scrollbar mảnh – chỉ lộ khi hover */
      /* Firefox */
      .td-code {
        scrollbar-width: thin;
        scrollbar-color: transparent var(--sb-track);
      }
    
      .td-code:hover {
        scrollbar-color: var(--sb-thumb) var(--sb-track);
      }
    
      /* WebKit */
      .td-code::-webkit-scrollbar {
        height: 8px;
        width: 8px;
        background: var(--sb-track);
      }
    
      .td-code::-webkit-scrollbar-thumb {
        background: transparent;
        border-radius: 999px;
        border: 2px solid transparent;
        background-clip: padding-box;
      }
    
      .td-code:hover::-webkit-scrollbar-thumb {
        background: var(--sb-thumb);
      }
    
      .td-code::-webkit-scrollbar-thumb:hover {
        background: var(--sb-thumb-h);
      }
    
      .td-code::-webkit-scrollbar-corner {
        background: transparent;
      }
    
      /* Line numbers (plugin) */
      .hljs-ln td {
        padding: 0 !important;
        vertical-align: top
      }
    
      .hljs-ln .hljs-ln-numbers {
        user-select: none;
        text-align: right;
        color: var(--muted);
        padding: 0 .75rem 0 1rem !important;
        border-right: 1px solid var(--border);
        width: 2.75rem;
        min-width: 2.75rem;
      }
    
      .hljs-ln .hljs-ln-code {
        padding-left: .75rem !important;
      }
    
      /* Toast */
      .td-codeblock {
        position: relative;
        margin: 1rem 0;
        border: 1px solid var(--border);
        border-radius: 14px;
        background: var(--cbg);
        box-shadow: 0 6px 24px var(--ring);
        overflow: hidden;
      }
    
      .td-toast {
        position: absolute;
        bottom: 10px;
        left: 50%;
        transform: translateX(-50%);
        background: rgba(20, 180, 120, .12);
        color: #00c389;
        border: 1px solid rgba(0, 195, 137, .35);
        padding: .5rem .75rem;
        border-radius: 10px;
        display: none;
        z-index: 3;
        pointer-events: none;
      }
    
      .td-toast.show {
        display: block;
        animation: td-fade 1.6s ease forwards;
      }
    
      .td-toast {
        left: auto;
        right: 12px;
        transform: none;
      }
    
      @keyframes td-fade {
        0% {
          opacity: 0;
          transform: translateY(6px)
        }
    
        15%,
        80% {
          opacity: 1;
          transform: translateY(0)
        }
    
        100% {
          opacity: 0
        }
      }
    </style>
    <!-- highlight.js core + line numbers plugin -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js"></script>
    
    <script>
    /*! TruongDevs CodeBlock UX — Compact toolbar (Copy · Open · Download · CodePen), Lines ON */
    (function(){
      const LANGUAGE_MAP = {
        'markup':'html','html':'html','xml':'xml','css':'css','scss':'scss','sass':'sass','less':'less','stylus':'styl',
        'javascript':'js','js':'js','jsx':'jsx','typescript':'ts','ts':'ts','tsx':'tsx',
        'json':'json','yaml':'yml','yml':'yml','toml':'toml','ini':'ini','properties':'properties',
        'bash':'sh','shell':'sh','zsh':'sh','powershell':'ps1','ps':'ps1',
        'sql':'sql','graphql':'graphql','gql':'graphql',
        'python':'py','py':'py','java':'java','kotlin':'kt','swift':'swift',
        'c':'c','cpp':'cpp','c++':'cpp','h':'h','hpp':'hpp',
        'csharp':'cs','cs':'cs','vbnet':'vb','visual-basic':'vb',
        'go':'go','golang':'go','rust':'rs','dart':'dart','php':'php','ruby':'rb',
        'r':'r','matlab':'m','fortran':'f90','scala':'scala','haskell':'hs','clojure':'clj','lisp':'lisp','scheme':'scm','ocaml':'ml',
        'elixir':'ex','erlang':'erl','fsharp':'fs','prolog':'pl','julia':'jl','groovy':'groovy','perl':'pl','lua':'lua','nim':'nim',
        'docker':'dockerfile','dockerfile':'dockerfile','nginx':'nginx','apacheconf':'conf','makefile':'mk','cmake':'cmake','diff':'diff','git':'git',
        'abap':'abap','actionscript':'as','ada':'ada','apl':'apl','applescript':'applescript','arduino':'ino','arff':'arff','asciidoc':'adoc',
        'asm6502':'asm','aspnet':'cshtml','autohotkey':'ahk','autoit':'au3','basic':'bas','batch':'bat','bison':'bison','brainfuck':'b','bro':'bro',
        'csp':'csp','css-extras':'css','d':'d','django':'jinja','eiffel':'e','elm':'elm','erb':'erb',
        'flow':'js','gedcom':'ged','gherkin':'feature','glsl':'glsl','gml':'gml','haml':'haml','handlebars':'hbs','haxe':'hx','hpkp':'hpkp','hsts':'hsts',
        'ichigojam':'ijm','icon':'icn','inform7':'ni','io':'io','j':'j','jolie':'ol','keyman':'kmn','latex':'tex','liquid':'liquid',
        'livescript':'ls','lolcode':'lol','mel':'mel','mizar':'miz','monkey':'monkey','n4js':'n4js','nasm':'asm','nix':'nix','nsis':'nsi',
        'objectivec':'m','opencl':'cl','oz':'oz','parigp':'gp','parser':'pegjs','pascal':'pas','plsql':'sql','processing':'pde','protobuf':'proto',
        'pug':'pug','puppet':'pp','pure':'pure','q':'q','qore':'q','reason':'re','renpy':'rpy','rest':'rst','rip':'rip','roboconf':'graph',
        'sas':'sas','smarty':'tpl','soy':'soy','tap':'tap','tcl':'tcl','textile':'textile','tt2':'tt2','twig':'twig','velocity':'vm','verilog':'v','vhdl':'vhd',
        'vim':'vim','wiki':'wiki','xeora':'xeora','xojo':'xojo','xquery':'xq','wasm':'wasm'
      };
      const NORMALIZE = { 'htm':'html','shell':'bash','sh':'bash','plaintext':'text','plain':'text','objective-c':'objectivec','c#':'csharp','c++':'cpp' };
    
      const icons = {
        copy:'<svg viewBox="0 0 24 24" fill="none"><path d="M9 9.5A2.5 2.5 0 0 1 11.5 7H18a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-6.5A2.5 2.5 0 0 1 9 17.5v-8Z" stroke="currentColor" stroke-width="1.5"/><path d="M6 15.5A2.5 2.5 0 0 1 3.5 13V6a2 2 0 0 1 2-2H12a2 2 0 0 1 2 2" stroke="currentColor" stroke-width="1.5"/></svg>',
        open:'<svg viewBox="0 0 24 24" fill="none"><path d="M14 5h5v5M10 14 19 5M13 10H6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="1.5"/></svg>',
        download:'<svg viewBox="0 0 24 24" fill="none"><path d="M12 3v11m0 0 3-3m-3 3-3-3M4 21h16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',
        codepen:'<svg viewBox="0 0 24 24" fill="none"><path d="M12 3 3 9v6l9 6 9-6V9l-9-6Zm0 0v18M3 9l9 6m9-6-9 6M3 15l9-6m9 6-9-6" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>'
      };
    
      function getLangAndExt(codeEl){
        let lang = 'text';
        for (const cls of codeEl.classList){ if (cls.startsWith('language-')){ lang = cls.replace('language-','').toLowerCase(); break; } }
        lang = NORMALIZE[lang] || lang;
        const ext = LANGUAGE_MAP[lang] || (lang==='text' ? 'txt' : lang);
        return { lang, ext };
      }
      const esc = s => s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');
      function toast(wrap,msg){ const t = wrap.querySelector('.td-toast'); t.textContent = msg; t.classList.remove('show'); void t.offsetWidth; t.classList.add('show'); }
    
      function enhance(code){
        const pre = code.parentElement;
        const wrap = document.createElement('div'); wrap.className = 'td-codeblock';
        pre.replaceWith(wrap);
    
        const {lang, ext} = getLangAndExt(code);
        const fileName = code.dataset.filename || `snippet.${ext}`;
    
        const bar = document.createElement('div');
        bar.className = 'td-codebar';
        bar.innerHTML = `
          <div class="td-filemeta">
            <span class="td-dot" aria-hidden="true"></span>
            <span class="td-lang">${lang}</span>
            <span class="td-fname" title="${fileName}">${fileName}</span>
          </div>
          <div class="td-actions">
            <button class="td-btn td-copy" title="Copy" aria-label="Copy">${icons.copy}<span class="td-label">Copy</span></button>
            <button class="td-btn td-open" title="Open in new tab" aria-label="Open">${icons.open}<span class="td-label">Open</span></button>
            <button class="td-btn td-download" title="Download" aria-label="Download">${icons.download}<span class="td-label">Download</span></button>
            <button class="td-btn td-codepen" title="Open on CodePen" aria-label="CodePen">${icons.codepen}<span class="td-label">CodePen</span></button>
          </div>`;
        const area = document.createElement('div'); area.className = 'td-code'; area.appendChild(pre);
        const toastEl = document.createElement('div'); toastEl.className = 'td-toast'; toastEl.textContent = 'Copied!';
        wrap.appendChild(bar); wrap.appendChild(area); wrap.appendChild(toastEl);
    
        const originalText = code.textContent; // để copy/download không dính số dòng
    
        // highlight + line numbers
        if (window.hljs) hljs.highlightElement(code);
        if (window.hljs && window.hljs.lineNumbersBlock){ try{ window.hljs.lineNumbersBlock(code); }catch(e){} }
    
        // actions
        bar.querySelector('.td-copy').addEventListener('click', async ()=>{
          try{ await navigator.clipboard.writeText(originalText); toast(wrap,'Copied!'); }
          catch{
            const ta = document.createElement('textarea'); ta.value = originalText; document.body.appendChild(ta);
            ta.select(); try{ document.execCommand('copy'); toast(wrap,'Copied!'); } catch{ toast(wrap,'Copy failed'); }
            ta.remove();
          }
        });
    
        bar.querySelector('.td-open').addEventListener('click', ()=>{
          const w = window.open('', '_blank');
          w.document.write(`<!doctype html><meta charset="utf-8"><title>${fileName}</title>
            <style>body{margin:0;background:#0b1221;color:#e6edf3}
            pre{white-space:pre-wrap;padding:16px;font:13px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}</style>
            <pre>${esc(originalText)}</pre>`);
          w.document.close();
        });
    
        bar.querySelector('.td-download').addEventListener('click', ()=>{
          const blob = new Blob([originalText],{type:'text/plain;charset=utf-8'});
          const url = URL.createObjectURL(blob);
          const a = Object.assign(document.createElement('a'),{href:url,download:fileName});
          document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url);
        });
    
        bar.querySelector('.td-codepen').addEventListener('click', ()=>{
          const lower = lang.toLowerCase();
          const isHTML = ['markup','html','xml','svg','pug','haml'].includes(lower);
          const isCSS  = ['css','scss','sass','less','stylus','styl'].includes(lower);
          const isJS   = ['javascript','js','jsx','ts','typescript','tsx'].includes(lower);
          const data = { title:`CodePen - ${lang} snippet`, html:'', css:'', js:'' };
          if (isHTML) data.html = originalText;
          else if (isCSS) data.css = originalText;
          else if (isJS) data.js = ['ts','typescript','tsx'].includes(lower) ? `// TS/TSX snippet\n${originalText}` : originalText;
          else data.html = `<pre>${esc(originalText)}</pre>`;
          const form = document.createElement('form');
          form.method='POST'; form.action='https://codepen.io/pen/define'; form.target='_blank';
          const input = document.createElement('input'); input.type='hidden'; input.name='data'; input.value=JSON.stringify(data);
          form.appendChild(input); document.body.appendChild(form); form.submit(); form.remove();
        });
    
        // double-click: select toàn bộ code
        area.addEventListener('dblclick', ()=>{
          const range = document.createRange(); range.selectNodeContents(code);
          const sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range);
        });
      }
    
      document.addEventListener('DOMContentLoaded', ()=>{
        document.querySelectorAll('pre > code').forEach(enhance);
      });
    })();
    </script>
  4. Khi viết bài, chỉ cần đặt code của bạn trong thẻ <pre><code> là hệ thống sẽ tự động hiển thị với giao diện mới.

Sau khi hoàn tất các bước trên, blog của bạn sẽ có khung chứa code Pro UX hiện đại, hỗ trợ sẵn các tính năng như Copy, Download và mở trực tiếp trên CodePen. Cực kỳ nhanh gọn và dễ dàng.

Kết luận

Sau khi áp dụng khung chứa code Pro UX cho Blogger, mình thật sự thấy blog trở nên chuyên nghiệp và tiện lợi hơn rất nhiều. Không chỉ dừng lại ở việc làm code dễ nhìn, dễ đọc, mà nó còn mang đến trải nghiệm tương tác mới cho người xem với các tính năng như Copy, Download hay mở trực tiếp trên CodePen. Đây chắc chắn sẽ là một công cụ hữu ích cho anh em nào thường xuyên viết blog chia sẻ kiến thức lập trình.

Mình là TruongDevs, một sinh viên IT luôn mong muốn lan tỏa những thủ thuật hay cho cộng đồng Blogger. Nếu bạn thấy bài viết này hữu ích, đừng ngại chia sẻ cho bạn bè, và nhớ ghi rõ nguồn TruongDevs.com khi sử dụng lại code nhé. Điều này vừa là sự tôn trọng tác giả, vừa giúp cộng đồng ngày càng phát triển lành mạnh hơn.

Nếu bạn có góp ý, thắc mắc hoặc muốn mình chia sẻ thêm những thủ thuật khác về Blogger, hãy để lại bình luận bên dưới. Mình sẽ cố gắng trả lời và cập nhật thêm nhiều nội dung mà anh em quan tâm.

Việc chia sẻ kiến thức sẽ ý nghĩa hơn khi chúng ta cùng nhau thảo luận và hoàn thiện nó. Mỗi góp ý của bạn chính là động lực để mình phát triển nội dung tốt hơn.

TruongDevs

Written by:
TruongDevs

About the author

TruongDevs
Không phải bug nào cũng xấu, có bug giúp ta tỉnh ra

Post a Comment