7: CSS
Phlo 在 <style> 块中使用紧凑的、无分号的 CSS 语法。
您可以使用 冒号 作为分隔符来编写规则:
selector: property: value- 嵌套:
A: B: property: value→ 输出:A B { property: value; }
规则:
- 一行 = 一个声明。 源代码中没有分号;引擎会添加它们。
- 冒号
:分隔链级别以及属性与值。 - 嵌套中的反斜杠
\将 下一个选择器部分 "粘合" 到父级(粘合)。下一个部分可以是伪类(:…)、属性选择器([…])等。 @media (…)可以出现在选择器块中;Phlo 会将其提升 到正确的位置,同时保留当前选择器。
7.1: `<style>` 块
<style>
html: height: 100dvh
body {
background: #947b6c
font-family: Sans-serif
p: line-height: 2em
}
</style>
输出(概念上):
html { height: 100dvh; }
body { background: #947b6c; font-family: Sans-serif; }
body p { line-height: 2em; }
一个 <style> 块可以通过 ns= 目标一个或多个包命名空间:<style ns=docs> 编译成 www/docs.css,<style ns=app,docs> 编译到两个包,而没有 ns= 的块则编译到 data/app.json 中的 defaultNS。有关命名空间模型,请参见第 2 章。相同的属性适用于 <script> 块。
7.2: 链和组
用冒号连接;用逗号分组,并且完整上下文应用于每个项目。
<style>
body: h1, p: \:first-letter: color: green
</style>
- 上下文:
body - 目标:
h1和p(带有连接的:first-letter) - 反斜杠在
:first-letter前面将该部分与链中的前一个选择器连接在一起。
输出:
body h1:first-letter,
body p:first-letter { color: green; }7.3: 选择器中的媒体查询
您可以在选择器块内部编写 @media (…);Phlo 会将其移动到正确的位置并保持选择器上下文:
<style>
h1 {
color: white
@media (max-width: 768px): color: black
}
</style>
输出:
h1 { color: white; }
@media (max-width: 768px){
h1 { color: black; }
}7.4: 变量
Phlo 支持 CSS variables 通过 $names。
您可以在 :root 中定义变量,或在任何其他级别,但 :root 是全局主题的常用位置。
<style>
:root {
$background: #0d0d0d
$surface: #1a1a1a
$text: #ffffff
$accent: #ff4a00
}
body {
background: $background
color: $text
}
button {
background: $accent
color: $text
}
</style>
输出
:root {
--background: #0d0d0d;
--surface: #1a1a1a;
--text: #ffffff;
--accent: #ff4a00;
}
body {
background: var(--background);
color: var(--text);
}
button {
background: var(--accent);
color: var(--text);
}
👉 Phlo 自动将 $variables 转换为 --custom-properties,并在引用时使用 var(--...)。
您可以在任何地方重用变量,包括媒体查询和嵌套选择器内部。
7.5: 动态变量
Phlo的前端引擎包括DOM/CSS.var库,它允许您直接从JavaScript读取和更新在CSS中定义的$variables,通过全局的app.var对象。
您在CSS中的每个$variable自动变为app.var.<name>可用。
示例
<style>
:root {
$background: #0d0d0d
$text: #ffffff
}
</style>
<script>
app.var.background = '#000000'
const textColor = app.var.text
</script>
app.var.background = '#000000'→ 实时更新DOM中--background的值,无需重建或重新加载。const textColor = app.var.text→ 读取当前值。
👉 这些更新在浏览器中实时生效,并立即影响所有使用该变量的元素。
您可以将其用于其他一些功能:
- 主题切换(深色/浅色模式)
- 根据用户输入动态调整强调颜色
- 交互式用户界面,无需切换单独的CSS类
工作原理
- CSS引擎将
$background转换为--background。 - 前端引擎通过
document.documentElement.style读取/写入它。 app.var提供一个简单的代理对象,因此您可以像处理普通JS属性一样处理这些。
7.6: 完整示例
输入
html: height: 100dvh
body {
background: #947b6c
font-family: Sans-serif
p: line-height: 2em
}
body: h1, p: \:first-letter: color: green
h1 {
color: white
@media (max-width: 768px): color: black
}
p {
color: navy
\:last-child: color: yellow
}
输出
body {
background: #947b6c;
font-family: Sans-serif;
}
body h1:first-letter,
body p:first-letter {
color: green;
}
body p {
line-height: 2em;
}
h1 {
color: white;
}
html {
height: 100dvh;
}
p {
color: navy;
}
p:last-child {
color: yellow;
}
@media (max-width: 768px){
h1 {
color: black;
}
}7.7: 最佳实践
- 使用
$variables来定义颜色、间距和字体;这使得主题和深色/浅色模式变得简单。 - 在
:root中定义全局主题变量。 - 使用选择器链和分组来编写紧凑、可读的代码。
- 将
@media直接放在块内;Phlo 会将其提升到正确的位置。 - 在嵌套中使用
\将伪类或属性粘合到父选择器。 - 代码中不使用分号;Phlo 会生成正确的 CSS 输出。
7.8: 图标精灵
在 data/app.json 中将 icons 指向一个或多个 PNG 文件夹,构建过程会将它们合成一个单一的 www/icons.png 精灵图以及使用它们的 CSS:
{
"icons": "%app/icons/",
"iconNS": "app"
}
命名约定:save.png 变为类 .icon.save;save.dark.png 变为同一类,作用于 body.dark,因此一个图标名称可以有上下文变体(主题、状态)。在视图中的用法:
<i.icon.save/>
生成的 CSS 会放入 iconNS 包(默认是 app),并且 view() 会自动预加载精灵图。