<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Web Dev on Louis&#39;s blog</title>
        <link>https://blog.louishhy.com/categories/web-dev/</link>
        <description>Recent content in Web Dev on Louis&#39;s blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <copyright>Louis Huang</copyright>
        <lastBuildDate>Thu, 22 May 2025 02:48:59 +0000</lastBuildDate><atom:link href="https://blog.louishhy.com/categories/web-dev/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>关于ClientWebAPI</title>
        <link>https://blog.louishhy.com/post/about-client-web-api/</link>
        <pubDate>Thu, 22 May 2025 02:48:59 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/about-client-web-api/</guid>
        <description>&lt;p&gt;看到了Hono.JS的介绍，
其中有一个部分是它可以 run everywhere，因为其使用了Web API Standard。&lt;/p&gt;
&lt;p&gt;正好自己之前对这些Web API一知半解，所以简单复习了一部分。&lt;/p&gt;
&lt;h2 id=&#34;dom--bom-manipulation&#34;&gt;DOM / BOM Manipulation
&lt;/h2&gt;&lt;p&gt;主要是利用了&lt;code&gt;document&lt;/code&gt;、&lt;code&gt;window&lt;/code&gt;等对象来操作DOM和BOM。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;document&lt;/code&gt;：提供操作文档的方法。例如&lt;code&gt;querySelector&lt;/code&gt;、&lt;code&gt;getElementById&lt;/code&gt;等。通过这种script可以让网页动态化等等。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;window&lt;/code&gt;：表示浏览器窗口的对象，可以知道比如说窗口的dimension，也可以操作例如滚动窗口到哪些地方。一些event handler也是直接绑在window上。
&lt;ul&gt;
&lt;li&gt;也因此复习了一下可以监听的events，例如&lt;code&gt;scroll&lt;/code&gt;。使用&lt;code&gt;addEventListener&lt;/code&gt;可以绑定事件处理函数，&lt;code&gt;removeEventListener&lt;/code&gt;可以解绑事件处理函数避免内存泄漏。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;history&lt;/code&gt;：表示浏览器的历史记录，可以用来操作浏览器的前进后退等功能。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;fetch-api&#34;&gt;Fetch API
&lt;/h2&gt;&lt;p&gt;应该是后端接触最多的一种API了。
&lt;code&gt;Request&lt;/code&gt;和&lt;code&gt;Response&lt;/code&gt;是两个最重要的对象。&lt;/p&gt;
&lt;p&gt;二者基本上都可以调用类似的方法来进行解析。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.formData()&lt;/code&gt;：将数据解析为&lt;code&gt;FormData&lt;/code&gt;对象，文件也会被自动解析为&lt;code&gt;File&lt;/code&gt;对象。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.json()&lt;/code&gt;：将JSON数据解析为JavaScript对象。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text()&lt;/code&gt;：将文本数据解析为字符串。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.arrayBuffer()&lt;/code&gt;：将数据解析为&lt;code&gt;ArrayBuffer&lt;/code&gt;对象。（可以用来直接处理二进制数据）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;除此之外&lt;code&gt;Response&lt;/code&gt;还有&lt;code&gt;.ok&lt;/code&gt;、&lt;code&gt;.status&lt;/code&gt;、&lt;code&gt;.statusText&lt;/code&gt;等属性可以用来判断请求是否成功。&lt;/p&gt;
&lt;p&gt;另外一般地，如果没有特殊需求的情况下，基本上API endpoint都是用&lt;code&gt;json&lt;/code&gt;或&lt;code&gt;multipart/form-data&lt;/code&gt;来传输数据，比较少直接传输二进制数据或者单纯的text。&lt;/p&gt;
&lt;h2 id=&#34;local-storage-和-session-storage&#34;&gt;Local Storage 和 Session Storage
&lt;/h2&gt;&lt;p&gt;存储在浏览器中的key-value pair，每一个origin都有自己的独立存储空间。
不同的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;localStorage&lt;/code&gt;：存储的数据在浏览器关闭后仍然存在，除非被purge。多个同origin的tab之间是共享的。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sessionStorage&lt;/code&gt;：存储的数据在浏览器关闭或标签页关闭后会被删除。按照标签页隔离。&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>关于html图片和相关css的随记</title>
        <link>https://blog.louishhy.com/post/regarding-html-image-and-related-css/</link>
        <pubDate>Mon, 19 May 2025 09:49:36 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/regarding-html-image-and-related-css/</guid>
        <description>&lt;p&gt;最近因为参加了一个hackathon重新捡起了前端，
