OPPO / 一加 / ColorOS 的 Google Play 安装教程
- 开启谷歌服务:打开设置,搜索「google」,点击「Google 设置」,开启「Google 移动服务」。
- 安装 Google Play:打开应用商店,搜索「google play」,升级「谷歌应用市场」。升级完后桌面会出现「Play 商店」。
测试机型:一加 OnePlus Ace 3(ColorOS 14)、OPPO Reno12(ColorOS 14)。
测试机型:一加 OnePlus Ace 3(ColorOS 14)、OPPO Reno12(ColorOS 14)。
物理(physical)表示实际的值,逻辑(logical)表示经过缩放的值。
像素(pixel)是显示器的基本单位,一个像素显示一种颜色。为了和逻辑像素(logical pixel)区分,像素(pixel)又称物理像素(physical pixel)。
逻辑像素(logical pixel),亦称 CSS 像素(CSS pixel),是经过操作系统缩放的像素。CSS 的 px
就是 CSS 像素。
物理分辨率(physical resolution)表示像素的数量。1920×1080 分辨率就表示显示器水平方向有 1920 个像素,垂直方向有 1080 个像素,共 2073600 个像素。尺寸相同时,显示器分辨率越高,显示效果就越精细。
逻辑分辨率(logical resolution)是经过系统缩放的分辨率。
我用 1920×1080 分辨率,27 英寸的显示器,文字看得清楚。假如我换成同尺寸 3840×2160 的显示器,此时显示器像素数是前者的 4 倍,可以容纳更多的文字,文字会变得小得看不清。在浏览器按几下 Ctrl -
调节缩放也可以看到过小的文字。
在系统设置 200% 缩放后,分辨率就变成了 (3840/2)×(2160/2),也就是 1920×1080,此时文字大小又正常了。3840×2160 是物理分辨率,1920×1080是逻辑分辨率。
以 2560×1440 物理分辨率,200% 缩放的显示器为例,展示相关 Web API 的用法。
|
|
我写了个查看物理分辨率、逻辑分辨率和视口大小的网站,欢迎使用。
jQuery 是一个经典的 JavaScript 库,其功能为修改 HTML 元素、处理事件、制作动画、发送请求(Ajax)。jQuery 首次发布于 2006 年 8 月 26 日,现在(2024 年)已经 18 岁了。截止于 2024 年 10 月 23 日,有 75.8% 的网站使用了 jQuery1。
虽然 jQuery 的使用率高,但新项目没必要用 jQuery,原生 JavaScript 已经可以实现 jQuery 的操作,参看 You Might Not Need jQuery 和 You-Dont-Need-jQuery。维护老项目时可能会用到 jQuery。
jQuery 的引入方法很多,我在本文采用 CDN 引入。
|
|
下面介绍一些常见用法。
jQuery 使用 CSS 选择器获取元素。
|
|
|
|
|
|
现在页面上的元素是这样的:
|
|
jQuery 使用同一个函数来取值和赋值,根据参数数量进行不同操作。
|
|
|
|
jQuery 的每个操作都会返回 jQuery 对象,所以可以进行连续操作。
|
|
|
|
现在页面是 start 在上面,end 在下面。
本文介绍了优化博客速度的几个方式:Pjax(免刷新加载页面)、dynamic script(动态插入脚本)、rel=preload(预加载)、minification(极简化)。
本博客是 Hugo 生成的静态网站,感觉访问速度还不算慢。有天我看别人的博客(大概是单页应用),发现点击链接居然没刷新网页就加载了新页面,速度非常快。那时我想:要是我的 Hugo 博客也能这么流畅就好了。我感觉把博客改成单页应用要耗费不少时间,遂作罢。
后来我发现可以用 Pjax 技术让静态网站实现免刷新加载页面。Pjax 的意思是 pushState(修改 URL)+ Ajax(asynchronous JavaScript and XML,发送请求)。通俗来说,Pjax 就是请求网页、替换内容、修改 URL,这个过程比加载整个页面更快。
搜索 Pjax 库,找到两个好几年没更新的库(MoOx/pjax、defunkt/jquery-pjax),我不想用不维护的库。我快放弃的时候发现了一个支持 Pjax 的 Hugo 主题:hugo-theme-luna,从自述文件可以看出 Pjax 是用 swup 实现的,然后我就用它了。
如果网站没有 JavaScript 代码,那直接加载 swup 就好了。
建议使用这些插件:
<head>
元素的内容和 <html>
元素的 lang
属性。注意要先加载插件再加载 swup。
|
|
我的博客用到了 3 个 JavaScript 程序:Google Analytics(流量统计)、Giscus(评论服务)、Disqus(评论服务),用了 swup 之后要考虑是否需要额外处理。
读者点击链接加载新页面后的处理:
我写了个动态插入脚本的函数,可以设置等待时间、加载前执行的函数、async、加载后执行的函数、attribute。
|
|
我给 Google Analytics、Giscus、Disqus 加了 100ms 等待时间,给 swup 添加了 200ms 等待时间。
在 <link>
标签使用 rel="preload"
可以让浏览器提前下载资源(字体、图片、脚本、样式等),后面动态插入脚本时浏览器就可以马上执行下载好的脚本。
示例:
|
|
preload 应该叫 predownload,因为它并不会提前加载脚本,只是提前下载。
这次优化博客没用到极简化,不过既然讲到优化博客了,就顺便说一下吧。极简化就是移除代码中不必要的内容(比如:空格、空行、缩进),从而减小文件大小,这样浏览器就能更快下载完网页。
Hugo 可以极简化 HTML、CSS 和 JavaScript 文件。本博客的代码用 Hugo 极简化了。举个例子,样式文件大小原本是 13.8 kB,经过极简化后是 7.4 kB(原文件的 53.6%),传输过程中再经过 Brotli 压缩后是 2.1 kB(原文件的 15.2%)。
以下是这次优化用到的代码:
我已经用 swup 两三天了,非常满意,真没想到静态网站可以变成单页应用。Preload 插件能让浏览器会自动提前加载页面,读者点击链接时页面会瞬间加载,这个感觉太爽啦!
我手机用的系统是开源的 LineageOS 20(Android 13),跨版本升级到 LineageOS 21(Android 14)需要用电脑手动操作。因为怕操作失误导致无法开机,所以想着先备份资料,但我懒得备份资料,于是好几个月没升级。今天就来升级了。
虽然升级 LineageOS 不会清空储存空间,但为了保险起见,我按照自己的需求备份以下内容:
按照 Upgrade LineageOS on lisa | LineageOS Wiki 的步骤,安装 LineageOS 21、重启到 Recovery、安装 Google Apps、重启。
这里碰到一个奇怪的问题:手机通过数据线直接插到笔记本电脑的 USB 口,用 fastboot 可以检测到设备,但安装新系统时会报错。数据线插到 USB 集线器才行。
升级过程比我预想的简单。系统正常运作,所以清除了前面的备份。目前遇到两个问题:状态栏的快捷设置在亮色模式下仍然是暗色;Fcitx5 输入法底下的导航栏不见了,将「导航栏背景」设置为「跟随键盘背景色」即可解决。
如果你也要升级 LineageOS,不要照搬我的步骤,要遵循 LineageOS Wiki 的步骤,不同设备的升级步骤可能有差异。
在网上看到有人争论同类事物的好坏(比如:Vim 和 VS Code、Arch linux 和 Ubuntu),我认为没有必要去争。纠结哪个最好容易导致无尽的争吵。没有完美的工具,我们应该去思考工具的特点和适用场景。两个工具适用场景相似时可以先随便选一个,不要追求完美,适合就继续用,不适合就换另一个。
拿厨刀举例,主厨刀(chef’s knife)和切片刀哪个好?这个问题没有绝对的答案。
主厨刀更轻更小,刀尖有弧度。刀尖有弧度就可以用摇刀切(rock chop),适合切蒜末。
切片刀更重,用它切菜时更流畅,使用者更省力。切片刀更宽大,可以把食材拍扁,还可以把切好的食材铲起来倒入锅中。
所以哪把刀好还是得看使用者的偏好,如果你喜欢轻巧就用主厨刀,喜欢功能多就用切片刀。
当然其实这两把刀都能切蔬菜和肉,不是很了解的情况下任选一把即可。选其他工具也一样,没实际用过就感受不到细微的差别,与其纠结,不如先随便挑一个用着。
图片出处:
AmE 表示 American English(美式英语),BrE 表示 British English(英式英语),表格的空白表示没有对应名称。
标点 | 英文 | 中文 |
---|---|---|
~ | tilde | 波浪号 |
! | exclamation point (AmE) / exclamation mark (BrE) | 感叹号 |
@ | at sign / at symbol | |
# | hash / pound sign / number sign | 井号 |
$ | dollar sign | 美元符号 |
% | percent sign | 百分号 |
^ | caret | 脱字符 |
& | ampersand / and sign | |
* | asterisk | 星号 |
( ) | parenthesis (AmE) / bracket (BrE) / round bracket (BrE) | 圆括号 |
- | hyphen / minus sign | 连字符/减号 |
+ | plus sign | 加号 |
` | backtick/backquote/grave | 反引号/重音符 |
_ | underscore | 下划线 |
= | equal sign (AmE) / equals sign (BrE) | 等号 |
{ } | brace / curly bracket | 花括号 |
| | verticle bar / pipe | 竖线/管道 |
[ ] | square bracket | 方括号 |
\ | backslash | 反斜线/反斜杠 |
: | colon | 冒号 |
" | double quote / double quotation mark | 双引号 |
; | semicolon | 分号 |
' | apostrophe / single quote / single quotation mark | 撇号/单引号 |
< | less-than sign | 小于号 |
> | greater-than sign | 大于号 |
? | question mark | 问号 |
, | comma | 逗号 |
. | period (AmE) / full stop (BrE) | 句号 |
/ | slash / forward slash | (正)斜线/(正)斜杠 |
笔记软件里面的草稿越来越多,但是发布的文章却越来越少了。造成这个情况的原因有:用于写博客的时间少了、对文章的要求过高。囤着草稿是不好的,写好的文章应该发出来,为了帮助自己和他人。
刚写博客那会,我对文章内容没有太高要求,就是想着写好后几天内改几次(吐槽:这要求还不高吗),力求通俗易懂。后来写作要求提升了两次。
第一次提升要求是因为我查 Linux 资料时经常看 ArchWiki。ArchWiki 的内容又新又全面,而且注册个账号就可以贡献内容,我自己也贡献了一些内容。在这个过程中我觉得知识应该像 ArchWiki 那样,集中在一个地方,每个话题都有单独的页面,还方便大家贡献。慢慢我就不想写那些别人写过的内容,除非我能写得更好。能查到的内容就没必要写了。这就是程序员说的「Don’t repeat yourself」,不要重复产生信息。
第二次提升要求是因为我写出了排在谷歌搜索首位的文章,这给网站带来了持续的访问量,会有更多人看到我的博客,我很开心。在此之前,我一直觉得推广博客很难,到处去分享感觉就像滥发消息(spamming)。从此之后,我会优先写别人没写过的话题,写重复的话题尽量保证质量好到能排到谷歌搜索的第一页。
最近我刻意改变,将文章的重心放到帮助自己,降低要求。要求就两个:自己能读懂(可以对别人来说没那么通俗)、完整(不要写一半就发,写完初稿就可以发了)。发稿速度马上就上涨了,感觉非常好。
最近发布了四篇文章:
Grid 教程和 Flexbox 教程都是参考 CSS-Tricks 的教程写的。之前我也看过 CSS-Tricks 那两篇教程(CSS Flexbox Layout Guide | CSS-Tricks、CSS Grid Layout Guide | CSS-Tricks),但是自己写教程的过程中对两个 CSS 布局的理解更深入了,对我来说很有用。写好之后我哪里不懂也可以看自己写的教程,自己写的教程查起来更方便。写重复的话题可以加深理解,这也不意味着做复读机,我在写的过程中会有新的感悟,写出一些新内容。
写博客就像做开源项目,要让自己感觉舒服,对自己有用,这样才容易坚持。
CSS Grid 是二维布局方法,也就是用竖线和横线将内容划分成格子,像棋盘一样。本文只介绍常见用法,要了解全部用法请看 MDN Web Docs。推荐大家看完后做文末提到的习题。
display: grid | inline-grid
使元素变成网格容器,其子元素叫网格项(其他后代不算),按照网格布局排列。下面代码的 .container
是网格容器,.item
是网格项,.sub-item
不是网格项。
|
|
|
|
划分网格的竖线(vertical line)或横线(horizontal line)。横线方向和书写方向一致(英文是从左到右),竖线方向是从上到下。同一条网格线可以有多个名称。
网格布局的最小单位,就像电子表格的单元格和棋盘的格子,相邻的 2 个竖线之间和相邻的 2 条横线之间的区域。1 个网格项可以使用多个网格单元。
2 条相邻网格线之间的区域,也就是 1 个横排(row)或者 1 个竖排(column)。
由 4 条网格线划分的区域,也就是长方形,比如 1 个网格单位、4 个网格单位、6 个网格单位。
示例(A 表示网格区域):
|
|
|
|
|
|
显性网格有固定数量的网格轨道,比如 3×3。如果此时加入额外的网格项,网格将自动添加 auto 尺寸的隐性网格轨道,原来的显性网格轨道加上自动添加的隐性网格轨道就是隐性轨道。只定义竖网格线也可以产生隐性网格。
fr
表示网格容器的 1 份可用空间。
|
|
参考资料:minmax() - CSS: Cascading Style Sheets | MDN
minmax()
函数设置最小值和最大值。下面代码表示第 1 横排的尺寸最小 50px,最大 auto
(根据内容自动扩大)。
|
|
参考资料:repeat() - CSS: Cascading Style Sheets | MDN
repeat()
函数用于表示重复的网格轨道片段。
|
|
|
|
除了使用固定的数字,还可用 auto-fit
和 auto-fill
。
网格容器可以使用以下属性。
对元素使用,使其变成网格容器。
|
|
值:
参考资料:
示例(在线版):
|
|
|
|
现在网格项排列成这样:
|
|
可以用 []
定义网格线名称,用空格分隔多个名称。
|
|
grid-column-start
和 grid-row-start
可以改变网格项的位置,在线示例。
|
|
现在 .item9
占据了 .item5
的位置。
|
|
参考资料:grid-template-areas - CSS: Cascading Style Sheets | MDN
grid-template-areas
以网格区域名称表示网格的结构。grid-template-areas
的优点是放置网格项时不需要用网格线(数网格线或者命名真的太痛苦了)。相同名称可以用多次,表示占用多个网格单元。英文句号 .
表示不使用此网格单元。grid-area
定义元素对应的网格区域名称。
grid-template-areas
会自动使用 -start
和 -end
命名网格线。header
网格区域的起始网格线(横线与竖线)都是 header-start
,终止网格线(横线与竖线)都是 header-end
。同一条网格线可以有多个名称。
示例(在线版):
|
|
|
|
参考资料:
grid-template
是 grid-template-rows
、grid-template-columns
、grid-template-areas
的缩写。grid-template
不会重置隐性网格属性。
只设置 grid-template-rows
和 grid-template-columns
的用法是用 /
隔开两者。
示例(在线版):
|
|
同时设置 grid-template-rows
、grid-template-columns
、grid-template-areas
的用法:
grid-template-areas
/
和竖排的尺寸(/
从下一行开始写也行)示例(在线版):
|
|
参考资料:
row-gap
表示横排之间的间隔,column-gap
表示竖排之间的间隔。gap
是前面两者的缩写,使用 1 个值表示横排间隔和竖排间隔一样,使用 2 个值分别表示横排间隔是竖排间隔。
示例:
|
|
以前这 3 个属性前面要加上 grid-
,比如 grid-row-gap
。带 grid-
前缀的属性已被弃用,浏览器为了保持兼容,仍然支持这些属性。
参考资料:
justify-items
设置网格项 inline 轴(横轴)对齐方式,默认值为 stretch
(占满网格单元宽度)。
|
|
参考资料:
align-items
设置网格项 block 轴(竖轴)的对齐方式,默认值为 stretch
(占满网格单元高度)。baseline
表示按基线对齐。内容有多行时,first baseline
表示按照首行的基线对齐,last baseline
表示按照尾行的基线对齐。
|
|
参考资料:
place-items
是 align-items
、justify-items
的缩写。使用 1 个值同时设置 2 个属性,使用 2 个值分别设置两个属性。
|
|
参考资料:
如果网格项的总尺寸小于网格容器的尺寸,网格容器会有多于的空白,此时网格项被放置于左上角(使用从左向右的语言)。justify-content
设置 inline 轴(横轴)的对齐方式。Flex 布局也有 justify-content
,用法类似,参看 CSS Flexbox 布局教程#justify-content-主轴对齐(发布前看看这个链接对不对)。
|
|
参考资料:
如果网格项的总尺寸小于网格容器的尺寸,网格容器会有多于的空白,此时网格项被放置于左上角(使用从左向右的语言)。align-content
设置 block 轴(竖轴)的对齐方式。Flex 布局也有 align-content
,用法类似。
|
|
参考资料:place-content - CSS: Cascading Style Sheets | MDN
place-content
是 align-content
和 justify-content
的缩写。用 1 个值同时设置两者,用 2 个值分别设置两者。
示例(在线示例):
|
|
参考资料:
如果网格项数量多于已定义的网格项数量,那么多出了网格项就位于隐性网格轨道。grid-auto-columns
设置竖向隐性网格轨道大小,grid-auto-rows
设置横向隐性网格轨道大小,两者默认值都是 auto
。
|
|
参考资料:
|
|
grid-auto-flow
设置网格项的放置算法。
row
(默认值):横向放置网格项,必要时添加新的横排。
|
|
column
:竖向放置网格项,必要时添加新的竖排,在线示例。
|
|
dense
关键词表示后面的元素可以移动到前面的空位,示例(在线示例):
|
|
|
|
参考资料:
grid
是 grid-template-rows
、grid-template-columns
、grid-template-areas
、grid-auto-rows
、grid-auto-columns
、grid-auto-flow
的缩写。
创建显性网格时用法与 grid-template
一样。
创建隐性网格时有 2 种用法(左边设置横排,右边设置竖排,中间以 /
分隔):
grid-auto-flow
为 column
:<grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>?
grid-auto-flow
为 row
:[ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns>
显性横排隐性竖排示例(在线版):
|
|
隐性横排显性竖排示例(在线版):
|
|
网格项可以使用以下属性:
参考资料:
这几个属性通过网格线的起点与终点规定 1 个网格项的位置,默认值为 auto
(自动放置)。span 数字
表示占用多少个网格轨道,不加数字时为 1。
示例(在线版):
|
|
|
|
参考资料:
grid-column
是 grid-column-start / grid-column-end
的缩写,使用 1 个值时只设置 grid-column-start
。
grid-row
是 grid-row-start / grid-row-end
的缩写,使用 1 个值时值设置 grid-row-start
。
示例(在线版):
|
|
grid-area
有两个用法。一是 grid-row-start / grid-column-start / grid-row-end / grid-column-end
的缩写(吐槽:这个顺序不好读,-start
后面应该跟 -end
);二是搭配 grid-template-area
,使用名称指定位置。
示例(在线版):
|
|
justify-self
设置 1 个网格项的 inline 轴(横轴)对齐方式,默认值是 stretch
。
|
|
|
|
align-self
设置 1 个网格项的 block 轴(竖轴)对齐方式,默认是 stretch
。
|
|
|
|
参考资料:
place-self
是 align-self justify-self
的缩写,只使用 1 个值时同时设置两者。
示例:
|
|
参考资料:Subgrid - CSS: Cascading Style Sheets | MDN
虽然 subgrid
不是属性,但用于网格项,所以列举于此。
示例(在线版):
|
|
|
|
参考资料:order - CSS: Cascading Style Sheets | MDN
网格项默认按照源代码顺序出现。order
设置网格项的出现顺序,默认值为 0
,可使用正数和负数。
示例(在线版):
|
|
auto-fill
Vs auto-fit
| CSS-Tricks)auto-fill
Vs auto-fit
| CSS-Tricks本文使用的图片出自 CSS Grid Layout Module Level 1#grid-concepts。
BEM(Block, Element, Modifier)是 HTML/CSS 类的命名方法,它可以让 HTML 和 CSS 代码更有条理。
一开始看不懂没关系,后面有示例。
<nav>
),可以不包含 element。<li>
),前面要加上双下划线 __
。--
。-
连接单词,比如:search-form
。block__element1__element2
,正确写法:block__element2
。<a class="menu__link menu__link--active" href="/zh-cn/">主页</a>
。<nav>
元素是 block,它包含的 element 有 <ul>
、<li>
、<a>
。--active
是修饰符。
|
|
|
|
我更推荐用 SCSS,用父选择器 &
可以把 block 和 element 的样式都放在一起,这种结构可以清晰地展现它们的层级关系。
|
|
如果你觉得 BEM 太冗长或者难以维护,那你可以试试原子式1 CSS 框架(atomic CSS framework),比如:Tailwind CSS 和 UnoCSS。这些框架会提供 utility(预定义的类)。开发者只需要写预定义的类名,不需要写 CSS 代码。以下是一些 Tailwind CSS 的 utility:
|
|
用 Tailwind CSS 重写之前的 CSS 代码(在线示例):
|
|
atomic CSS 一般译为「原子化 CSS」,我认为这个翻译是错的。「化」表示状态变化,对应英文的「-ize」和「-ify」词缀,比如:净化(purify)、标准化(standardize)。atomic 可以拆分成 atom(原子)和 -ic(形容词后缀),所以我把 atomic 翻译成原子式,「式」表示形式、样式。atomic 也可以翻译成原子型,「型」表示类型、样式。 ↩︎
Flexbox(弹性盒子)是一维的布局方法,也就是在一条横线(row)或者竖线(column)上排列元素。推荐大家看完本文后做文末提到的习题。
flex 容器(flex container)的属性有 display
、flex-direction
、flex-wrap
、flex-flow
、justify-content
、align-items
、align-content
、row-gap
、column-gap
、gap
。
以下的 section
元素包含了 3 个 article
元素。
|
|
要排列 article
元素,将它们的父元素设置为 flex 容器。
|
|
在上述例子中,section
元素是 flex 容器(flex container),article
元素是 flex 项(flex item)。
flex-direction
定义排列方向和主轴。
|
|
row
(默认值):横向,和文字方向(dir)一致,如果方向是从左往右,那么就是从左往右排列子元素row-reverse
:和前者相反,从右往左column
:纵向,从上到下column-reverse
:和前者相反,从下到上主轴(main axis)就是和 flex 项排列方向一致的轴,交叉轴(cross axis)则是与主轴垂直的轴。一定要分清楚方向和两条轴,在对齐 flex 项时会用到。
|
|
上述代码表示从左到右排列 flex 项,主轴是从左到右,交叉轴是从上到下。
flex-wrap
控制是否换行,默认不换行。
|
|
nowrap
(默认值):全部 flex 项排列成一条线wrap
:溢出时换行wrap-reverse
:溢出时换行,但后面的元素会排到前面示例代码(在线示例):
|
|
|
|
flex-flow
是 flex-direction
和 flex-wrap
的缩写,默认值为 row nowrap
。
下面两份代码效果一样:
|
|
|
|
justify-content
设置主轴的对齐方式。
|
|
下面只介绍常用的值。
flex-start
(默认):将所有 flex 项放到主轴的起点。如果主轴是 row(从左到右),那么所有 flex 项贴近左边。例子(.
表示空间):Item1Item2Item3......
。flex-end
:将所有 flex 项放到主轴的终点。例子:......Item1Item2Item3
。center
:将所有 flex 项放在主轴的中间。例子:....Item1Item2Item3....。
space-between
:均匀分配 flex 项,每个 flex 项之间的距离一样,头部 flex 项贴近主轴开头,尾部 flex 项贴近主轴末尾,例子:Item1..Item2..Item3
。space-around
:均匀分配 flex 项,每个 flex 项的前后间隔一样,例子:.Item1..Item2..Item3.
。space-evenly
:均匀分配 flex 项,每个 flex 项之间的距离一样,头部 flex 项和主轴开头有一样的距离,尾部 flex 项和主轴末尾有一样的距离。例子:..Item1..Item2..Item3..
。交叉轴垂直于主轴。align-items
设置交叉轴的对齐方式。
|
|
align-items
用法和 justify-content
类似,这里介绍一些不一样的值。
stretch
(默认值):使 flex 项填满容器。baseline
:根据基线对齐,用于字体大小不同的 flex 项,图示。align-content
设置多行 flex 项的交叉轴对齐方式,flex 项只有一行时(flex-wrap: nowrap;
)无效,图示。
|
|
align-content
用法和 align-items
类似。
如果在 flex 项上画横线和竖线,row-gap
表示横线的间隔大小,column-gap
表示竖线的间隔大小,gap
是前面两者的缩写,在线示例。
|
|
gap
只是设置最小间隔,使用 space-between
可以加大间隔。
flex 项(flex item)的属性有 order
、flex-grow
、flex-shrink
、flex-basis
、flex
、align-self
。
flexbox 没有 justify-self
,参看 Box alignment in flexbox - CSS: Cascading Style Sheets | MDN#there_is_no_justify-self_in_flexbox。
默认情况下,flex 项按照源代码出现的顺序排列。使用 order
属性可以改变顺序,默认值为 0,数字越大位置越后,可以使用负值(比如:-1)。如果多个 flex 项的 order
值一样,它们还是按原始顺序排列。
|
|
图示:
|
|
flex-basis
设置 flex 项的大小,默认为 auto
。
|
|
flex 容器有多余空间时,flex-grow
设置 flex 项的增长系数,默认为 0(不增长),负值无效。
|
|
上面代码表示将多余空间(假设为 100px)均分为 4 份,.item1
的宽度增加 1 份(25px),.item2
的宽度增加 2 份(50px),.item3
的宽度增加 1 份(25px),在线示例。
空间不足时,flex-shrink
设置 flex 项的收缩指数,默认为 1(可收缩),0 表示不可收缩,负值无效。flex-shrink
的效果和 flex-grow
类似。
假设有 1 个 200px 宽度的 flex 容器,它包含 3 个 flex 项(每个宽度 100px,共 300px),此时有 100px 溢出的宽度。
|
|
如果 flex 项总宽度减去 100px,那么就不会溢出,在线示例。
|
|
上面代码表示把溢出的 100px 均分为 4 份。.item1
宽度减去 1 份(25px),变成 75px;.item2
宽度减去 2 份(50px),变成 50px;.item3
宽度减去 1 份(25px),变成 75px。
flex
是 flex-grow
、flex-shrink
和 flex-basis
的缩写,默认为 0 1 auto
。推荐使用 flex
代替那 3 个属性,它会自动使用合理的默认值。比如使用 flex: 1
设置 flex-grow: 1
时,flex-basis
会变成 0%。
flex
可以使用 1~3 个值,具体用法请看 flex - CSS: Cascading Style Sheets | MDN。
使用 flex
可以轻松设置 flex 项的大小比例,在线示例。
|
|
align-self
设置单个 flex 项的交叉轴对齐方式,用法和 align-items
一样,两者可以同时用。
本文列举了本站于2024年7月28日至2024年08月03日的改动。
@
)post
文件夹改为 posts
改动很多,最好在 Git 仓库建一个分支搭配子域名(如 test.cyrusyip.org
)测试,没问题再合并代码至主分支。修改网站要注意功能和链接(URL)变动,改了链接要修改文章内部链接、重定向、迁移评论。
不再使用以下软件/服务:
删除相关文件,修订自述文件和 package.json
。
先构建一次,保存起来
|
|
删除 Jane 主题和相关文件,重命名配置和中文内容文件夹。
|
|
安装主题。
|
|
写新配置,对照原来的配置(_config.toml
)。删掉了 keywords、description、Google Analytics、Disqus、utterances,后面再加回来。
|
|
构建,对比目录名和文件名变化,如果没变化表示 URL(链接)没变化。用 tree 命令列举两次构建的文件,复制到剪切板,使用 Diffchecker 对比。
|
|
新主题编译的网站少了一些没用到的页码,这里无需处理。新网站还多了一篇 2021-01-29-python-calculate-utility-bills.Rmarkdown
,这是 Rmarkdown 文件,不应该出现于此,在配置文件忽略它。
|
|
构建网站后再对比,没这个 .Rmarkdown
文件了。
对比:
enableGitInfo
,还没添加统计和评论功能(只是加脚本应该不太会影响构建时间)。用肉眼对比新旧网站,看看有没有问题。看样式、文章数量、日期等。
另建一个站点测试会比较稳妥,但这次为了节约时间就直接改了。
giscus 由 GitHub Discussions 驱动,功能比 utterances 强,支持多语言和回复评论。
转换步骤:
gh issue edit
命令giscus.json
配置文件,限制域名,参看 giscus/ADVANCED-USAGE.md#originsblog-comment
改为 blog-comments
,去 giscus 官网重新获取脚本(非必须步骤,这里存了超过一则评论,所以用复数 comments)之前用的 Even 主题 和 Jane 主题 要求内容放在 content/post
文件夹,但是标签(/tags/
)和类别(/categories/
)用的是复数,我觉得这非常不协调。这次换主题终于可以改成复数 posts
了。
改了之后网站链接(URL)会变化,需要重定向旧链接、修改文章内链接、迁移评论,参考我之前写的文章(真是帮了大忙):
构建未修改的网站并保存。
|
|
重命名文件夹。
|
|
预览并修改配置。
|
|
|
|
|
|
|
|
关掉 Hugo 服务器,构建修改后的网站并保存。
|
|
复制两个网站目录的结构到剪切板,用 Diffchecker 对比。
|
|
就只是 post
目录变成了 posts
。
|
|
要将 [本站的某文章](/zh-cn/post/2021/01/01/hi/)
这样的链接改成 [本站的某文章](/zh-cn/posts/2021/01/01/hi/)
。
获取包含链接的文件,并删掉不需要改的链接。
|
|
链接记录节选:
|
|
自己手动改链接,改一条就删去一条记录。使用 hugo server --navigateToChanged
命令预览网站可以很方便地查看变化。
我一开始让 ChatGPT 写 Node.js 脚本帮我改,多番交流后它生成了一些不存在的链接,看来这个工作还是太难为它。
现在本站使用 Cloudflare Pages 构建,参考 Redirects · Cloudflare Pages docs 设置重定向。我有点搞不懂我之前写的一些重定向规则,所以要写好注释,未来的我会感谢现在写注释的我。
|
|
测试链接:
关闭 Disqus 和 giscus 评论,以免迁移时有读者留言。
参考教程:How to download, edit, and upload a URL Map CSV | Disqus
打开迁移工具,点击「Start URL mapper」->「you can download a CSV here」,去邮箱拿到下载链接,下载并解压。这个 CSV 里面的链接非常乱,有无评论的、带查询参数的(/?utterances=xxx
)、失效链接。建一个 Git 仓库,把 CSV 文件放进去并提交,后面方便看改动。
修改 CSV,留下以 https://cyrusyip.org/zh-cn/post
和 https://cyrusyip.org/en/post
开头的。
文件节选:
|
|
在 Vim 执行 :%s/.*/&,&
,现在每行都有两个一样的链接,提交改动。
|
|
执行 :%s/\v(.*)(post)/\1posts
,现在把每行第二个链接的 post
改成 posts
,提交改动。
|
|
把修改后的 CSV 文件上传到 Disqus 的 URL mapper。
将标题的 post
改为 posts
。
示例:
|
|
GitHub CLI 不支持修改 Discussion,又得手动改了。
这几篇文章有 Disqus 评论,打开看看是否有评论。
在 Discussions 里找几篇文章,打开看看是否有评论。
可以看到评论,重新打开 Disqus 和 giscus。
一开始我用 Hugo 做中文网站时打算在文章里用中文标签,但是链接里面的中文会被转换为人类读不懂的字符。比如:/zh-cn/tags/博客/
会变成 /zh-cn/tags/%E5%8D%9A%E5%AE%A2/
。我不喜欢这样,当时搜索一番也没找到办法,就用英文标签了。现在终于知道怎么改了,最终改为链接里面还是用英文,但是页面就显示中文。
下面是针对 hugo-theme-jane(ef8a126)主题的更改方法,方法是通用的,但是不同主题修改的部分可能不同。开始前先厘清两个概念:标签名(tag name)、标签标题(tag title)。在文章前页(front matter)写的是标签名,用于链接;在 _index.md
文件定义的是 title 是标签标题,它会显示于页面。
|
|
|
|
如果你启用了 GitInfo 而且不想更改 lastmod,请参考 Hugo:给文章添加 lastmod(上次修改时间)。
/zh-cn/tags/*/
) #
以 anime(日本动画)为例。先自定义一个标签的标题。
|
|
添加内容:
|
|
文章前页(front matter)的 tags 还是保持用 anime。
|
|
现在 /zh-cn/tags/anime/
会显示「日本动画」。
/zh-cn/post/*
) #
在浏览器 inspect 找到 CSS 类,然后去 VS Code 搜索。
本地预览网站。随便打开一篇文章(http://localhost:1313/zh-cn/post/2022/12/03/ajin-oad/),滚动到底部的标签,右击 Inspect,可以看到对于的 HTML 代码。
|
|
搜索主题目录。
|
|
可以发现此代码就在 themes/jane/layouts/post/single.html
,将其复制到 layouts/post/
(我之前复制过,这次跳过此步骤)。
编辑 layouts/post/single.html
。
找到下面这段代码:
|
|
将 <a href="{{ .Permalink }}">{{ $name }}</a>
里面的 $name
改为 .LinkTitle
。改完是这样的:
|
|
现在 http://localhost:1313/zh-cn/post/2021/03/21/dongman/
底下会显示标签「日本动画」。
/zh-cn/tags/
) #
用前面的方法 Inspect 元素并搜索代码。
|
|
可以发现标签列表页面的模板为 themes/jane/layouts/_default/terms.html
,复制一份到根目录再改。
|
|
打开 layouts/_default/terms.html
,搜索 tag-cloud-tags
,找到这段代码。
|
|
将里面的 $tagName
改为 .LinkTitle
:
|
|
提交改动。
|
|
标签名全部改成全小写,以连字符分割。改动比较多,新建一个分支,提交完再合并到主分支。
|
|
使用 VS Code 插件 Front Matter CMS 修改标签名。
加标签标题就比较繁琐,要自己创建文件。我让 ChatGPT 给我写了个脚本,好使!
我说的话:
I am customizing tag titles in a Hugo website. I want you to create a CLI program.
1
create-tag-title directory tag-name tag-title
If I run
1
create-tag-title content/en arch-linux 'Arch Linux'
the program should create
content/en/tags/arch-linux/_index.md
, the content of_index.md
should be:
1 2 3
--- title: Arch Linux ---
ChatGPT 给的 Python 脚本(Shebang 是我加的1):
|
|
自己写提交信息还是太繁琐,让 ChatGPT 把这部分也加上。
我说的话:
Besides creating the
_index.md
, I want to stagecontent/
directory and commit. Example:
1
git add content/; git commit -m 'tag-title: arch-linux -> Arch Linux'
ChatGPT 返回的代码(Shellbang 是我加的):
|
|
我使用的 Python 版本是 3.12.4。
可以在修改前后构建网站,用于对比。如果链接有变化,需要重定向旧链接。改了一堆东西,我已经没心思检查了,忽略此步骤。
写完文章我才想到可以让 ChatGPT 加 Shebang ↩︎
本网站使用 Hugo 构建,文章日期(date)是这样的:
|
|
这里缺少了时间和时区。于是我给全部文章都设置了同一个时区(时间没填就是 00:00:00),但这个办法有隐患。如果我在另一个时区写文章,这时新的文章还是使用了旧时区。所以最好在每篇文章写上日期、时间和时区。
Hugo 日期的格式为 ISO 8601,示例:
|
|
补全日期的方法就是去掉引号1、补上 T00:00:00+08:00
。T00:00:00
是时间,+08:00
是时区。
修改日期前先给全部文章加上 lastmod(上次修改时间),不然修改日期后 lastmod 全部变成今天了。
在根目录新建 use-iso8601-date.sh
,添加执行权限。
|
|
在 use-iso8601-date.sh
填入脚本内容。
|
|
修改前先构建网站,后面用于对比。
|
|
补全日期。
|
|
删除时区配置。
|
|
再次构建网站。
|
|
使用文件对比工具(我用的是 Kompare)对比 public-original
和 public-changed
,有一处差异:/en/post/2023/11/06/hugo-top-level-404/
文内代码块的日期也被修改了。这样改也没错。
预览,稍微和 https://cyrusyip.org/ 对比一下,看起来一样。
|
|
删除构建的网站。
|
|
查看差异后提交改动。
|
|
删除脚本。
|
|
日期的引号去不去都行,我觉得不用更简洁就选择去掉。 ↩︎
背景:本站文章的 lastmod(上次修改时间)就是 Git 提交的 author date(作者日期)。我需要批量修改文章(Hugo:补全文章的 ISO 8601 日期),这会导致所有文章的 lastmod 都变成今天。文章内容没变就不应该改 lastmod,所以我打算给每篇文章都加上 lastmod,后面改动文章就 lastmod 就不会变。
先把 lastmod 的优先级调至最高,不然 Hugo 会继续使用 Git 提交日期。
|
|
在根目录新建 add-lastmod.sh
,添加执行权限
|
|
往 add-lastmod.sh
填入脚本内容。
|
|
修改前先构建网站,后面用于对比。
|
|
添加 lastmod。
|
|
再次构建网站。
|
|
使用文件对比工具(我用的是 Kompare)对比 public-original
和 public-changed
,结果完全相同。
预览,稍微和 https://cyrusyip.org/ 对比一下,看起来一样。
|
|
删除构建的网站。
|
|
查看差异后提交改动。
|
|
删除脚本。
|
|