Bài viết này trình bày một cách triển khai Focus Mode thực tế, dựa trực tiếp trên code, với mấu chốt nằm ở việc sử dụng hook wp_head để quyết định layout ngay từ đầu.
Vấn đề thường gặp khi triển khai Focus Mode
Hầu hết các Focus Mode được xây dựng bằng cách chờ DOMContentLoaded rồi mới ẩn sidebar. Cách làm này khiến sidebar bị render trước, sau đó biến mất, dẫn đến việc cột nội dung bị dồn lại và gây nhảy giao diện.
Để tránh CLS, sidebar phải được ẩn trước lần paint đầu tiên của trình duyệt. Trong WordPress, điều này chỉ có thể thực hiện một cách an toàn thông qua hook wp_head.
Khởi tạo trạng thái Focus Mode thật sớm bằng wp_head
Đoạn code dưới đây được chạy rất sớm trong wp_head. Nó chỉ có nhiệm vụ kiểm tra trạng thái Focus Mode đã được lưu trong localStorage hay chưa, và nếu có thì gắn một class tạm thời lên thẻ html.
// ===== Focus Mode: singular only, chạy sớm =====
function init_html_early_focus_mode_inline_script() {
if ( ! is_singular() ) {
return;
}
?>
<script>
(function () {
try {
if (localStorage.getItem('init_focus_mode') === '1') {
document.documentElement.classList.add('init-focus-pending');
}
} catch (e) {}
})();
</script>
<?php
}
add_action('wp_head', 'init_html_early_focus_mode_inline_script', 1);
Điểm quan trọng ở đây là đoạn script này không thao tác với body, không query DOM, và không gây thay đổi layout. Nó chỉ đánh dấu trạng thái sớm để CSS có thể phản ứng ngay lập tức.
CSS render sớm để chống CLS
JavaScript chỉ đánh dấu trạng thái là chưa đủ. Sidebar chỉ thực sự không bị render khi CSS tương ứng đã tồn tại trước lần paint đầu tiên. Vì vậy, CSS chống CLS cũng phải được inline trong wp_head.
// Focus mode EARLY anti-CLS
add_action('wp_head', function () {
if ( ! is_singular() ) {
return;
}
?>
<style>
html.init-focus-pending body.single-post #id-sidebar {
display: none !important;
}
html.init-focus-pending body.single-post #id-content {
margin-inline: auto;
}
</style>
<?php
}, 1);
Với đoạn CSS này, nếu Focus Mode đang bật, sidebar sẽ không bao giờ được render ngay từ đầu. Kết quả là layout ổn định tuyệt đối và không phát sinh CLS.
CSS cho trạng thái Focus Mode sau khi trang đã tải
Sau khi trang đã render xong, Focus Mode sẽ được điều khiển bằng class gắn vào body. CSS lúc này không còn ảnh hưởng đến layout ban đầu nữa.
/* Focus Mode */
body.is-focus-mode #id-sidebar {
display: none !important;
}
body.is-focus-mode #id-content {
margin-inline: auto;
}
Đồng bộ trạng thái và render nút bật tắt
Khi DOMContentLoaded, trạng thái tạm thời trên html sẽ được đồng bộ sang body. Đồng thời, nút bật tắt Focus Mode được render để người dùng có thể tương tác.
// FOCUS
document.addEventListener('DOMContentLoaded', () => {
if (!document.body.classList.contains('single-post')) {
return;
}
const STORAGE_KEY = 'init_focus_mode';
const root = document.documentElement;
let isEnabled = root.classList.contains('init-focus-pending');
// Sync early state → body
if (isEnabled) {
document.body.classList.add('is-focus-mode');
root.classList.remove('init-focus-pending');
}
const btn = document.createElement('button');
btn.className = [
'uk-button',
'uk-button-secondary',
'uk-border-pill',
'uk-position-fixed',
'uk-position-small',
'uk-position-bottom-right',
'uk-box-shadow-medium',
'uk-visible@l',
'init-focus-toggle'
].join(' ');
btn.style.zIndex = 9999;
document.body.appendChild(btn);
const render = (enabled) => {
btn.innerHTML = enabled
? `<span uk-icon="icon: close"></span> ${initHTMLData.exit || 'Exit'}`
: `<span uk-icon="icon: file-text"></span> ${initHTMLData.focus || 'Focus'}`;
};
render(isEnabled);
btn.addEventListener('click', () => {
isEnabled = !isEnabled;
document.body.classList.toggle('is-focus-mode', isEnabled);
localStorage.setItem(STORAGE_KEY, isEnabled ? '1' : '0');
render(isEnabled);
});
});
Từ thời điểm này trở đi, việc bật hoặc tắt Focus Mode chỉ là thay đổi class trên body, không còn ảnh hưởng đến layout ban đầu và không gây CLS.
Kết luận
Mấu chốt của Focus Mode không nằm ở UI hay nút bấm, mà nằm ở việc quyết định layout đủ sớm. Bằng cách sử dụng wp_head để khởi tạo trạng thái và CSS chống CLS trước khi trình duyệt paint, Focus Mode có thể hoạt động mượt mà, ổn định và không làm ảnh hưởng đến Core Web Vitals.
Cách triển khai này đặc biệt phù hợp cho blog kỹ thuật và hệ thống tài liệu, nơi trải nghiệm đọc và hiệu năng luôn là ưu tiên hàng đầu.
Admin
21/01/2026 lúc 22:46
nút Tập Trung góc dưới bên phải trang này chính là ví dụ cho việc nhảy giao diện (CLS) 😂😂😂
vào chế độ tập trung (PC) và F5 để biết thứ bài viết này tránh!!!