diff --git a/assets/css/site.css b/assets/css/site.css index 29a7986..af5723e 100644 --- a/assets/css/site.css +++ b/assets/css/site.css @@ -338,3 +338,137 @@ ol > li { ul > li { line-height: 1.8; } + +/* ══════════════════════════════════════════════════════════════════ + * 容器宽度:改为流式(工单 #31) + * + * ── 改之前是什么样(线上实测,Playwright 逐 1px 扫 320~1920)────── + * Bootstrap 的 `.container` 只有 **4 个固定 max-width 档位**: + * + * 视口 576~767 → 容器 540px 单边留白 18~113.5px + * 视口 768~991 → 容器 720px 单边留白 24~135.5px + * 视口 992~1309 → 容器 960px 单边留白 16~174.5px + * 视口 1312~1920 → 容器 1280px 单边留白 16~320px + * + * 每个档位内宽度**完全不变**,于是窗口越宽、两侧空白越宽;跨过断点 + * 宽度瞬间跳一格,留白突变 89.5 / 119.5 / 158.5px —— 这就是用户说的 + * 「一蹦一蹦」「某些固定宽度下两边有两个非常宽的空白」。 + * + * 根本问题不是"断点太少",而是**容器宽度本身只有 4 个取值**。 + * 加密断点只是让台阶小一点,仍然是台阶。 + * + * ── 现在怎么算 ───────────────────────────────────────────────── + * 用 **min()** 让宽度连续跟随视口、到上限后居中: + * + * width: min(1440px, 100% - 2×边距) + * + * · 视口窄时 → `100% - 边距` 生效,宽度随窗口连续变化,两侧永远只有 + * 固定边距(不留大空白); + * · 视口宽到某个点 → `1440px` 生效,超出部分居中留白,正文不会无限拉长。 + * + * 两个分支在交界处**数值相等**(1440 + 2×边距),所以过渡是**连续的**, + * 没有台阶、没有突变。这是 min() 相比 media query 的本质优势: + * media query 是**离散判断**,min() 是**连续取值**。 + * + * ⚠️ 上限 1440px 是用户选定的(工单 #31)。原来 Bootstrap 最高到 1280, + * 1920 屏上单边空 320px;改 1440 后 1920 屏单边空 240px,同时正文 + * 依然有足够的宽度可读性。 + * + * ⚠️ 边距用 `max(16px, 2.5vw)` 而不是定值:窄屏保证 16px 不被吃掉 + * (手机上贴边很难看),宽屏略微增加,与视口更协调。2.5vw 在 1440 + * 视口时 = 36px,正好让上限分支的边距看起来不突兀。 + * + * 🔴 三条规则都要,缺一条就前功尽弃: + * ① `.container` 基础规则 —— 覆盖 Bootstrap 的 `width:100%` 与 4 个 + * `max-width` 档位(后者全在 `@media (min-width:…)` 里,优先级 + * (0,1,0) 与基础规则相同,靠**后加载**取胜,见下方说明); + * ② 页面上有 **3 个** `.container`(导航 / 主内容 / 页脚), + * 必须同一条规则覆盖,否则导航和页脚会跟正文错位; + * ③ `max-width` 必须显式设成 `none`,否则 Bootstrap 的 + * `@media (min-width:576px){.container{max-width:540px}}` 依然生效 + * —— 它和我们的基础规则同优先级,而 media query 里那条**更晚** + * 出现在 bootstrap.min.css 里;我们虽然在 site.css(更晚加载), + * 但 `max-width` 那条属性必须被我们**显式声明**才能压住。 + * + * 加载顺序(inc/theme-core.php):bootstrap → kratos.min → **site.css**, + * 所以同优先级下 site.css 胜出。 + * ⚠️ 不要用 `!important`:Bootstrap 里 `@media print` 有一条 + * `.container{min-width:992px!important}` 是打印用的,我们改的是 + * `width`/`max-width`,不冲突;一旦上 `!important` 反而会与打印样式 + * 打架。 */ +.container { + /* 宽度 = min(上限, 视口 - 两侧边距)。连续取值,无台阶。 */ + width: min(1440px, 100% - 2 * max(16px, 2.5vw)); + /* 🔴 必须显式覆盖 Bootstrap 的 4 个 max-width 档位(540/720/960/1280) */ + max-width: none; + /* 左右 auto 居中:窄屏时 width 已经等于可用宽度,auto 不产生额外偏移; + 宽屏时 width 封顶 1440,auto 把剩余空间均分到两侧。 */ + margin-right: auto; + margin-left: auto; + /* Bootstrap 原来是 15px;这里改由 width 的边距项承担, + 否则会**双重扣减**(padding 15 + width 里再扣一次边距), + 窄屏上内容被吃掉 30px。 */ + padding-right: 0; + padding-left: 0; +} + +/* 栅格行原本用 margin:-15px 抵消 container 的 15px padding。 + 现在 container 的 padding 已经是 0,这 -15px 会把内容**往外顶** 15px、 + 直接溢出容器右侧。所以同步归零。 + (`.row` 只出现在 .k-main 里,导航/页脚没有 .row,不必担心误伤。) */ +.k-main .row { + margin-right: 0; + margin-left: 0; +} + +/* 列自身的 15px padding 保留:它是"两列之间的间隙"来源, + 归零会让正文和侧栏贴在一起。这里显式声明是为了说明意图 —— + 不管 Bootstrap 以后怎么改,这一条的语义是明确的。 */ +.k-main .row > [class*="col-"] { + padding-right: 15px; + padding-left: 15px; +} + +/* 🔴 导航里的 container 要单独补偿(实测才发现) + * + * `.k-nav` 同时带着 Bootstrap 的 `.navbar` 类,而 `.navbar` 有 + * `padding-right/left: 16px`。所以导航里的 container 是嵌在**已经内缩 + * 16px** 的盒子里的: + * + * 视口 1440:正文 container 宽 1368 左 36 + * 导航 container 宽 1336 左 52 ← 比正文窄 32、右移 16 + * + * 改之前两者都是 Bootstrap 的 1280px 固定档位、都被居中,宽度一致, + * 这个 16px 内缩只表现为"导航比正文稍微靠里一点",不明显。 + * 改成流式后上限提高、位置随视口走,16px 的相对偏差就突出了, + * 导航栏的 logo/菜单会与正文左边缘对不齐。 + * + * 解法见下方规则体内注释(用同一套 width 公式 + **margin:auto 居中**; + * 我最初的两版负 margin 方案都是错的,原因记在下面)。 + * ⚠️ 不能给 `.k-nav` 直接 `padding:0` —— 那是 Bootstrap 给所有 navbar 的 + * 统一内边距,小屏折叠态下菜单面板依赖它,去掉会贴边。 */ +.k-nav > .container, +.k-nav .navbar > .container { + /* 导航里的 container 要和正文**逐像素对齐**。 + * + * 难点:`.k-nav` 同时带 Bootstrap 的 `.navbar`,而它左右各有 16px padding。 + * 直接用 `width: min(1440px, 100vw - 边距)` 会得到正确**宽度**,但 + * 位置差 16px(父级内缩没被算进去)。 + * + * 正确做法:用**与正文完全相同**的公式算宽度,然后**不要**加负 margin, + * 让 `margin: auto` 在这 16px 内缩的盒子里居中。数学上刚好抵消: + * + * 视口 1440:navbar 内容框 1408,容器 1368,auto ⇒ 左 = 16+(1408-1368)/2 = 36 ✅ + * 视口 1920:navbar 内容框 1888,容器 1440,auto ⇒ 左 = 16+(1888-1440)/2 = 240 ✅ + * + * 🔴 前两版都错在这里,值得记下: + * ① 用 `100%` + `calc(… + 32px)` + 负 margin ⇒ `100%` 在绝对定位的 + * `.k-nav` 里解析成**视口宽**,结果满宽 320@0; + * ② 用 `100vw` 公式 + `margin-left/right: -16px` ⇒ 宽度对了,但负 margin + * 把容器顶到父级 padding **之外**,左 = 0 而不是 36。 + * 负 margin 是"抵消父级内缩"的思路,但抵消之后就不再居中; + * 真正要的是"在已内缩的盒子里按比例居中"。 */ + width: min(1440px, 100vw - 2 * max(16px, 2.5vw)); + margin-right: auto; + margin-left: auto; +} diff --git a/style.css b/style.css index 419bfa0..49b4677 100644 --- a/style.css +++ b/style.css @@ -1,7 +1,7 @@ /* Theme Name: Kratos_Yang Text Domain: kratos_Yang -Version: 3.2.63 +Version: 3.2.64 Requires PHP: 7.0 Description: 这是一个Kratos主题的分支版本,用来增加一些定制化功能。 Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好