server {
...
location = /test/test.ini {
deny all;
}
...
}
其中
location = /test/test.ini
:这个配置会匹配精确的 URL 路径 /test/test.ini。deny all
:这条指令禁止所有的访问,任何请求访问该文件都会收到 403 Forbidden 错误。
完成配置后,重新加载 Nginx 配置:
sudo nginx -s reload
server {
...
location = /test/test.ini {
deny all;
}
...
}
其中
location = /test/test.ini
:这个配置会匹配精确的 URL 路径 /test/test.ini。deny all
:这条指令禁止所有的访问,任何请求访问该文件都会收到 403 Forbidden 错误。完成配置后,重新加载 Nginx 配置:
sudo nginx -s reload
header元素表示页眉,通常包含网站的标题、Logo、导航栏nav等内容。
nav元素表示导航栏,一般放在header元素或aside元素中,分别表示顶部导航栏或侧边导航栏,当然也可以视具体需求放在footer中表示底部导航栏。
我的软件环境:
Ubuntu 24
Nginx
Cloudflare DNS
我使用Let’s Encrypt的Cerbot为admin.larabbs.zuotijia.me申请SSL/TLS证书后,使用浏览器访问https://admin.larabbs.zuotijia.me网站报错:
但是同样使用Let’s Encrypt的Cerbot为www.zuotijia.me申请SSL/TLS证书,能正常通过浏览器访问https://www.zuotijia.me网站。说明不是Cerbot的问题。
错误原因
错误原因是,在Cloudflare上使用的是Cloudflare免费提供的SSL通用证书(Cloudflare Universal SSL),它只支持根域名(yourwebsite.com)以及二级泛域名(*.yourwebsite.com),不支持三级及以上的域名。
解决方法
方法一,不要使用三级及以上的域名。
方法二,在Cloudflare的仪表板->SSL/TLS->概述界面
配置加密模式为“灵活”或“关闭”:
但这种方法不够安全,因此不推荐这种方法。
方法三,不要使用Cloudflare管理域名,使用其他域名服务提供商来管理你的域名。
参考
https://devsdawn.com/2021/10/cloudflare-multi-level-subdomains-ssl-error
https://developers.cloudflare.com/ssl/edge-certificates/additional-options/total-tls/error-messages
https://developers.cloudflare.com/ssl/edge-certificates/additional-options/total-tls
https://developers.cloudflare.com/ssl/edge-certificates/additional-options/total-tls/enable
https://developers.cloudflare.com/ssl/edge-certificates/custom-certificates
https://developers.cloudflare.com/ssl/edge-certificates/custom-certificates/uploading
比如说有2个页面index.html和about.html,共用同一份style.css,那么怎么区分index.html和about.html的CSS属性不致于混淆呢?
其中一种好用的解决方法是,给index.html的body元素设置id=”index”属性,给about.html的body元素设置id=”about”属性。在style.css文件里,分别使用#index和#about作为包含选择器的开头,分别用来限定index.html和about.html的CSS属性。例如:
/* index.html的CSS */
#index div {
/* …. */
}
/* about.html的CSS */
#about div {
/* …. */
}
本文翻译自《An Interactive Guide to CSS Grid》。
CSS Grid是CSS语言中最令人惊叹的部分之一。它为我们提供了大量的新工具,可以用来创建复杂又流畅的布局。
CSS Grid非常复杂。我花了很长时间才真正适应它!
在本教程中,我将分享在我使用CSS Grid的过程中,我经历的一些精彩的时刻。你将学习这种布局模式的基础知识,并了解如何用它做一些很酷的事情。
浏览器支持情况?
CSS Grid是构建CSS布局的最现代的工具,但它并不是“前沿”。自2017年以来,所有主流浏览器都支持它!
根据caniuse的数据,97.8%的用户支持CSS Grid。Flexbox仅超过它约0.5%!
CSS由几种不同的布局算法组成,每种算法都是为不同类型的用户界面设计的。默认布局算法Flow layout是为数字文档设计的。表格布局是为表格数据而设计的。Flexbox布局用于沿单个轴分配子条目。
CSS Grid是最新、最伟大的布局算法。它非常强大:我们可以用它来构建复杂的布局,这些布局可以根据许多约束流畅地适应。
在我看来,CSS Grid最不寻常的部分是网格结构,行和列,完全在CSS中定义:
(译者注:案例请看原文)
使用CSS Grid,单个DOM节点被细分为行和列。在本教程中,我们用虚线突出显示行/列,但实际上它们是不可见的。
这太奇怪了!在所有其他布局模式中,创建这样的隔间的唯一方法是添加更多的DOM节点。例如,在Table布局中,每一行都使用<tr>创建,该行中的每个单元格都使用<td>或<th>创建:
<table>
<tbody>
<!-- First row -->
<tr>
<!-- Cells in the first row -->
<td></td>
<td></td>
<td></td>
</tr>
<!-- Second row -->
<tr>
<!-- Cells in the second row -->
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
与表格布局不同,CSS Grid允许我们完全从CSS内部管理布局。我们可以随心所欲地分割容器,创建我们的网格子节点可以用作锚点的隔间。
我们使用display属性选择网格布局模式:
.wrapper {
display: grid;
}
默认情况下,CSS Grid使用单列,并将根据子条目的数量根据需要创建一行或多行。这被称为隐式网格,因为我们还没有明确定义任何结构。
这就是它在默认情况下如何工作的:
(译者注:案例请看原文)
隐式网格是动态的;将根据子条目的数量添加或删除一行或多行。每个子条目都有自己的一行。
默认情况下,网格的容器元素的高度由其子条目的数量决定。它动态地增长和收缩。有趣的是,这甚至不是一个“CSS网格”的特性;网格的容器元素仍在使用文档流布局(Flow layout),Flow布局中的块状元素(display:block)默认会动态地垂直增长以包含其内容。只有里面的子元素使用网格布局(Grid layout)来排列。
但是,如果我们给网格的容器元素一个固定的高度呢?在这种情况下,里面的行将平均分配它的高度,即每一行都有相同的高度:
(译者注:案例请看原文)
默认情况下,CSS Grid将创建单列布局。我们可以使用grid-template-columns属性指定列:
(译者注:案例请看原文)
为清晰起见,添加了虚线
在上面的案例以及在整个教程中,我使用虚线来显示列和行之间的划分。在CSS网格布局中,这些线是不可见的,也无法使其可见。在本文章,这些虚线只做演示用。
通过grid-template-columns: 25% 75%;属性,我告诉CSS网格布局算法将元素分为两列。
列可以使用任何有效的CSS长度值来定义,包括像素、rems、视口单位等。此外,我们还可以使用一个新的单位——fr单位:
(译者注:案例请看原文)
fr代表“分数”。在这个例子中,我们说第一列消耗1单位的空间,而第二列消耗3单位的空间。这意味着总共有4个单位的空间,这成为分母。第一列消耗了1/4的可用空间,而第二列消耗了3/4。
fr单位为CSS网格带来了类似于Flexbox样式的灵活性。百分比和长度值创建了硬约束,而fr列可以根据需要自由增长和收缩,以包含其内容。
尝试缩小此容器以查看fr单位和百分比单位之间的差异:
(译者注:案例请看原文)
在上述案例中,我们的第一列有一张可爱的幽灵图片,它的宽度被设置为55px。但是,如果列太小而无法容纳它呢?
更准确地说:fr单位分配额外的空间。首先,列宽将根据列的内容计算。如果容器还有剩余空间,将根据fr单位的值进行按比例分配。这与我在《Flexbox交互式指南》中讨论的flex-grow属性的功能非常相似。
总的来说,这种灵活性是一件好事。百分比单位太严格了。
我们可以在gap中看到一个完美的例子。gap是一个神奇的CSS属性,它在网格中的所有列和行之间添加了固定数量的空间。
看看当我们在百分比单位和fr单位之间切换时会发生什么:
(译者注:案例请看原文)
请注意,当使用基于百分比单位的列时,内容是如何溢出到网格容器之外的。这是因为百分比单位是使用网格容器的总面积来计算的。这两列占用了网格容器内容区域的100%,并且不允许收缩。当我们添加16px的间隙时,这两列别无选择,只能溢出网格容器。
相比之下,fr单位是根据网格容器的额外空间计算的。在这种情况下,由于设置了间隙gap:16px;,网格容器的额外的空间减少了16px。CSS网格算法在两个网格列之间按比例分配剩余空间。
gap与grid-gap
当CSS Grid首次引入时,grid-gap属性用于在列和行之间添加空间。然而,很快,社区意识到,在Flexbox中拥有这个功能也会很棒。因此,该属性被赋予了一个更通用的名称:gap。
如今,grid-gap已被标记为弃用,浏览器将其取别名为gap。这两个属性做完全相同的事情。它们都有几乎相同的浏览器支持,约96%。
因此,我建议使用gap而不是grid-gap,无论你是使用Flexbox还是CSS grid。但也不强制转换现有的grid-gap声明。
如果我们在两列网格中添加两个以上的子元素,会发生什么?
好吧,让我们试试:
(译者注:案例请看原文)
有趣!我们的网格获得了第二行。网格算法希望确保每个子元素都有自己的网格单元。它将根据需要生成新行以实现这一目标。这在我们有可变数量的子元素(例如照片网格)并且我们希望网格能自动扩展的情况下很方便。
不过,在其他情况下,我们希望显式定义一行或多行,以创建特定的布局。我们可以使用grid-template-rows属性来实现这一点:
(译者注:案例请看原文)
通过定义grid-template-rows和grid-template-columns,我们创建了一个显式的网格。这非常适合构建页面布局,比如在本教程的顶部的“圣杯”布局。
假设我们正在构建一个日历:
对于这种场景,CSS Grid是一个很好的工具。我们可以将其构造为7列网格,每列占用1个单位的空间:
.calendar {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}
这是可行的,但要写出每一个1fr有点烦人。想象一下,如果我们有50列!
幸运的是,有一个更好的方法来解决这个问题:
.calendar {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
repeat函数将为我们进行复制/粘贴。我们只需要说我们想要7列,每列宽1fr。
以下是这个日历的完整代码:
(译者注:案例请看原文)
默认情况下,CSS网格布局算法会将每个子元素分配到第一个未被占用的网格单元,就像商人在浴室地板上铺设瓷砖一样。
不过,有一件很酷的事情:我们可以将我们的子元素分配给任何一个单元格!甚至可以跨越多行/多列。
这是一个交互式演示,展示了CSS网格布局算法是如何工作的。单击/按下或拖动以将子元素放置在网格中:
(译者注:案例请看原文)
grid-row和grid-column 属性允许我们指定网格布局的子元素应占用的网格空间。
如果我们想让子对象占据一行或一列,我们可以通过一个编号来指定它。grid-column:3将设置子元素坐在第三列。
网格子元素还可以拉伸并跨越多行或多列。此语法使用斜线来描述开始和结束:
.child {
grid-column: 1 / 4;
}
乍一看,这看起来像一个分数1/4。然而,在CSS中,斜线字符不用于分割,而是用于分隔一组值。在这种情况下,它允许我们在单个声明中设置开始列和结束列。
这实质上是对此的简写:
.child {
grid-column-start: 1;
grid-column-end: 4;
}
这里有一个狡猾的陷阱:我们提供的数字是基于列线,而不是列索引。
用图表最容易理解这个陷阱:
容易令人困惑的是,一个4列的网格实际上有5条列线。当我们为网格分配一个子元素时,我们使用这些线来锚定它们。如果我们想让我们的子元素跨越前3列,它需要从第1个列线开始,到第4个列线结束。
负数的列线
在像英语这样的从左到右读写的语言中,我们从左到右数列。然而,对于负的列号或行号,我们也可以从右向左反向计数。
.child {
/* 表示从右往左数的第2条列线 */
grid-column: -2;
}
真正酷的是,我们可以混合使用正数和负数。看看这个:
请注意,即使我们根本没有更改网格列的分配,子元素也跨越了网格的整个宽度!
我们在这里说,我们的子元素应该跨越第一列到最后一列。无论有多少列,这个方便的声明都会按预期工作。
你可以在我的博客文章“使用CSS网格布局进行全出血布局”中看到这个技巧的一个实际用例。
好了,是时候谈谈CSS Grid最酷的部分之一了。😄
假设我们正在构建此布局:
根据我们迄今为止所学到的知识,我们可以这样构建它:
.grid {
display: grid;
grid-template-columns: 2fr 5fr;
grid-template-rows: 50px 1fr;
}
.sidebar {
grid-column: 1;
grid-row: 1 / 3;
}
.header {
grid-column: 2;
grid-row: 1;
}
.main {
grid-column: 2;
grid-row: 2;
}
这是可行的,但有一种更符合人体工程学的方法:使用网格区域(grid areas)相关属性。
下面是它的样子:
(译者注:案例请看原文)
与之前一样,我们使用grid-template-columns和grid-template-rows定义网格结构。但是,我们有一个奇怪的声明:
.parent {
grid-template-areas:
'sidebar header'
'sidebar main';
}
这是如何工作的:我们正在绘制我们想要创建的网格,就像我们在制作ASCII文字艺术一样。每一行文字代表网格的一行,每个单词都是我们为网格的特定切片命名的。看看它在视觉上是如何排序的。
然后,我们不是用grid-column和grid-row来分配子元素,而是用grid-area来分配它!
当我们希望特定区域跨越多行或多列时,我们可以在模板中重复该区域的名称。在这个例子中,“sidebar”区域跨越了两行,即第一列中的两个单元格成为了“sidebar”区域。
我们应该使用grid-area还是grid-column和grid-row?当构建显式布局时,我真的很喜欢使用grid-area。它允许我为网格的分配赋予语义意义,而不是使用难以理解的行/列编号。也就是说,当网格具有固定数量的行和列时,使用grid-area效果最佳。而grid-column和grid-row对于隐式网格很有用。
当涉及到网格分配时,有一个很大的问题:选项卡的顺序仍将基于DOM位置,而不是网格位置。
用一个例子来解释会更容易。在这个例子里,我设置了一组按钮,并用CSS Grid排列它们:
(译者注:案例请看原文)
当涉及到网格分配时,有一个很大的问题:选项卡的顺序仍将基于DOM位置,而不是网格位置。
用一个例子来解释会更容易。在这个例子里,我设置了一组按钮,并用CSS Grid排列它们:
(译者注:案例请看原文)
在“结果”窗格上,按钮似乎按顺序排列。从左到右,从上到下阅读,从一到六。
如果你使用的是带键盘的设备,试着按一下这些按钮。你可以通过单击左上角的第一个按钮(“One”),然后按Tab键一次移动一个按钮。
你应该看到这样的效果:
(译者注:案例请看原文)
从用户的角度来看,焦点轮廓在页面上毫无韵律或理由地跳跃。这是因为按钮的焦点是基于它们在DOM中的顺序排序的。
为了解决这个问题,我们应该重新排序DOM中的网格子元素,使其与视觉顺序相匹配,这样我就可以实现从左到右、从上到下按视觉顺序进行制表。
CSS工作组意识到这是CSS网格布局的一个缺陷。必须将网格子元素的DOM顺序与视觉顺序相匹配,这违背了可以将子元素随意分配给特定网格单元格的目的!
修复工作正在进行中。将来,CSS属性reading-order应该允许我们指示浏览器忽略DOM顺序,并按照子元素在屏幕上的显示顺序聚焦子元素。
不幸的是,截至2024年9月,此属性尚未在任何浏览器中实现。你可以在Rachel Andrew的帖子“解决CSS布局和源代码顺序断开连接的问题”中了解有关此属性的更多信息。
在我们目前为止看到的所有示例中,我们的列和行都会拉伸以填充整个网格容器。然而,事实并非如此!
例如,假设我们定义了两列,每列宽90px。只要网格容器的宽度大于180px,就会有一些额外空间:
我们可以使用justify-content属性来控制列的分布:
(译者注:案例请看原文)
如果你熟悉Flexbox布局算法,这可能会让你感觉似曾相识。CSS Grid建立在Flexbox首次引入的对齐属性的基础上,进一步发展了这些属性。
最大的区别在于,我们对齐的是列,而不是子元素本身。本质上,justify-content允许我们排列网格的各个部分,并按照我们的意愿在网格中分布它们。
如果我们想在列中对齐子元素本身,我们可以使用justify-items属性:
(译者注:案例请看原文)
当我们将DOM节点放入网格父容器时,默认行为是将宽度其拉伸充满整个列,就像Flow布局中的<div>被水平拉伸以填充其容器一样。但是,使用justify-items,我们可以调整该行为。
这很有用,因为它允许我们摆脱列的严格对称性。当我们将justify-items设置为拉伸以外的值时,子元素将缩小到其默认宽度,由其内容决定(译者注:适应其内容)。因此,同一列中的子元素可以具有不同的宽度。
我们甚至可以使用justify-self属性控制特定网格子元素的对齐方式:
(译者注:案例请看原文)
与justify-items不同,justify-items设置在网格容器上,并控制所有网格子元素的对齐方式,而justify-self设置在子元素上。我们可以将justify-items视为一种为所有网格子元素的justify-self属性设置默认值的方法。
到目前为止,我们一直在讨论如何在水平方向上对齐内容。CSS Grid 提供了一组额外的属性来在垂直方向上对齐内容:
(译者注:案例请看原文)
align-content与justify-content类似,但它影响的是行而不是列。同样,align-items与justify-items类似,但它处理网格区域内的网格的垂直对齐,而不是水平对齐。
进一步细分:
最后,除了justify-self,我们还有align-self。此属性控制单个网格子元素在其单元格内的垂直位置。
最后我想向你展示我最喜欢的CSS Grid小技巧之一。
仅使用两个CSS属性,我们就可以将子元素水平和垂直地置于容器内:
(译者注:案例请看原文)
place-content属性是以下CSS样式的语法糖:
.parent {
justify-content: center;
align-content: center;
}
正如我们所了解的,justify-content控制列的位置。align-content控制行的位置。在这种情况下,我们有一个带有单个子元素的隐式网格,因此我们最终得到一个 1×1 网格。place-content: center会将行和列都推到网格容器的中心。
在现代CSS中有很多方法可以将一个div居中,但以上是我所知道的唯一只需要两个CSS属性的方法!
在项目开发中,是否将字体文件、图片文件等二进制文件放入 Git 仓库进行版本管理,主要取决于项目的需求和团队的工作流程。以下是一些常见的考虑因素:
1. 版本管理
文本文件(如 HTML、CSS、JavaScript 文件)通常是较小的文件,并且可以清晰地显示差异(diff)。这些文件在 Git 中的管理非常有效,特别是当多人协作时,Git 可以轻松地比较文件的不同版本、合并更改。
二进制文件(如字体文件、图片、音频、视频等)由于它们的特殊格式,Git 无法像文本文件一样处理它们的差异(diff)。Git 只能在二进制级别进行版本管理,这意味着它无法显示更改的细节,只能存储文件的完整副本。
2. 考虑因素
3. 最佳实践
方法一,使用 Git LFS(Git Large File Storage)
如果必须在 Git 仓库中管理二进制文件(如图片、字体等),可以使用 Git LFS。Git LFS 允许你将大文件(例如图片、音频、视频等)存储在专门的存储服务器上,并在 Git 仓库中仅存储指向这些文件的引用。这样可以避免仓库体积过大,提高 Git 操作的性能。
示例:
git lfs install
git lfs track "*.jpg"
git lfs track "*.png"
git lfs track "*.woff"
方法二,将大文件存储在外部服务器或 CDN
对于大图片和字体文件,可以将它们存储在外部服务器、内容分发网络(CDN)或专门的文件存储服务(如 Amazon S3)中,而不是直接存储在 Git 仓库中。然后在前端项目中通过 URL 引用它们。这样,Git 仓库只需管理轻量级的文件(如配置文件或链接文件),而不需要直接存储这些大的二进制文件。
方法三,避免频繁更新二进制文件
如果你的团队在开发过程中不需要频繁更改字体和图片文件,或者这些文件的更改非常有限,放入 Git 仓库中进行版本管理是可以的。但如果这些文件经常被修改,考虑使用 Git LFS 或其他外部存储方案。
4. 总结
运行git status
命令,输出如下信息:
Untracked files:
(use "git add <file>..." to include in what will be committed)
"m/\345\210\244\346\226\255\347\224\250\346\210\267\345\256\242\346\210\267\347\253\257\346\265\217\350\247\210\345\231\250\350\256\276\345\244\207\347\232\204\347\261\273\345\236\213/"
"m/\350\247\206\345\217\243/"
说明git不能正常显示中文目录的名字,这个问题通常是由于Git的输出字符编码与终端的编码不匹配导致的。为了解决Git在输出中文目录名称时无法正确显示的问题,你可以通过以下几步进行配置:
1. 设置Git使用UTF-8编码
确保Git提交时使用UTF-8编码:
git config --global i18n.commitencoding utf-8
确保Git输出日志时使用UTF-8编码:
git config --global i18n.logoutputencoding utf-8
关闭路径的引用(即不使用\转义路径中的特殊字符),使路径直接显示:
git config --global core.quotepath off
2. 配置终端编码使用UTF-8编码
如果你使用的是Linux或macOS系统,确保终端的编码设置为UTF-8。你可以检查终端的当前编码,运行以下命令:
echo $LANG
如果输出不是UTF-8,你可以设置终端使用UTF-8编码。修改你的终端配置文件(例如.bashrc或.zshrc),加入以下内容:
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
然后重新加载配置文件:
source ~/.bashrc # 或者 source ~/.zshrc
3. 确保文件系统支持中文字符
确认你所在的文件系统支持中文字符。大多数现代文件系统(如ext4)都支持UTF-8编码,如果你在不同的文件系统上工作,确保它支持中文路径。
4. 重新运行git status
在配置完成之后,重新运行git status
,应该能够正确显示中文目录和文件名。
设置了width=device-width后,iPhone 7 Plus的浏览器执行alert(document.body.clientWidth);显示的值是398,但是iPhone 7 Plus屏幕的分辨率是1920 x 1080像素分辨率,为什么不是显示1920呢?
当你在 iPhone 7 Plus 上使用 width=device-width 并执行 alert(document.body.clientWidth) 显示值为 398 时,这个值并不是显示的设备屏幕分辨率(1920 x 1080 像素),而是与设备的物理像素密度和设备像素比(device pixel ratio)相关的值。
设备像素比(device pixel ratio, DPR)
iPhone 7 Plus的屏幕分辨率为1920 x 1080像素,但它的设备像素比(DPR)为3。这意味着每个CSS像素(即网页设计时的逻辑像素)实际上由3个物理像素组成。例如,屏幕上实际的1 CSS像素会占用3 x 3 = 9物理像素。
width=device-width的作用
当你设置width=device-width时,浏览器会将视口的宽度设为设备的逻辑宽度,而不是真正的物理屏幕分辨率。
对于iPhone 7 Plus,视口宽度通常会设置为375px(iPhone 7 Plus设备的逻辑宽度)。这意味着你看到的document.body.clientWidth是375px,而不是1920px。
为什么会显示为398px?可能是因为浏览器在处理视口的宽度时考虑到了页面的边距、缩放因子或者其它因素。此外,浏览器还可能通过屏幕的设备像素比来进行相应的调整,从而显示为398px,而不是375px。这个值也可能受浏览器界面、工具栏或状态栏的影响。
方法一,在客户端浏览器中使用js代码判断
借助navigator对象:
示例代码如下:
<script type="text/javascript">
console.log('浏览器信息:');
console.log(navigator.userAgent);
console.log('浏览器版本名称:');
console.log(navigator.appName);
console.log('浏览器版本号:');
console.log(navigator.appVersion);
console.log('浏览器语言:');
console.log(navigator.language);
console.log('浏览器平台:');
console.log(navigator.platform);
// 从navigator.userAgent即可判断用户客户端浏览器设备的类型
// test()方法用于检测一个字符串中是否匹配某个正则模式,以下代码的功能是当用户客户端设备的类型匹配Android或webOS或iPhone或iPod或BlackBerry时,就跳转到移动端m站,否则跳转到PC端网站
window.location.href=/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)?"phone.html":"pc.html";
</script>
方法二,在服务器端使用nginx判断
根据用户设备不同返回不同样式的站点,以前经常使用的是纯前端的自适应布局,但无论是复杂性和易用性上面还是不如分开编写的好,比如我们常见的淘宝、京东……这些大型网站就都没有采用自适应,而是用分开制作的方式,根据用户请求的 user-agent 来判断是返回 PC站点还是移动端站点。
首先在 /usr/share/nginx/html 文件夹下 mkdir 分别新建两个文件夹 PC 和 mobile,vim 编辑两个 index.html 随便写点内容。
cd /usr/share/nginx/html
mkdir pc mobile
cd pc
vim index.html # 随便写点比如 hello pc!
cd ../mobile
vim index.html # 随便写点比如 hello mobile!
然后和设置二级域名虚拟主机时候一样,去 /etc/nginx/conf.d 文件夹下新建一个配置文件 fe.sherlocked93.club.conf:
# /etc/nginx/conf.d/fe.sherlocked93.club.conf
server {
listen 80;
server_name fe.sherlocked93.club;
location / {
root /usr/share/nginx/html/pc;
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
root /usr/share/nginx/html/mobile;
}
index index.html;
}
}
使用 $http_user_agent 全局变量来判断用户请求数据中的的user-agent,指向不同的root路径,返回对应站点。
参考
《你不知道的Nginx(万字详解)》
方法三,在服务器端使用编程来判断
例如,如果你使用PHP作为服务器端开发语言,那么可以Jenssegers/Agent包来判断客户端设备的类型。
Setting CSS global initial styles is mainly for ensuring compatibility across different browsers. Here’s an example:
/* Global Initial Styles */
html, body, div, span, h1, h2, h3, h4, h5, h6, a, em, img, p, dd, dl, dt, ul, li, ol, form, label, table, tr, td, input {
margin: 0;
padding: 0;
color: #333;
}
p {
font-size: 14px;
}
body {
width: 100%;
font-size: 12px;
font-family: "Microsoft YaHei", Arial, Helvetica, serif;
background-color: #f5f4f9;
}
a, a:link, a:visited {
text-decoration: none;
}
a:hover {
color: #e60012;
}
li {
list-style: none;
}
img {
border: none;
}
.clear {
clear: both;
}
If you’re using CSS frameworks like Bootstrap, LayUI, or Tailwind CSS, they’ve already set these global initial styles for you, so you don’t need to set them yourself.