然后发现styling这方面需要和组友合作很多
所以开始重新inspect一些css的细节。&lt;/p&gt;
&lt;p&gt;今天想要谈一些关于前端中图片的使用。&lt;/p&gt;
&lt;h2 id=&#34;1-图片的宽高&#34;&gt;1. 图片的宽高
&lt;/h2&gt;&lt;p&gt;图片是一个replacement element，自己有一个intrinsic size。
但是其真实显示的大小是由CSS来决定的。&lt;/p&gt;
&lt;p&gt;HTML best practice是务必给图片加上&lt;code&gt;width&lt;/code&gt;,&lt;code&gt;height&lt;/code&gt;和&lt;code&gt;alt&lt;/code&gt;属性。
这样网页会预留好空间来放这个图片，避免layout shift。
与此同时也会知道图片的宽高比。
这样css控制时就会知道图片原始的比例。&lt;/p&gt;
&lt;p&gt;注意css中，&lt;code&gt;width&lt;/code&gt;和&lt;code&gt;height&lt;/code&gt;是可以是relative的。
我以前的误解是这个东西必须是绝对数值，可以看看下面我为什么会产生这个误解（。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;img&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;/* 相对于父元素 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;/* 让浏览器自动计算高度，保持宽高比 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;2-nextjs中的image&#34;&gt;2. Next.JS中的Image
&lt;/h2&gt;&lt;p&gt;Next.JS中Image组件中必须用绝对数值specify的&lt;code&gt;width&lt;/code&gt;和&lt;code&gt;height&lt;/code&gt;是决定图片的intrinsic size。
最终渲染的大小是css决定的。&lt;/p&gt;
&lt;p&gt;这个就是我以为css中必须是绝对数值的原因。&lt;/p&gt;
&lt;p&gt;另外一个就是Next.JS可以使用&lt;code&gt;fill&lt;/code&gt;来让图片充满父元素，这个时候就不用&lt;code&gt;width&lt;/code&gt;和&lt;code&gt;height&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;然而一个细节就是默认这个时候这个图片的position是absolute的。
所以要记得设置父元素/祖先元素为非&lt;code&gt;static&lt;/code&gt;的position。&lt;/p&gt;
&lt;h2 id=&#34;3-关于img的display&#34;&gt;3. 关于&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;的display
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;的display是&lt;code&gt;inline&lt;/code&gt;的。&lt;/p&gt;
&lt;p&gt;因此其实可以通过styling来改变其display的方式使得它不必包裹在一个&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;中
也能服从良好的布局。&lt;/p&gt;
&lt;p&gt;之前有一篇文章说最好要用&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;包裹图片，现在想想也不一定。
事实上&lt;code&gt;object-fit&lt;/code&gt;和&lt;code&gt;object-position&lt;/code&gt;都不必再来一个&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;来包裹图片，
这些效果会直接作用于画框（&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;）上。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MDN object-fit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/object-position&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MDN object-position&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;4-关于text-align&#34;&gt;4. 关于text-align
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;text-align&lt;/code&gt;其实不单单是用来控制文字的，任何inline的元素都可以用这个属性来控制。&lt;/p&gt;
&lt;p&gt;所以理所当然地你可以用这个来居中图片（只要你还没有改变它的&lt;code&gt;display&lt;/code&gt;，默认是&lt;code&gt;inline&lt;/code&gt;）&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;img&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;text-align&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;center&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/text-align&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MDN text-align&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;5-关于如何学习css的一个说法&#34;&gt;5. 关于如何学习CSS的一个说法
&lt;/h2&gt;&lt;p&gt;看到一句话说CSS不能使用传统的程序员思维来学习，更多是随用随查，多用。
但是底层的一些概念要搞懂。&lt;/p&gt;
&lt;p&gt;有一个学习路线说的是搞懂四个概念：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;选择器，样式，盒模型，定位&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;个人感觉总结的还是很不错的，
事实上很多时候颠来倒去的奇妙bug和不优雅的实现也是因为这些概念没有扎实引起。&lt;/p&gt;
&lt;p&gt;以后可以参考这个学习路线来再吃一遍css。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>HTML/CSS/JS核心记忆索引</title>
        <link>https://blog.louishhy.com/post/memo-index-for-html-css-js/</link>
        <pubDate>Mon, 17 Feb 2025 14:28:25 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/memo-index-for-html-css-js/</guid>
        <description>&lt;p&gt;这篇文章提供一个个人的快速索引，
旨在以后忘记 html,css,js 时能尽快恢复大部分的核心知识。&lt;/p&gt;
&lt;p&gt;这篇文章的要求的知识范畴是：知道这些东西能让你更有自信地使用框架（例如 React）。&lt;/p&gt;
&lt;p&gt;详细的语法大部分不会包括在内，大部分时候你可以直接查询。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;这不是一篇教学笔记。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;html&#34;&gt;HTML
&lt;/h2&gt;&lt;p&gt;HTML 是一种 markup language，渲染时形成 DOM Tree.&lt;/p&gt;
&lt;p&gt;HTML 提供&lt;strong&gt;块级元素&lt;/strong&gt;和&lt;strong&gt;内联元素&lt;/strong&gt;（虽然新标准提供更加详细而复杂的分类，但是可以这么来表现）。&lt;/p&gt;
&lt;p&gt;HTML 可以展示文字，图片，视频，音频，画布，以及超链接。&lt;/p&gt;
&lt;p&gt;HTML 可以表现不同的标题，强调，斜体，horizontal line，上下标。&lt;/p&gt;
&lt;p&gt;HTML 的 tag 一些具有语义。
对于一个页面其结构一般是&lt;code&gt;header&lt;/code&gt;, &lt;code&gt;nav&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;aside&lt;/code&gt; （侧边栏）, &lt;code&gt;footer&lt;/code&gt;.
对于部分一般使用&lt;code&gt;section&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;只有在没有适合语义的时候（例如对一组元素做 styling 时）才使用无语义的块级元素&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;
和内联元素&lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;。此外，&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;一般一个页面只用一次，方便 SEO。&lt;/p&gt;
&lt;p&gt;HTML 的 header 可以设置 title 标题，charset, favicon，description 描述，lang 语言等元信息。
这些对于 SEO 非常重要。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Structuring_content/Basic_HTML_syntax&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;元素参考&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Structuring_content/Webpage_metadata&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Header 相关的设置&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;css&#34;&gt;CSS
&lt;/h2&gt;&lt;h3 id=&#34;层叠&#34;&gt;层叠
&lt;/h3&gt;&lt;p&gt;CSS 层叠样式表的核心是&lt;strong&gt;层叠&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;层叠体现在：顺序（后来的会覆盖前面的），优先级（一套优先级计算机制），继承（一些属性，例如颜色，会被子元素继承）。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Handling_conflicts&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;层叠规则&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;选择器&#34;&gt;选择器
&lt;/h3&gt;&lt;p&gt;CSS 通过选择器来进行元素的选定。你可以用 id，class，或者 type (html tag 的类型) 来选定。&lt;/p&gt;
&lt;p&gt;CSS 也可以选择后代或者多个条件同时满足的元素。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Basic_selectors&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;选择器语法&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;伪类与伪元素&#34;&gt;伪类与伪元素
&lt;/h3&gt;&lt;p&gt;伪类可以选择一个元素在特定的状态下的样式，例如 hover。用单个冒号，形如&lt;code&gt;:hover&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;伪元素可以选择一个元素并且为其添加一个虚拟元素，这个虚拟元素如同其&lt;strong&gt;子元素&lt;/strong&gt;，
所以你可以通过&lt;code&gt;relative&lt;/code&gt;, &lt;code&gt;absolute&lt;/code&gt;来 style 它。用双冒号，形如&lt;code&gt;::after&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Pseudo_classes_and_elements&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;伪类和伪元素&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;盒模型&#34;&gt;盒模型
&lt;/h3&gt;&lt;p&gt;在 CSS 中，一切都是盒。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Box_model&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;盒模型&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;两个注意点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用【替代盒模型】是现代最佳实践，其 width 和 height 描述的是 content + padding + border&lt;/li&gt;
&lt;li&gt;Margin 可以为负并且产生 merge。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.louishhy.com/post/memo-index-for-html-css-js/image.png&#34;
	width=&#34;440&#34;
	height=&#34;240&#34;
	srcset=&#34;https://blog.louishhy.com/post/memo-index-for-html-css-js/image_hu12915692757837351257.png 480w, https://blog.louishhy.com/post/memo-index-for-html-css-js/image_hu9718391884935973410.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;替代盒模型 (source: mdn)&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;183&#34;
		data-flex-basis=&#34;440px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;盒有三种外部表现：&lt;code&gt;block&lt;/code&gt;, &lt;code&gt;inline&lt;/code&gt;, &lt;code&gt;inline-block&lt;/code&gt;。（块级/内联）&lt;/p&gt;
&lt;p&gt;最大的区别就是：是否&lt;strong&gt;换行&lt;/strong&gt;，&lt;strong&gt;width/height&lt;/strong&gt; 设置是否有效，是否把周围元素&lt;strong&gt;推开&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;内部表现包含&lt;code&gt;flex&lt;/code&gt;和&lt;code&gt;grid&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;flex&lt;/code&gt;是弹性盒模型。它可以让元素在一维上对齐，并且可以让元素按照自己的内容伸缩（&lt;code&gt;flex-1&lt;/code&gt;, etc.）&lt;/p&gt;
&lt;p&gt;&lt;code&gt;display&lt;/code&gt;属性定义了内部和外部的表现。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Web/CSS/display&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;display&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/CSS_layout/Flexbox&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;弹性盒模型 flexbox&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;字体样式与字体栈&#34;&gt;字体样式与字体栈
&lt;/h3&gt;&lt;p&gt;在 &lt;code&gt;font-family&lt;/code&gt; 中堆叠一系列字体，最后一个字体为系统默认字体的标识，以确保字体可用。
这被称为字体栈。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;font-family&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Trebuchet MS&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Verdana&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;sans-serif&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;保底字体为：&lt;code&gt;serif&lt;/code&gt;（衬线），&lt;code&gt;sans-serif&lt;/code&gt;（无衬线），&lt;code&gt;monospace&lt;/code&gt;（等宽，一般用于代码）&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Text_styling/Fundamentals&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;字体&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;布局流与定位技术&#34;&gt;布局流与定位技术
&lt;/h3&gt;&lt;p&gt;默认地，文档将按照默认布局流进行排布。&lt;/p&gt;
&lt;p&gt;CSS 利用&lt;code&gt;position&lt;/code&gt;将元素移出默认布局流，并且用&lt;code&gt;inset&lt;/code&gt;等来定位他们。以下改写自 mdn。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;静态定位（&lt;code&gt;static&lt;/code&gt;）：放在默认位置。&lt;/li&gt;
&lt;li&gt;相对定位 (&lt;code&gt;relative&lt;/code&gt;): 相对于原来其【应该在的默认位置】进行移动。&lt;/li&gt;
&lt;li&gt;绝对定位 (&lt;code&gt;absolute&lt;/code&gt;): 相对于其最近被定位祖先元素（比如被设置为&lt;code&gt;relative&lt;/code&gt;的）。
&lt;strong&gt;如果祖先树不存在这样的元素，那么相对于&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;进行调整。&lt;/strong&gt;
（所以你需要指定一个祖先元素为&lt;code&gt;relative&lt;/code&gt;然后才能正常使用&lt;code&gt;absolute&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;固定定位（&lt;code&gt;fixed&lt;/code&gt;）: 相对于视窗。&lt;/li&gt;
&lt;li&gt;粘性定位（&lt;code&gt;sticky&lt;/code&gt;）: 先保持和 &lt;code&gt;static&lt;/code&gt; 一样的定位，当它的相对视口位置（offset from the viewport）达到某一个预设值时，它就会像 position: fixed 一样定位。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/CSS_layout/Introduction&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;布局流&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;层叠层-cascading-layer&#34;&gt;层叠层 (Cascading Layer)
&lt;/h3&gt;&lt;p&gt;用层级来调整 css 的优先度，使得一系列样式可以被定义在同一个&lt;code&gt;@layer&lt;/code&gt;中，并定义覆盖顺序。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;layer&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;，&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;layout&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;，&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;utilities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;layer&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;layout&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;main&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;grid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 tailwind 中是核心概念。（base, component, utilities）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意。未分层的层外样式优先权比任何层内样式都高。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics/Cascade_layers&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;层叠层&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;javascript&#34;&gt;Javascript
&lt;/h2&gt;&lt;p&gt;此处不涉及 js 基本语法，异步编程 etc.，只涉及浏览器中重要的模式和知识。&lt;/p&gt;
&lt;h3 id=&#34;事件与事件冒泡&#34;&gt;事件与事件冒泡
&lt;/h3&gt;&lt;p&gt;DOM node 可以触发事件，可以登记 callback 以响应事件。&lt;/p&gt;
&lt;p&gt;在一个 dom node 触发的事件会默认冒泡至其父节点。&lt;/p&gt;
&lt;p&gt;callback 中的&lt;code&gt;event&lt;/code&gt; (&lt;code&gt;(e) =&amp;gt; {...}&lt;/code&gt;)中包含了一些重要信息。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;e.target&lt;/code&gt;：触发了这个事件的元素。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;e.currentTarget&lt;/code&gt;：处理这个事件的元素（这个 callback 被 register 的元素。
例如说，冒泡的时候，target 就会是这个子元素，&lt;code&gt;currentTarget&lt;/code&gt;就是目前事件到达的父元素）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;e.preventDefault()&lt;/code&gt;： 禁止默认行为（例如表单中按钮的默认行为是提交表单）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;web-apis&#34;&gt;Web APIs
&lt;/h3&gt;&lt;p&gt;提供一些重要的 Web API。&lt;/p&gt;
&lt;p&gt;客户端重要的 objects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Window&lt;/code&gt;：可以得到窗口大小等信息。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Navigator&lt;/code&gt;：媒体流等信息。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Document&lt;/code&gt;：操作 DOM（增加 node 等等）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;客户端存储 objects：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sessionStorage&lt;/code&gt;: 浏览器关闭时会消除的 kv pairs。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;localStorage&lt;/code&gt;：会持续保存，浏览器重启也不会消除的 kv pairs。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;获取数据：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Extensions/Client-side_APIs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;客户端 Web API&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>mdn CSS 概要记录 - 选择器和盒子模型</title>
        <link>https://blog.louishhy.com/post/mdn-css-keypoints-selectors-and-box-model/</link>
        <pubDate>Sun, 16 Feb 2025 15:37:49 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/mdn-css-keypoints-selectors-and-box-model/</guid>
        <description>&lt;p&gt;学习 tailwind 之后想学习一下 CSS 的基础概念，所以去翻了 &lt;a class=&#34;link&#34; href=&#34;https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Core/Styling_basics&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;mdn CSS 基础&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;有一些选择器感觉是非常适合原来的 vanilla CSS 而设计出来的，
但是对于 tailwind 这种 utility-based 的 CSS framework 不太常用
（一个例子是&lt;code&gt;+&lt;/code&gt;这种兄弟 selector）。&lt;/p&gt;
&lt;p&gt;所以记录一下比较核心的概念（相对经常用到的）。
这篇文章主要写&lt;strong&gt;选择器&lt;/strong&gt;和&lt;strong&gt;盒子模型&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;1-选择器&#34;&gt;1. 选择器
&lt;/h2&gt;&lt;p&gt;选择器选定 HTML DOM Tree 中的既定元素，并且增加对应的样式。&lt;/p&gt;
&lt;p&gt;以下是一些很常用的选择器样式的格式。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 选择一种html tag类型 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;h1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 选择一个类 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;class1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 选择一个id */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;id1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 有title属性的锚元素（anchor）*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 有href, 并且href是&amp;#34;https://example.com&amp;#34;的元素 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* *****复合选择器***** */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 选择一个既有class1又有class2的h1 element */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;h1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;class1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;class2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 后代选择器：选择为div的子元素的p (后代) */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* *****伪类与伪元素***** */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 伪类 用:标记 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;hover&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;/* 伪元素 用::标记 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;after&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c&#34;&gt;/* 必须设置content属性，即使是空字符串。 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;2-伪类和伪元素&#34;&gt;2. 伪类和伪元素
&lt;/h2&gt;&lt;p&gt;这个对我是一个比较新的概念。&lt;/p&gt;
&lt;p&gt;伪类指的是在特定状态下才被 apply 的选择器。比如说：hover 的时候。&lt;/p&gt;
&lt;p&gt;伪元素创造一个&lt;em&gt;虚拟元素&lt;/em&gt;。它可以被视为目标元素的子元素。
例如说，可以用&lt;code&gt;::before&lt;/code&gt;或者&lt;code&gt;::after&lt;/code&gt;在元素前后添加新内容。
也可以精准选定第一行等等。&lt;/p&gt;
&lt;p&gt;除了在元素前添加图标之外，
由于可以被视为目标的子元素，因此理论上也可以对目标元素使用&lt;code&gt;relative&lt;/code&gt;，
然后子元素使用&lt;code&gt;absolute&lt;/code&gt;来添加覆盖该元素的阴影或者动画效果。&lt;/p&gt;
&lt;p&gt;这里有一个类似 Material design 的水波纹效果的例子。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;button&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;relative&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;/* 让 ::after 绝对定位时相对这个按钮 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;overflow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;hidden&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;/* 防止水波超出按钮 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;background&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;#3498db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;border&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;none&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;padding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;24&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;pointer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;font-size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;button&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;after&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;absolute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;top&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;left&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;background&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;translate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-50&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;-50&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;scale&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;border-radius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;transition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;transform&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.4&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;ease-out&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;opacity&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.4&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;ease-out&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;button&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;active&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;after&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;translate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-50&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;-50&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;scale&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;opacity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;感觉不少 css 特效的底层都用到了伪元素，算是解答了心中的一个疑惑。&lt;/p&gt;
&lt;h2 id=&#34;3-盒模型&#34;&gt;3. 盒模型
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;我超！盒！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;盒模型是 CSS 的基础之一，包含&lt;code&gt;content&lt;/code&gt;, &lt;code&gt;padding&lt;/code&gt;, &lt;code&gt;border&lt;/code&gt;, &lt;code&gt;margin&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.louishhy.com/post/mdn-css-keypoints-selectors-and-box-model/image.png&#34;
	width=&#34;544&#34;
	height=&#34;300&#34;
	srcset=&#34;https://blog.louishhy.com/post/mdn-css-keypoints-selectors-and-box-model/image_hu7411741034969014871.png 480w, https://blog.louishhy.com/post/mdn-css-keypoints-selectors-and-box-model/image_hu6634375634654276103.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;盒模型（来自mdn web docs）&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;181&#34;
		data-flex-basis=&#34;435px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;盒子的参数可以被归纳为：外部显示类型和内部显示类型。&lt;/p&gt;
&lt;h3 id=&#34;31-外部显示类型outer-display-types&#34;&gt;3.1 外部显示类型(outer display types)
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;block&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;产生换行。&lt;/li&gt;
&lt;li&gt;高宽设置(&lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;)有效。&lt;/li&gt;
&lt;li&gt;padding, border, margin 会将其他元素推开。&lt;/li&gt;
&lt;li&gt;未指定宽度时，通常直接占到 100%父容器的宽度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;inline&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不产生换行。&lt;/li&gt;
&lt;li&gt;高宽设置无效。&lt;/li&gt;
&lt;li&gt;padding, border, margin 会被应用。水平的边距会把其他元素推开。但是，垂直边距不会把其他&lt;code&gt;inline&lt;/code&gt;元素推开。也就是说，&lt;em&gt;如果溢出的话，会和其他&lt;code&gt;inline&lt;/code&gt;元素重叠&lt;/em&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;inline-block&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是&lt;code&gt;inline&lt;/code&gt;和&lt;code&gt;block&lt;/code&gt;的 mix。&lt;/li&gt;
&lt;li&gt;不产生换行。&lt;/li&gt;
&lt;li&gt;高宽设置(&lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;)有效。&lt;/li&gt;
&lt;li&gt;padding, border, margin 会将其他元素推开。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;32-内部显示类型inner-display-types&#34;&gt;3.2 内部显示类型(inner display types)
&lt;/h3&gt;&lt;p&gt;通常指的是&lt;code&gt;flex&lt;/code&gt;, &lt;code&gt;grid&lt;/code&gt;这种掌管内部元素排布的类型。&lt;/p&gt;
&lt;h3 id=&#34;33-替代盒模型&#34;&gt;3.3 替代盒模型
&lt;/h3&gt;&lt;p&gt;Tailwind 默认使用的是替代盒模型。(事实上，替代盒模型也是现代 css 开发的最佳实践。)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;box&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;box-sizing&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;border-box&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;原有的盒模型，&lt;code&gt;width&lt;/code&gt;和&lt;code&gt;height&lt;/code&gt;指的是盒子的内容大小，也就是实际大小应该加上&lt;code&gt;padding&lt;/code&gt;和&lt;code&gt;border&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;替代盒模型中，&lt;code&gt;width&lt;/code&gt;和&lt;code&gt;height&lt;/code&gt;指的是盒子可见范围的大小，也就是算进了&lt;code&gt;padding&lt;/code&gt;和&lt;code&gt;border&lt;/code&gt;的大小。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.louishhy.com/post/mdn-css-keypoints-selectors-and-box-model/image-1.png&#34;
	width=&#34;440&#34;
	height=&#34;240&#34;
	srcset=&#34;https://blog.louishhy.com/post/mdn-css-keypoints-selectors-and-box-model/image-1_hu12915692757837351257.png 480w, https://blog.louishhy.com/post/mdn-css-keypoints-selectors-and-box-model/image-1_hu9718391884935973410.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;替代盒模型（来自mdn web docs）&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;183&#34;
		data-flex-basis=&#34;440px&#34;
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;34-细节外边距折叠-margin-collapsing&#34;&gt;3.4 细节：外边距折叠 Margin Collapsing
&lt;/h3&gt;&lt;p&gt;算是一个细节，这里引用原文。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;外边距是盒子周围一圈看不到的空间。它会把其他元素退推离盒子。&lt;/p&gt;
&lt;p&gt;外边距属性值&lt;strong&gt;可以为正也可以为负&lt;/strong&gt;。在盒子一侧设置负值会导致盒子和页面上的其他内容重叠。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但是，当两个外边距重合的时候，有一套独特的计算方法。&lt;/p&gt;
&lt;p&gt;简而言之就是“合并 取最大”。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;根据外边距相接触的两个元素是正边距还是负边距，结果会有所不同：&lt;/p&gt;
&lt;p&gt;两个正外边距将合并为一个外边距。其大小等于最大的单个外边距。&lt;/p&gt;
&lt;p&gt;两个负外边距会折叠，并使用最小（离零最远）的值。&lt;/p&gt;
&lt;p&gt;如果其中一个外边距为负值，其值将从总值中减去。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;以上。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Next.JS的ESLint &#43; Prettier设置</title>
        <link>https://blog.louishhy.com/post/prettier-eslint-setup-for-nextjs/</link>
        <pubDate>Sun, 16 Feb 2025 11:03:44 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/prettier-eslint-setup-for-nextjs/</guid>
        <description>&lt;p&gt;简单记录一下在设置自己东拼西凑全栈的 ESLint + Prettier 的小 tips 和坑。&lt;/p&gt;
&lt;h2 id=&#34;技术栈&#34;&gt;技术栈
&lt;/h2&gt;&lt;p&gt;首先贴一下自己最近接触 Web dev 之后选择/脑补出来的技术栈，
设想的使用场景是个人的兴趣开发，PoC 或者是小规模应用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Javascript / Typescript / React&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Meta-framework&lt;/strong&gt;: Next.JS
&lt;ul&gt;
&lt;li&gt;前后端可以同时开发，感觉还是很不错的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSS&lt;/strong&gt;: TailwindCSS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;组件调试&lt;/strong&gt;: Storybook&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI 库&lt;/strong&gt;: shadcn-ui，lucide-react（图标）
&lt;ul&gt;
&lt;li&gt;这个很看个人的爱好，我个人挺喜欢 shadcn 的设计语言。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;认证系统&lt;/strong&gt;: Auth.JS
&lt;ul&gt;
&lt;li&gt;懒人，开箱即用.jpg&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ORM&lt;/strong&gt;: Prisma&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;输入/输出验证&lt;/strong&gt;: Zod&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;测试框架&lt;/strong&gt;: Jest&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Format/Linting&lt;/strong&gt;：ESLint + Prettier&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenAPI&lt;/strong&gt;：next-swagger-doc&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;表单&lt;/strong&gt;: react-hook-form&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Email 方面目前还没有需求，
目前看着 resend 不错。&lt;/p&gt;
&lt;h2 id=&#34;关于-eslint--prettier-的设置&#34;&gt;关于 ESLint + Prettier 的设置
&lt;/h2&gt;&lt;p&gt;项目开始的时候自然要设置一下 Format 和 linting。
虽然 ESLint 也有 formatting 的功能，
但是 Prettier 胜在开箱即用，据 stackoverflow 而言速度也快。&lt;/p&gt;
&lt;p&gt;这次的方法针对的是配合 tailwindcss 的设置。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设置完你的 next.js（利用&lt;code&gt;create-next-app&lt;/code&gt;）。你的 tailwind 应该也在这个时候设置完毕了。&lt;/li&gt;
&lt;li&gt;安装 prettier。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm i -D prettier
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;为了防止 prettier 全局扫描时也扫描 node_modules 的全部文件，
创建一个.prettierignore。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;//.prettierignore
node_modules
&lt;/code&gt;&lt;/pre&gt;&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;
&lt;p&gt;prettier 存在一个配合 tailwindcss 的 plugin，
可以按照 tailwind 推荐的方式来 rearrange classes。
详见&lt;a class=&#34;link&#34; href=&#34;https://tailwindcss.com/blog/automatic-class-sorting-with-prettier&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;我们首先安装一个 plugin。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -D prettier-plugin-tailwindcss
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后，准备一个&lt;code&gt;prettier.config.mjs&lt;/code&gt;。
（写这篇文章时 prettier config 对 ts 的支持仍在 beta，
所以用 mjs 以求稳定性。）&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;plugins&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;prettier-plugin-tailwindcss&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;
&lt;p&gt;由于 eslint 和 prettier 可能会在 formatting 上发生冲突，
所以安装一个 prettier 的官方包 &lt;a class=&#34;link&#34; href=&#34;https://github.com/prettier/eslint-config-prettier&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;eslint-config-prettier&lt;/a&gt;，
让 eslint 来处理 linting，prettier 来处理 formatting。
由于具体 config 方法各异，
请参考这个 repo 的 README，给出了非常详尽的步骤。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（可选）可以打开 vscode 的自动 formatting-on-save。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 marketplace 安装 Prettier 的插件。&lt;/li&gt;
&lt;li&gt;搜索&lt;code&gt;default formatter&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;设置 Default formatter 为 Prettier-code formatter。&lt;/li&gt;
&lt;li&gt;搜索&lt;code&gt;format on save&lt;/code&gt;并将其打开。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;现在可以快乐地使用了！
只要按 Ctrl+S 就会自动做好 formatting，让你的代码更加可读。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>利用RadixUI的Overlay解决方案</title>
        <link>https://blog.louishhy.com/post/use-radix-to-do-overlay/</link>
        <pubDate>Wed, 05 Feb 2025 08:59:05 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/use-radix-to-do-overlay/</guid>
        <description>&lt;p&gt;shadcn-ui中有一个Dialog组件可以很快速地创建Dialog + Overlay。
其基本功能就是会显示一个黑色覆盖层，并且覆盖层中间会弹出一个窗口作为Dialog。&lt;/p&gt;
&lt;p&gt;但是shadcn-ui中的组件已经经过充分定制。
有些时候自己已经设计好了一份弹窗，不想要shadcn的predefined style。
一种方法是去修改shadcn源码，另一种方法是直接用shadcn底层的radix来写，客制化程度更高。&lt;/p&gt;
&lt;p&gt;这里我们用一个例子，假设我们已经有了一个Component叫做&lt;code&gt;MemberCard&lt;/code&gt;，我们想要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用一个占满全屏的Overlay&lt;/li&gt;
&lt;li&gt;当click到卡片外部的区域时，关闭这张&lt;code&gt;MemberCard&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;拥有Radix的各种功能，例如无障碍，Esc退出等等。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Dialog&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;@radix-ui/react-dialog&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;motion&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;framer-motion&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;MemberInfo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;@/types/MemberInfo&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;MemberCard&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;./MemberCard&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;VisuallyHidden&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;@radix-ui/react-visually-hidden&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;interface&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;CardDialogProps&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;isOpen&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;boolean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;onClose&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;member&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;MemberInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;CardDialog&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;React&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;FC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;CardDialogProps&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;isOpen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;onClose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;member&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Dialog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Root&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isOpen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;onOpenChange&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;onClose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* Portal负责把这个组件送出dom，通常在body的下方。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;      这样它就不会受到事件冒泡和父元素CSS（例如z-index）等的影响。 */&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Dialog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Portal&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* 透明的Overlay，记得设置覆盖全屏。 */&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Dialog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Overlay&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;fixed inset-0 bg-black/50 backdrop-blur-sm z-50&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* 为了将Dialog Content居中，这里需要一个div来做flex styling。它的大小也是充满全屏的。 */&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;div&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;fixed inset-0 z-50 flex items-center justify-center&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* 将组件包裹在这里。注意Content要和组件一样大。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;          这样才能触发onPointerDownOutside，达到点击背景退出的效果。 */&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Dialog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Content&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;w-3/4 max-w-7xl outline-none&amp;#34;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;onPointerDownOutside&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;onClose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* Radix的Dialog必须存在Title来触发无障碍。这里我们用VisuallyHidden隐藏。 */&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Dialog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Title&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;asChild&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;VisuallyHidden&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;member&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;personal&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;information&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/VisuallyHidden&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/Dialog.Title&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* 卡片容器 */&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;motion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;div&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;nx&#34;&gt;initial&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;scale&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.3&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;nx&#34;&gt;animate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;scale&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MemberCard&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;member&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/motion.div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/Dialog.Content&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/Dialog.Portal&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/Dialog.Root&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;CardDialog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后就可以快乐解决了！&lt;/p&gt;
&lt;p&gt;另外，虽然这里用了workaround，
但是其实非常多的东西都可以用shadcn-ui解决，感觉它覆盖了95%以上的日常开发需求。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>前端学习：开发游戏公会的PR Page中学到的</title>
        <link>https://blog.louishhy.com/post/things-i-learnt-from-building-game-guild-pr-page/</link>
        <pubDate>Sat, 01 Feb 2025 07:30:04 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/things-i-learnt-from-building-game-guild-pr-page/</guid>
        <description>&lt;p&gt;最近找到工作之后心血来潮地想学一下前端，
