几天前,我正从头开始重建我的投资组合网站。然后,作为典型的Web开发人员,我偶然发现了我应该在静态两页网站上使用哪个框架的问题。我以为要进行全栈框架会过大(例如Next.js,Gatsby等),因此我的选择仅限于某些静态Web生成器。由于我不熟悉Ruby和Go基于Jekyll和Hugo之类的SSG,所以我已经定居了110。
但是问题不止于此,因为稍后,我在尝试实现黑暗模式时面临着一个烦人的错误。因此,每当我尝试以黑暗模式重新加载页面时,它总是会闪烁。我认为原因是一个静态渲染的页面和客户端的黑暗模式实现,但事实证明,这比这更简单:)
好吧,这就是故事的结局。现在,让我们进入教程。 ð
不用担心,本教程应该适用于任何SSG(静态站点生成器)生成的网站,常规静态HTML,甚至是服务器渲染的一个
安装
创建一个带有项目名称的文件夹:
mkdir project-name && cd project-name
一旦在文件夹中启动节点项目,并以dev依赖关系安装11ty软件包:
npm init -y
npm install -D @11ty/eleventy
本质上,11ty是一个CLI工具,因此您可以在全球安装它并在任何地方使用它。但是,为了进行良好的封装练习,我更喜欢将其安装在可以利用它的项目中
将tailwind软件包添加为dev依赖项&init生成tailwind.config.js
&postcss.config.js
文件:
npm install -D tailwindcss postcss autoprefixer
安装了所有必要的软件包后,现在该设置
了设置
在文件夹根中创建.eleventy.js
配置文件,然后将此摘要复制到文件中:
module.exports = function(eleventyConfig) {
// Return your Object options:
return {
dir: {
input: "src",
output: "_dist"
}
}
};
-
input
是11Ty从模板生成HTML的入口点,默认情况下它等于Project Folder root。因此,如果定义src
,它将寻找一个名为src
的文件夹,并在内部处理所有模板 -
output
是最终处理模板将写入 的文件夹
更新package.json
脚本以看起来像:
"scripts": {
"start": "npm-run-all --parallel dev:*",
"build": "run-s build:*",
"dev:11ty": "eleventy --serve",
"dev:css": "tailwindcss -i src/assets/css/main.css -o _dist/assets/css/main.css --watch --postcss",
"build:11ty": "eleventy",
"build:css": "tailwindcss -i src/assets/css/main.css -o _dist/assets/css/main.css --minify --postcss"
}
由于NPM默认没有并行脚本执行,因此我们需要安装额外的软件包,以称为npm-run-all
将npm-run-all
安装为dev依赖性:
npm install -D npm-run-all
现在您可以执行这两个脚本:
"start": "npm-run-all --parallel dev:*",
"build": "run-s build:*",
run-s
呢?不用担心,它默认来自npm-run-all
,它的作用是顺序执行脚本,而不是并行执行,我们不需要为构建生产版本而做。
在设置了所有必要的脚本和配置之后,现在我们要编写简单的暗模式逻辑。
首先,创建一个src
文件夹并在内部制作index.njk
模板文件,将此基本摘要复制到文件中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script>
if (
localStorage.getItem('color-theme') === 'dark' ||
(!('color-theme' in localStorage) &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
</script>
<link rel="stylesheet" href={{
'/assets/css/main.css' | url
}}
type="text/css" />
<title>Dark Mode in 11ty</title>
</head>
<body class="bg-white dark:bg-knight">
<div>
hello from index
</div>
</body>
</html>
注意如何在头上导入样式表,但是我们实际上没有CSS文件,现在是时候在src/assets/css
中创建一个名为main.css
(您可以将CSS文件放在您喜欢的任何地方在分类的文件夹中,例如assets/css
)
现在将此摘要复制到main.css
:
@tailwind base;
@tailwind components;
@tailwind utilities;
也不要忘记设置尾风配置,以便尾风编译器可以搜索所有使用的类并将其转换为常规CSS,现在将此片段复制到tailwind.config.js
:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{njk,md}', './src/**/*.svg'],
darkMode: 'class',
theme: {},
plugins: [],
};
-
content
是尾风编译器查找的路径 -
darkMode
是用于尾风的暗模式方法,它具有两种类型的class
和media
。我们在这里使用class
,因为是最灵活的一个
好吧,现在创建一个名为bundle.js
的文件或您在src/js
文件夹中喜欢的任何内容,然后复制此片段:
const THEME_KEY = 'color-theme';
const toggleButton = document.querySelector('#dark-mode-toggle');
const docEl = document.documentElement;
toggleButton.addEventListener('click', function () {
if (localStorage.getItem(THEME_KEY)) {
if (localStorage.getItem(THEME_KEY) === 'light') {
docEl.classList.add('dark');
localStorage.setItem(THEME_KEY, 'dark');
} else {
docEl.classList.remove('dark');
localStorage.setItem(THEME_KEY, 'light');
}
// if NOT set via local storage previously
} else {
if (docEl.classList.contains('dark')) {
docEl.classList.remove('dark');
localStorage.setItem(THEME_KEY, 'light');
} else {
docEl.classList.add('dark');
localStorage.setItem(THEME_KEY, 'dark');
}
}
});
然后,在index.njk
中的</body>
标签之前添加此代码:
<script type="module" src="/js/bundle.js"></script>
现在,返回src
中的index.njk
文件,然后写下这样的东西:
<body class="bg-white dark:bg-knight">
<div>
Hello from index
<button id="dark-mode-toggle" class="-mt-1" aria-label="dark-mode-button">
<p class="dark:hidden">Dark</p>
<p class="hidden dark:inline">Light</p>
</button>
</div>
</body>
确保按钮ID等于QuerySelector中的按钮ID,在这种情况下为dark-mode-toggle
有些人想直接从JavaScript中切换到切换按钮内的深色/灯光图标或文本,但是我在这里使用dark:
伪级本身是非常常规但非常有效和简单的方法。
最后,不要忘记将所有未经处理的文件传递到_dist文件夹,因为只有110个仅处理模板文件,例如nunjucks(.njk),liquid(.liquid),等等。
将此摘要写入.eleventy.js
:
module.exports = function (eleventyConfig) {
// we're copying the bundle.js to _dist/js since is not proccessed
eleventyConfig.addPassthroughCopy({ 'src/js/bundle.js': 'js/bundle.js' })
/*
* but we don't need to copy the CSS because it has already been
* processed by the Tailwind, you can see the scripts in package.json
* and how they instruct the compiler to output it into the
* _dist/assets/css folder.
*/
// you can copy the rest of unprocessed file here
return {
dir: {
input: 'src',
output: '_dist',
data: '_data',
includes: '_includes',
layouts: '_layouts',
},
};
};
完成上面的所有步骤后,在项目目录中运行NPM运行启动命令,转到Localhost:8080,测试Toggle按钮和VOILã,您现在应该在静态上具有无闪烁的黑暗模式使用Tailwind CSS和Vanilla JavaScript的站点。
概括
- 这是什么解决方案?为什么黑暗模式不再闪烁了?好吧,原因很简单。
<head>
中的此内联脚本是构造障碍物,并在请求后立即运行,并且由于没有“ async”或“ defer”关键字。从下载和执行此脚本开始的所有内容都将阻止HTML渲染,因此,没有发生FOUC(未风格的内容)。
<script>
if (
localStorage.getItem('color-theme') === 'dark' ||
(!('color-theme' in localStorage) &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
</script>
您可能想将此脚本放在任何其他渲染障碍资产之上,例如CSS样式表链接和第三方CDN字体。
- 您可以在此处阅读完整的110文档:https://www.11ty.dev/docs/
- 今天就这样。我希望您喜欢本教程,如果您想纠正或添加某些内容,请在下面发表评论。