第一个想自己做一些漂亮的网页，第二个是作为后端了解前端在做什么可以更好地了解整体的landscape。&lt;/p&gt;
&lt;p&gt;正好自己之前为所属的mmo公会(BP你死的好惨啊.jpg)做过一个网页，
但是当时的网页是直接抄的模版，所以基本上就是填入想要的东西就可以，
主要的学习点是用Cloudflare。
所以这次就决定从零做起。&lt;/p&gt;
&lt;h2 id=&#34;1-技术选型&#34;&gt;1. 技术选型
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;前端库: React with Typescript （后期转向了Next.JS框架）&lt;/li&gt;
&lt;li&gt;框架: Next.JS&lt;/li&gt;
&lt;li&gt;CSS: Tailwind&lt;/li&gt;
&lt;li&gt;UI库: shadcn/ui&lt;/li&gt;
&lt;li&gt;UI动画: motion&lt;/li&gt;
&lt;li&gt;云服务: Cloudflare&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;考虑到这个app不需要任何的后端逻辑，只是一个展示用的app，
而且想接触到稍微不太难的底层，所以使用了这个组合。
虽然到后期熟悉了一些React之后，还是投入了Next.JS。&lt;/p&gt;
&lt;p&gt;说起来，前段时间在学校的时候另一位同学和我猛猛吐槽tailwind，
但是一把梭真的好爽啊 尤其是对于没有学过前端的人而言。&lt;/p&gt;
&lt;p&gt;此外，Cloudflare真的是拯救了穷穷的我。&lt;/p&gt;
&lt;h2 id=&#34;2-style-component的基本思路&#34;&gt;2. Style component的基本思路
&lt;/h2&gt;&lt;p&gt;这是我第一次使用tailwind或者说正经地学习css，
并且确实是我觉得最痛苦也最烦躁的一部分之一。
还好我们有tailwind。&lt;/p&gt;
&lt;p&gt;相应地，总结了一部分思路，
个人觉得参照这些思路就可以决定自己需要哪些properties了。&lt;/p&gt;
&lt;h3 id=&#34;21-定位方式&#34;&gt;2.1 定位方式
&lt;/h3&gt;&lt;p&gt;HTML的默认定位方式是&lt;code&gt;static&lt;/code&gt;，也就是说元素会按照文档流正常排列，
不受定位影响。&lt;/p&gt;
&lt;p&gt;所以如果想改变位置，必须指定
&lt;code&gt;relative? absolute? fixed? sticky?&lt;/code&gt;。
这些决定了你定义component的坐标参考。
值得一提的是&lt;code&gt;absolute&lt;/code&gt;的参考是第一个**非&lt;code&gt;static&lt;/code&gt;**的ancestor。&lt;/p&gt;
&lt;p&gt;例如说，当你需要覆盖屏幕的overlay的时候就用&lt;code&gt;fixed&lt;/code&gt;，
它给出的坐标系就是整个视窗，随后再使用&lt;code&gt;inset-0&lt;/code&gt;即可。&lt;/p&gt;
&lt;h3 id=&#34;22-flexbox-grid-container&#34;&gt;2.2 Flexbox, grid, container
&lt;/h3&gt;&lt;p&gt;决定你的容器类型。&lt;/p&gt;
&lt;p&gt;flex和grid就不多赘述了，个人感觉要多加使用。
例如想要调整唯一元素居中的时候，相比于自己硬写，
用&lt;code&gt;justify-center&lt;/code&gt;更加鲁棒。&lt;/p&gt;
&lt;p&gt;container是tailwind提供的一种可以动态防止你的容器撑到屏幕两端的容器，
一般在style全页级的容器的时候很好用。&lt;/p&gt;
&lt;h3 id=&#34;23-位置与大小&#34;&gt;2.3 位置与大小
&lt;/h3&gt;&lt;p&gt;接下来就是决定component的位置和大小。&lt;/p&gt;
&lt;p&gt;值得注意的是，当设计component的时候不要规定component本身的大小，
而应该设计component内部的响应式布局。
至于component本身的大小，
应当交给其父元素用围绕它的&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;块级元素来进行指定。
component本身使用&lt;code&gt;w-full&lt;/code&gt;等适应其父元素，个人觉得会更好。&lt;/p&gt;
&lt;p&gt;此外，在使用比例大小和基于&lt;code&gt;vw&lt;/code&gt;，&lt;code&gt;vh&lt;/code&gt;的大小时
有些时候还是要善用max或者min的。
它可以防止元素变得过小，
也可以防止变得变得过宽盛满元素。
这个确实是新的知识，人的视野其实只能集中在屏幕上的一部分，
文字太宽的话，会变得难以阅读。&lt;/p&gt;
&lt;h3 id=&#34;24-padding和margin&#34;&gt;2.4 Padding和Margin
&lt;/h3&gt;&lt;p&gt;这个就不多赘述了。一般而言p-4(1rem)是一个不错的开始点。&lt;/p&gt;
&lt;h3 id=&#34;25-背景颜色&#34;&gt;2.5 背景颜色
&lt;/h3&gt;&lt;p&gt;简单的背景颜色调整不再赘述。&lt;/p&gt;
&lt;p&gt;一个很不错的functionality是tailwind的&lt;code&gt;bg-gradient-to-*&lt;/code&gt;，
可以很愉快的构建出渐变色彩。&lt;/p&gt;
&lt;p&gt;此外，透明度也可以很方便地调整。对于颜色是&lt;code&gt;*-color-*/[alpha]&lt;/code&gt;，
比如说&lt;code&gt;from-gray-900/50&lt;/code&gt;。&lt;code&gt;opacity-*&lt;/code&gt;也可以帮助调整。&lt;/p&gt;
&lt;h3 id=&#34;26-阴影圆角边缘等装饰&#34;&gt;2.6 阴影/圆角/边缘等装饰
&lt;/h3&gt;&lt;p&gt;Tailwind提供了非常好的&lt;code&gt;rounded-*&lt;/code&gt;，&lt;code&gt;border-*&lt;/code&gt;和&lt;code&gt;shadow-[size]&lt;/code&gt;, &lt;code&gt;shadow-[color]&lt;/code&gt;
等utilities可以来美化元素。&lt;/p&gt;
&lt;h3 id=&#34;27-图片等的处理&#34;&gt;2.7 图片等的处理
&lt;/h3&gt;&lt;p&gt;虽然严格上并不算是css相关，但是在处理用Next框架的图片的时候，
有一些必要的东西需要知道。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把next/image的&lt;code&gt;Image&lt;/code&gt;包在&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;中，再用块级元素去调整它的大小。
内层的图片加上&lt;code&gt;fill&lt;/code&gt;即可，fill会使得next将图片填满父容器。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;object-position&lt;/code&gt;和&lt;code&gt;object-fit&lt;/code&gt;决定了&lt;strong&gt;可替换元素(replaced elements)&lt;/strong&gt;
在其所占据的box中的位置。
可替换元素指的是像图片这种无法被css stylesheet影响到其本身的元素。
所以对于图片，视频而言非常重要。&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;对于&lt;code&gt;object-fit&lt;/code&gt;，常用的主要是&lt;code&gt;object-cover&lt;/code&gt;（不变形覆盖，无黑边但是会被crop）
和&lt;code&gt;object-contain&lt;/code&gt;（不变形，完整展示，但是有可能产生黑边）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;需要立刻展示的图片不要忘记了&lt;code&gt;priority&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;关于sizes，可以使用响应式，因为Next会自动调整fetch的图像的大小。
一个栗子是：&lt;code&gt;sizes=&amp;quot;(min-width: 1080px) 100vw, 1080px&lt;/code&gt;。
这样图片就会至少是1080p。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;28-动画效果&#34;&gt;2.8 动画效果
&lt;/h3&gt;&lt;p&gt;复杂的动画效果建议使用motion库。
但是简单的onhover，tailwind的&lt;code&gt;hover:scale-105&lt;/code&gt;等等的utility很好用。
具体你需要&lt;code&gt;transition-transform duration-500 hover:scale-110&lt;/code&gt;的combo。
(&lt;code&gt;transition-transform&lt;/code&gt;使得转换变得平滑。)&lt;/p&gt;
&lt;p&gt;其他的就是少用的东西了，可以随时查询调整。&lt;/p&gt;
&lt;p&gt;总结起来就是五大基础：
位置，大小（包括padding/margin的大小），颜色，装饰，动画。
图片需要多考虑一下可替换元素的特殊性质和图片的优化。&lt;/p&gt;
&lt;h2 id=&#34;3一些问题的解决方法&#34;&gt;3.一些问题的解决方法
&lt;/h2&gt;&lt;p&gt;中途碰到了一些不熟悉的实现在这里也记录一下。&lt;/p&gt;
&lt;h3 id=&#34;31-导入新字体并使用tailwind&#34;&gt;3.1 导入新字体并使用tailwind
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;下载新字体，并把woff2打包好放在public中。&lt;/li&gt;
&lt;li&gt;去global css中设置好font face。&lt;/li&gt;
&lt;li&gt;去tailwind.config.ts的theme中添加font family。
别忘记加上default themes里面的sans。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;32-预加载所有的图片后再展示&#34;&gt;3.2 预加载所有的图片后再展示
&lt;/h3&gt;&lt;p&gt;因为PR page是一系列的图片轮流播放，并且头图比较大，
所以有些用户会看到一个碎裂的图像加载出来（网速烂的时候）。&lt;/p&gt;
&lt;p&gt;自己想到的解决方法是preload完所有的hero image才开始展示。
贴个代码。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-jsx&#34; data-lang=&#34;jsx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// ...之前的代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;currentIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;setCurrentIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;useState&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isInitialLoadComplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;setIsInitialLoadComplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;useState&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 在背景第一次进入DOM后预加载，并且通过isInitialLoadComplete来控制。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nx&#34;&gt;useEffect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;preloadAllImages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// 封装为Promise，将其加载到浏览器内存。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;loadPromises&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;backgroundImagesPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Promise&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;resolve&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;onload&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;nx&#34;&gt;resolve&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// 等待全部预加载完毕。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Promise&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;loadPromises&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// 发送预加载信号。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;nx&#34;&gt;setIsInitialLoadComplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;preloadAllImages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;useEffect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isInitialLoadComplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// 预加载之后才开始播放轮换动画。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;interval&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;setInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;setCurrentIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prev&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;backgroundImagesPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;backgroundShiftIntervalSeconds&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;clearInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isInitialLoadComplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;33-渐变切换的做法以及注意点&#34;&gt;3.3 渐变切换的做法以及注意点
&lt;/h3&gt;&lt;p&gt;轮播的时候图片需要渐变隐出，与此同时下一张图片渐变进入。&lt;/p&gt;
&lt;p&gt;这个效果我们可以用framer motion来实现。motion.div可以指定退出的动画。&lt;/p&gt;
&lt;p&gt;需要注意的点是，因为&lt;code&gt;motion.div&lt;/code&gt;退出的时候，如果直接将其从DOM上移除，
那么就不会有退出动画了，会直接消失。&lt;/p&gt;
&lt;p&gt;motion的方法是将你要添加&lt;strong&gt;退出&lt;/strong&gt;动画的元素一定要包在一个&lt;code&gt;&amp;lt;AnimatePresence&amp;gt;&lt;/code&gt;中。
观察DOM可以发现，当元素被卸载时，它会存在这个Presence中一小段时间，
直到动画结束才会被卸载。&lt;/p&gt;
&lt;p&gt;此外必须要提醒的是，在&lt;code&gt;&amp;lt;AnimatePresence&amp;gt;&lt;/code&gt;中存在的元素，
一定要一个key。
motion通过检测这个key知道哪些元素发生了变化，
从而进行animate。&lt;/p&gt;
&lt;p&gt;放一个代码！&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-jsx&#34; data-lang=&#34;jsx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;useEffect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// Wait for initial load to complete
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isInitialLoadComplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;interval&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;setInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;setCurrentIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prev&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;backgroundImagesPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;backgroundShiftIntervalSeconds&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;clearInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isInitialLoadComplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;div&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;className&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;relative h-screen w-full overflow-hidden bg-[#190157]&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;AnimatePresence&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;initial&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* initial 控制一开始就有的元素是否播放动画 */&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isInitialLoadComplete&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;Background&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;na&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;currentIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;na&#34;&gt;backgroundImagePath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;backgroundImagesPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;currentIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;na&#34;&gt;backgroundShiftTransitionDuration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;backgroundShiftDurationSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;)}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;AnimatePresence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;cm&#34;&gt;/* 其他的代码 */&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;34-next的server-side-component与motion的问题&#34;&gt;3.4 Next的Server-side component与Motion的问题
&lt;/h3&gt;&lt;p&gt;因为知识不足，被这个坑了老大一把。&lt;/p&gt;
&lt;p&gt;Next默认是用React Server Component，
所以在使用Motion的时候无法完全兼容，Animate Presence的时候存在glitch。&lt;/p&gt;
&lt;p&gt;原因是因为motion使用了effects，这些只有在client端才有。&lt;/p&gt;
&lt;p&gt;解决方法是&amp;rsquo;use client&amp;rsquo;。&lt;/p&gt;
&lt;h3 id=&#34;35-关于shadcnui&#34;&gt;3.5 关于shadcn/ui
&lt;/h3&gt;&lt;p&gt;可以去&lt;code&gt;globals.css&lt;/code&gt;中设置theme colors，非常适合决定好一套颜色之后
在全网页通用使用，
可以维持审美的一致性。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;以上！&lt;/p&gt;
&lt;p&gt;这个项目做了三四天，作为小白有不少的收获，记录一下。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>关于java数据层的一些想法</title>
        <link>https://blog.louishhy.com/post/%E5%85%B3%E4%BA%8Ejava%E6%95%B0%E6%8D%AE%E5%B1%82%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/</link>
        <pubDate>Sun, 06 Oct 2024 10:05:57 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/%E5%85%B3%E4%BA%8Ejava%E6%95%B0%E6%8D%AE%E5%B1%82%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/</guid>
        <description>&lt;p&gt;今天看了一下java语言是如何访问数据库的，结果被内容和rather verbose的语法冲的头昏脑胀（？）&lt;/p&gt;
&lt;p&gt;记录一下我自己对于java数据层结构的一些理解（希望以后不要被自己错误的理解打脸x）&lt;/p&gt;
&lt;p&gt;（以及，我会感觉很多语言的数据层结构的philosophy是一样的，所以这个也有助于用来理解其他语言的数据层结构）&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.louishhy.com/post/%E5%85%B3%E4%BA%8Ejava%E6%95%B0%E6%8D%AE%E5%B1%82%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/QQ_1728209543145.png&#34;
	width=&#34;1644&#34;
	height=&#34;778&#34;
	srcset=&#34;https://blog.louishhy.com/post/%E5%85%B3%E4%BA%8Ejava%E6%95%B0%E6%8D%AE%E5%B1%82%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/QQ_1728209543145_hu13559622665110678468.png 480w, https://blog.louishhy.com/post/%E5%85%B3%E4%BA%8Ejava%E6%95%B0%E6%8D%AE%E5%B1%82%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/QQ_1728209543145_hu17701577078064841686.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;层级示意图&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;211&#34;
		data-flex-basis=&#34;507px&#34;
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;最底层jdbc和hikaricp连接池&#34;&gt;最底层：JDBC和HikariCP连接池
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;JDBC是java访问数据库的标准接口&lt;/strong&gt;。JDBC提供了一套访问数据库的API，可以通过JDBC来访问数据库，执行SQL语句，获取查询结果等。&lt;/p&gt;
&lt;p&gt;它的实现是通过JDBC&lt;strong&gt;驱动程序&lt;/strong&gt;来实现的，不同的数据库有不同的驱动程序。&lt;/p&gt;
&lt;p&gt;连接是一个昂贵的资源，所以我们需要有效率地复用连接。&lt;strong&gt;连接池&lt;/strong&gt;解决了这个问题，当需要连接的时候，从连接池中获取连接，使用完毕后，将连接放回连接池。HikariCP是目前常用的一个高性能的连接池。&lt;/p&gt;
&lt;h2 id=&#34;hibernate和jpa&#34;&gt;Hibernate和JPA
&lt;/h2&gt;&lt;p&gt;聊Hibernate之前得先聊聊JPA。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JPA规范定义了java的对象关系映射（ORM）的标准，将对象映射至数据库的表&lt;/strong&gt;。它使用Entity Manager来向数据库中CRUD对象，而不需要亲自编写JDBC或者SQL语句。它也提供了查询语言。&lt;/p&gt;
&lt;p&gt;（当然它也定义了不少其他的东西）&lt;/p&gt;
&lt;p&gt;Hibernate是一个ORM框架，不仅实现了JPA规范，还提供了一些其他的功能。Hibernate可以通过注解来定义实体类和数据库表之间的映射关系。&lt;/p&gt;
&lt;h2 id=&#34;dao&#34;&gt;DAO
&lt;/h2&gt;&lt;p&gt;DAO（Data Access Object）是一个数据访问对象，用于访问数据库。它提供了一些方法，用于CRUD数据库中的数据。&lt;/p&gt;
&lt;p&gt;举一个简单的例子&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;interface&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;UserDao&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;getUserById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insertUser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;updateUser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;deleteUser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样用户就不用关心数据库的操作，只需要调用DAO的方法即可，有利于解耦。但是事实上在不少的情况下，service直接操作数据库也是可以的。&lt;/p&gt;
&lt;h2 id=&#34;spring的事务管理transaction-management&#34;&gt;Spring的事务管理(Transaction Management)
&lt;/h2&gt;&lt;p&gt;虽然有点离题，但是spring通过实现一些Transaction Manager来实现事务管理，这样可以保证一组操作要么全部成功，要么全部失败（如果不熟悉事务，可以去看看ACID）。Spring在事务扔出RuntimeException的时候会自动回滚。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;所以通常我们建议在处理事务时派生RuntimeException，这样就不用再去手动处理了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;举个栗子：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Transactional&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;transfer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;amount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;userDao&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getUserById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;userDao&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getUserById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setBalance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getBalance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;amount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setBalance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getBalance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;amount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;userDao&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;updateUser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;userDao&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;updateUser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;另外注意，在Spring中事务默认是具有&lt;strong&gt;传递性&lt;/strong&gt;的。&lt;/p&gt;
&lt;p&gt;也就是说在一个transactional的方法中调用另一个transactional的方法，那么这两个transaction会被合并成一个transaction来执行并共同commit或者rollback。&lt;/p&gt;
&lt;p&gt;或者，引用一下&lt;a class=&#34;link&#34; href=&#34;https://liaoxuefeng.com/books/java/spring/database/declarative-tx/index.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;廖雪峰老师&lt;/a&gt;的精确说明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Spring的声明式事务为事务传播定义了几个级别，默认传播级别就是REQUIRED，它的意思是，如果当前没有事务，就创建一个新事务，如果当前有事务，就加入到当前事务中执行。&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        </item>
        <item>
        <title>Small review on CSS</title>
        <link>https://blog.louishhy.com/post/small-review-on-css/</link>
        <pubDate>Sat, 07 Sep 2024 02:07:34 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/small-review-on-css/</guid>
        <description>&lt;img src="https://images.unsplash.com/photo-1725610588150-c4cd8b88affd?q=80&amp;w=2574&amp;auto=format&amp;fit=crop&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Featured image of post Small review on CSS" /&gt;&lt;p&gt;Though I am not currently proficient in frontend, I do sometimes have to get in touch with HTML/CSS when setting up static pages. Here is some personal note on my recent refresh on CSS (last time I touched it is during my undergrad🫠).&lt;/p&gt;
&lt;h2 id=&#34;css-box-model&#34;&gt;CSS box model
&lt;/h2&gt;&lt;p&gt;Important concepts include &lt;code&gt;margin&lt;/code&gt;, &lt;code&gt;border&lt;/code&gt;, &lt;code&gt;padding&lt;/code&gt;, and &lt;code&gt;content&lt;/code&gt;. Here is a nice illustration from Wikipedia:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://upload.wikimedia.org/wikipedia/commons/7/7a/Boxmodell-detail.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Box model definition from Wikipedia&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;float&#34;&gt;Float
&lt;/h2&gt;&lt;p&gt;Float is a CSS property that specifies whether a box should float to the left, right, or not at all in its parent container. It is commonly used to wrap text around images. Understand it as putting the element &amp;ldquo;out of the normal flow&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;psuedo-classes&#34;&gt;Psuedo-classes
&lt;/h2&gt;&lt;p&gt;Psuedo-classes are used to define the special state of an element. For example, &lt;code&gt;:hover&lt;/code&gt; is used to define the style of an element when the mouse is placed over it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;link&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;hover&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;css-animations&#34;&gt;CSS Animations
&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;@keyframes&lt;/code&gt; rule is used to create animations, where the percentage is the time during the animation. For example, the following code will change the background color of an element from red to yellow to blue to green.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;keyframes&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;example&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;yellow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can also alter the timing function of the animation using the &lt;code&gt;animation-timing-function&lt;/code&gt; property, like &lt;code&gt;ease&lt;/code&gt;, &lt;code&gt;linear&lt;/code&gt;, &lt;code&gt;ease-in&lt;/code&gt;, &lt;code&gt;ease-out&lt;/code&gt;, &lt;code&gt;cubic-bezier()&lt;/code&gt; family, etc.&lt;/p&gt;
&lt;h2 id=&#34;responsive-layout&#34;&gt;Responsive layout
&lt;/h2&gt;&lt;h3 id=&#34;media-queries&#34;&gt;Media queries
&lt;/h3&gt;&lt;p&gt;Media queries are used to apply different styles for different devices, using different breakpoints. The following code will change the background color of an element to yellow when the screen width is less than 600px.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;media&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;only&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;screen&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;max-width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;600px&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;body&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;yellow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;relative-units&#34;&gt;Relative units
&lt;/h3&gt;&lt;p&gt;In introductory courses &lt;code&gt;px&lt;/code&gt; is usually used as the unit of length, but there are a bunch of other units out there that are more responsive. Those incl.:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vw&lt;/code&gt; and &lt;code&gt;vh&lt;/code&gt;: 1% of the viewport width and height, respectively.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;em&lt;/code&gt;: Relative to the font-size of the parent element.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rem&lt;/code&gt;: Relative to the font-size of the root element.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vmin&lt;/code&gt; and &lt;code&gt;vmax&lt;/code&gt;: 1% of the viewport&amp;rsquo;s smaller and larger dimension, respectively.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%&lt;/code&gt;: Relative to the parent element.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;logical-pixels&#34;&gt;Logical pixels
&lt;/h3&gt;&lt;p&gt;I have once thought that how can media handle tablet displays on iPad&amp;rsquo;s retina or other high-resolution tablets.&lt;/p&gt;
&lt;p&gt;Logical pixels is an encapsulation of the physical px in CSS, where &lt;code&gt;device-pixel-ratio&lt;/code&gt; is the ratio of physical pixels to logical pixels. This allows for high-resolution displays to display content at a higher resolution without changing the layout of the page.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Setting up Hugo static blog page</title>
        <link>https://blog.louishhy.com/post/setting-up-hugo-static-blog-page/</link>
        <pubDate>Fri, 23 Aug 2024 14:15:58 +0000</pubDate>
        
        <guid>https://blog.louishhy.com/post/setting-up-hugo-static-blog-page/</guid>
        <description>&lt;img src="https://blog.louishhy.com/post/setting-up-hugo-static-blog-page/hugo-logo-wide.svg" alt="Featured image of post Setting up Hugo static blog page" /&gt;&lt;h2 id=&#34;problem-setting&#34;&gt;Problem setting
&lt;/h2&gt;&lt;p&gt;When I first tried to build up a blog, I have been thinking about renting a VPS and running a Wordpress instance on it. This is why you have seen the previous blog. But:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VPS costs you, sometimes payment is done annually in one installment.&lt;/li&gt;
&lt;li&gt;In terms of a blog, dynamic nature of Wordpress is an overkill.&lt;/li&gt;
&lt;li&gt;Have to setup TLS termination proxy, Wordpress and a MySQL instance. Heavy :(&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have seen some of my friends spinning up their blog using &lt;code&gt;Hugo&lt;/code&gt;. With the static page hosting service (free!) by &lt;code&gt;Cloudflare Pages&lt;/code&gt;, I have decided to give it a try.&lt;/p&gt;
&lt;p&gt;In this blog, I&amp;rsquo;ll mainly talk about the &lt;strong&gt;subtle problems&lt;/strong&gt; I have faced in these sessions besides trivial documentation.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How to setup a Hugo blog&lt;/li&gt;
&lt;li&gt;Using the &lt;code&gt;Stack&lt;/code&gt; hugo theme&lt;/li&gt;
&lt;li&gt;Deploying to Cloudflare Pages&lt;/li&gt;
&lt;li&gt;Setting up Front Matter CMS (Content Management System) for easy content creation in vscode&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;1-setting-up-hugo&#34;&gt;1. Setting up Hugo
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo&lt;/a&gt; is a static site generator written in &lt;code&gt;Go&lt;/code&gt; that is blazingly fast. To start a new hugo project, simply follow the &lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/getting-started/quick-start/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;quickstart&lt;/a&gt; guide.&lt;/p&gt;
&lt;h3 id=&#34;archetypes-front-matter-template&#34;&gt;&lt;code&gt;archetypes&lt;/code&gt; front matter template
&lt;/h3&gt;&lt;p&gt;Hugo uses front matter, a &amp;ldquo;preamble&amp;rdquo; in the markdown file to store metadata and control the behavior of the content. In fact here is the front matter of this blog:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Setting up Hugo static blog page&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ld&#34;&gt;2024-08-23T14:15:58.493Z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;preview&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# This is for `Front Matter CMS`&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;draft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;categories&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# This is for `Stack` theme, the header you have seen in this post.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;slug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;setting-up-hugo-static-blog-page&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One (probably annoying thing) about Hugo is that it can use TOML, YAML or JSON for front matter. I like yaml but the default generated content with &lt;code&gt;hugo new post/your-post.md&lt;/code&gt; is TOML. In addition, sometimes you do want the autogenerated files have different front matter according to the content type.&lt;/p&gt;
&lt;p&gt;The solution is to open the &lt;code&gt;archetypes&lt;/code&gt; folder and edit the &lt;code&gt;default.md&lt;/code&gt; file, or create new ones such as &lt;code&gt;post.md&lt;/code&gt; file. Hugo will match the templates according to the type, e.g. &lt;code&gt;hugo new post/your-post.md&lt;/code&gt; will use the &lt;code&gt;post.md&lt;/code&gt; template. &lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/content-management/archetypes/#lookup-order&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Check the matching rules.&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;2-using-the-stack-hugo-theme&#34;&gt;2. Using the &lt;code&gt;Stack&lt;/code&gt; hugo theme
&lt;/h2&gt;&lt;p&gt;If I haven&amp;rsquo;t changed the theme after I have written this blog🤔, I am using the &lt;a class=&#34;link&#34; href=&#34;https://github.com/CaiJimmy/hugo-theme-stack&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Stack&lt;/a&gt; theme. More than grateful for CaiJimmy for designing this elegant theme. It also has a nice &lt;a class=&#34;link&#34; href=&#34;https://stack.jimmycai.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For those that would like to set up the frames quickly, here are some steps:&lt;/p&gt;
&lt;h3 id=&#34;setting-up-sidebar&#34;&gt;Setting up sidebar
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Go to the theme folder of the &lt;code&gt;Stack&lt;/code&gt; theme (should be something like &lt;code&gt;themes/hugo-theme-stack&lt;/code&gt;), find the &lt;code&gt;config.yaml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Find the &lt;code&gt;params.sidebar&lt;/code&gt; section and fill in the details.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;setting-up-main-menu-and-widgets&#34;&gt;Setting up main menu and widgets
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Stack&lt;/code&gt; provides menu items on the left and interesting widgets on the right side of the page. To setup those widgets you have to follow some steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create those pages under the &lt;code&gt;content/page&lt;/code&gt; folder. The theme relies on those pages to build the widgets.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;content/page/archives/index.md&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;title: &amp;#34;Archives&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;layout: &amp;#34;archives&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;slug: &amp;#34;archives&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;menu:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    main:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        params: 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            icon: archives
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;content/page/about/links.md&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;title: Links
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;links:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- This is a sample links page to Github. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; title: GitHub
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    description: GitHub is the world&amp;#39;s largest software development platform.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    website: https://github.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    image: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;menu:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    main: 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        params:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            icon: link
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;comments: false
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&amp;lt;!-- To use this feature, add &lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`links`&lt;/span&gt;&lt;span class=&#34;c&#34;&gt; section to frontmatter.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`image`&lt;/span&gt;&lt;span class=&#34;c&#34;&gt; field accepts both local and external images. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;content/page/about/search.md&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;title: &amp;#34;Search&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;slug: &amp;#34;search&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;layout: &amp;#34;search&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;outputs:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; html
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;menu:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    main:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        params: 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            icon: search
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can also add the &lt;code&gt;weight&lt;/code&gt; parameter to &lt;code&gt;menu.main.params&lt;/code&gt; to change the order of the main menu items.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;icon&lt;/code&gt; parameter refers to the SVGs in &lt;code&gt;assets/icons&lt;/code&gt; folder in your &lt;strong&gt;theme folder&lt;/strong&gt;. For example, &lt;code&gt;icon: archives&lt;/code&gt; refers to &lt;code&gt;assets/icons/archives.svg&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;After the creation of those pages, go to the &lt;code&gt;config.yaml&lt;/code&gt; file in your theme folder. We first customize the left menu:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Custom menu configurations&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The `icon` refers to the SVGs in `assets/icons` folder.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# `Stack` uses icons from tabler.io (https://tabler.io/icons), &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# which you can download for customization.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;menu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;identifier&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Home&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;weight&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;icon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;newTab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Social menu doesn&amp;#39;t have text, just a list of icons.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;social&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;identifier&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;github&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;GitHub&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;&amp;lt;your-github-link&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;icon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;brand-github&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;newTab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;widgets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;homepage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;search&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;archives&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;categories&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;toc&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This enables the menu items and widgets.&lt;/p&gt;
&lt;h3 id=&#34;fix-the-code-block-glitch&#34;&gt;Fix the code block glitch
&lt;/h3&gt;&lt;p&gt;A glitch in the current version (&lt;code&gt;Stack v3.26.0&lt;/code&gt;) is that the code block has a mysterious black background. This should be a temporary issue but here is the (&lt;a class=&#34;link&#34; href=&#34;https://github.com/CaiJimmy/hugo-theme-stack/issues/695&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;official&lt;/a&gt;) fix:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to &lt;code&gt;hugo.yaml&lt;/code&gt; (or &lt;code&gt;hugo.toml&lt;/code&gt;, if you haven&amp;rsquo;t changed the configuration file format) &lt;strong&gt;in the project root&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;markup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;highlight&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;noClasses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;3-deploying-to-cloudflare-pages&#34;&gt;3. Deploying to Cloudflare Pages
&lt;/h2&gt;&lt;p&gt;In normal circumstances deploying this stack to Cloudflare should be a smooth process.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Stack v3.26.0&lt;/code&gt; however breaks the Cloudflare automatic page building process, which is probably caused by using an old image version of Hugo. To fix this, in your page build configuration, add the environment variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Change to the newest or compatible Hugo version at your reading time.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;HUGO_VERSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;v0.133.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and it should fix the issue.&lt;/p&gt;
&lt;h2 id=&#34;4-setting-up-front-matter-cms&#34;&gt;4. Setting up Front Matter CMS
&lt;/h2&gt;&lt;p&gt;Front matter is a vscode extension that runs locally and manages your contents and does SEO. It has high flexibility but setting it up was a nightmare for me (due to my lack of coding skills 😭). Anyways, I provide some key setups aside from the general guidance Front Matter CMS provides, which itself is nice👍.&lt;/p&gt;
&lt;h3 id=&#34;markdown-front-matter-template-and-page-bundle-support&#34;&gt;Markdown front matter template and page bundle support
&lt;/h3&gt;&lt;p&gt;One thing that you have to notice is that Front Matter does not respect the settings you provided in the &lt;code&gt;archetypes&lt;/code&gt; folder. It uses its own template located inside the &lt;code&gt;frontmatter.json&lt;/code&gt; generated.&lt;/p&gt;
&lt;p&gt;Here is the modification I provide, with three augmentations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable page bundle support.
&lt;ul&gt;
&lt;li&gt;Page bundle is a way to organize your resources and an &lt;code&gt;index.md&lt;/code&gt; in one folder. If you do not know what a page bundle is, check the &lt;a class=&#34;link&#34; href=&#34;https://gohugo.io/content-management/page-bundles/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Added the &lt;code&gt;slug&lt;/code&gt; field. Slug is very important in Front Matter since it use it to open the preview (which I cover in later sections).&lt;/li&gt;
&lt;li&gt;Added the &lt;code&gt;image&lt;/code&gt; field, which is used by the &lt;code&gt;Stack&lt;/code&gt; theme.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I regard it as a very &lt;strong&gt;INELEGANT&lt;/strong&gt; modification since I directly modify the default profile, which I should create a new &lt;code&gt;post&lt;/code&gt; profile or somehow.&lt;/p&gt;
&lt;p&gt;But I mainly use CMS for writing posts, so, lazy me 🤷.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;frontMatter.taxonomy.contentTypes&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;c1&#34;&gt;// When generating page content, use a page-bundle format.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;pageBundle&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;c1&#34;&gt;// This is for the header post image in `Stack` theme.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Post image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;image&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// This is for automatic slug generation.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Slug&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;slug&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;slug&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;editable&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;{{slug}}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;      &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;preview-setup&#34;&gt;Preview setup
&lt;/h3&gt;&lt;p&gt;Front Matter CMS uses the &lt;code&gt;slug&lt;/code&gt; of the pages to generate the preview. What it actually does is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Spins up a local server (you have to click the &lt;code&gt;Start server&lt;/code&gt; button.)&lt;/li&gt;
&lt;li&gt;Generates a link to the page you are currently working on, using the rules &lt;a class=&#34;link&#34; href=&#34;https://frontmatter.codes/docs/site-preview#configuration&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;here&lt;/a&gt;. In short, &lt;code&gt;&amp;lt;preview host URL&amp;gt;/&amp;lt;frontMatter.preview.pathName&amp;gt;/&amp;lt;slug&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open a browser based on the link.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It&amp;rsquo;s important to know that you have to setup the &lt;code&gt;frontmatter.json&lt;/code&gt; correctly to use the preview feature. Also, you have to &lt;strong&gt;make sure that the preview pathname is correctly set&lt;/strong&gt;. If not, it will access &lt;code&gt;&amp;lt;hostname&amp;gt;/&amp;lt;slug&amp;gt;&lt;/code&gt; rather than, for example, &lt;code&gt;&amp;lt;hostname&amp;gt;/post/&amp;lt;slug&amp;gt;&lt;/code&gt; (let&amp;rsquo;s assume you host posts under the &lt;code&gt;content/post&lt;/code&gt; folder).&lt;/p&gt;
&lt;p&gt;The difficulty is really to recognize the aforementioned fact - once you understand it it is not hard at all and it is well documented.&lt;/p&gt;
&lt;p&gt;Check the documentation &lt;a class=&#34;link&#34; href=&#34;https://frontmatter.codes/docs/site-preview#page-folder&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;here&lt;/a&gt; to modify the generated &lt;code&gt;frontmatter.json&lt;/code&gt; by adding &lt;code&gt;previewPath&lt;/code&gt; property according to the instructions.&lt;/p&gt;
&lt;h2 id=&#34;5-epilogue&#34;&gt;5. Epilogue
&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s shift away from the technical story and talk about something rather personal.&lt;/p&gt;
&lt;p&gt;Sometimes I do think trying new thing is a hard time, but it still provides that dopamine surge that supports you to work until five in the morning. I have had a long chat with one of my friend, on the essence of software engineering (I probably will write a blog afterwards on this topic). What he essentially said is that SWE is an art for solving the problems, and it really depends on your experience to know what is the best solution.&lt;/p&gt;
&lt;p&gt;He is right, in my opinion. There are so many awesome tools out there waiting to be explored, although during the exploration I do have to bang my head against the wall just to compensate for my lack of knowledge.
Spending for like 12 hrs to just setup a page and spending another 3 hrs to write a blog recording my mistake is &amp;ldquo;not a good time management&amp;rdquo;.
But I do think it is worth it to left some record here just to make myself setting up the next blog easier.
And, if I am lucky enough to have a reader like you🤗, hope this helps.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
