Skip to content

图片标题对齐

概述

本功能实现了图片说明文字(figcaption)的智能对齐,能够根据文本长度、实际渲染宽度和换行情况自动选择最佳的对齐方式:短文本居中对齐,长文本或换行文本左对齐。特别针对移动端的换行显示问题进行了优化,避免出现第二行只有 1-2 个字的尴尬情况。

功能特性

🎯 核心特性

  • 实际宽度检测: 通过创建临时元素测量文本实际渲染宽度
  • 换行智能判断: 检测文本是否会换行以及换行是否均匀分布
  • 多语言支持: 针对中英文混合内容进行优化
  • 响应式设计: 不同屏幕尺寸使用不同的判断策略
  • 零配置: 无需手动设置,自动应用到所有 figcaption
  • 手动覆盖: 支持 CSS 类强制指定对齐方式

📱 响应式特性

  • 桌面端: 换行时阈值 50 字符,不换行时 70 字符
  • 平板端: 换行时阈值 35 字符,不换行时 50 字符
  • 移动端: 换行时阈值 20 字符,不换行时 30 字符,优先左对齐换行文本

🌐 多语言优化

  • 中文字符: 按 1.8 倍宽度计算(更精确的权重)
  • 换行检测: 智能检测不均匀换行(如末行只有 1-2 个字)
  • 混合内容: 智能处理中英文混合的文本

实现原理

对齐规则

文本情况 对齐方式 说明
短文本且不换行 居中对齐 视觉效果最佳的情况
中等文本且不换行 居中对齐 保持美观的居中显示
换行且不均匀分布 左对齐 避免末行 1-2 字的尴尬情况
移动端换行文本 左对齐 优化移动端阅读体验
很长文本 左对齐 传统的长文本对齐方式

智能检测算法

1. 实际宽度测量

// 创建临时元素测量实际渲染宽度
const testElement = document.createElement('span');
testElement.style.cssText = `
  position: absolute;
  visibility: hidden;
  font-size: 0.95rem;
  font-style: italic;
  white-space: nowrap;
`;
testElement.textContent = text;
document.body.appendChild(testElement);
const textWidth = testElement.offsetWidth;

2. 换行检测

// 检测是否会发生换行
const containerWidth = container.offsetWidth;
const actuallyWraps = textWidth > containerWidth * 0.9;

3. 不均匀换行检测

// 检测换行后是否分布不均(末行字数过少)
if (actuallyWraps && isMobile) {
  const words = text.split(/[\s\u3000]+/);
  const lastWord = words[words.length - 1];
  const avgWordLength = textLength / words.length;
  hasUnevenWrapping = lastWord.length < avgWordLength * 0.4;
}

4. 效果长度计算

// 中文字符宽度权重优化
const chineseCharCount = (text.match(/[\u4e00-\u9fff]/g) || []).length;
const englishCharCount = textLength - chineseCharCount;
const effectiveLength = englishCharCount + (chineseCharCount * 1.8);

响应式阈值策略

// 根据屏幕尺寸和换行情况动态调整阈值
let threshold;
if (isMobile) {
  threshold = actuallyWraps ? 20 : 30; // 移动端更严格
} else if (isTablet) {
  threshold = actuallyWraps ? 35 : 50; // 平板端中等
} else {
  threshold = actuallyWraps ? 50 : 70; // 桌面端宽松
}

文件结构

CSS 样式文件

assets/scss/partials/_content.scss

包含 figcaption 的基础样式和 JavaScript 控制类。

JavaScript 逻辑文件

assets/js/figcaption-alignment.js

包含智能检测和对齐控制逻辑。

模板集成

layouts/partials/js-bundle.html

JavaScript 文件已自动集成到打包系统中。

CSS 类说明

自动应用的类

  • .js-short-caption: 短文本或中等文本,居中对齐
  • .js-long-caption: 长文本或换行文本,左对齐

手动覆盖类

  • .force-center: 强制居中对齐
  • .force-left: 强制左对齐

使用方法

自动应用

功能会自动应用到页面上的所有<figcaption>元素,无需任何配置。

<figure>
  <img src="example.jpg" alt="示例图片">
  <figcaption>这是一个短标题</figcaption> <!-- 自动居中 -->
</figure>

<figure>
  <img src="example.jpg" alt="示例图片">
  <figcaption>这是一个很长的图片说明文字,包含了详细的描述信息,在移动端会换行,会自动左对齐以获得更好的阅读体验</figcaption> <!-- 自动左对齐 -->
</figure>

手动控制

如需覆盖自动对齐,可以添加强制对齐类:

<figure>
  <img src="example.jpg" alt="示例图片">
  <figcaption class="force-left">短文本但强制左对齐</figcaption>
</figure>

<figure>
  <img src="example.jpg" alt="示例图片">
  <figcaption class="force-center">长文本但强制居中对齐</figcaption>
</figure>

技术实现

CSS 基础样式

figcaption {
  // 默认居中对齐
  text-align: center;
  max-width: fit-content;
  margin-left: auto;
  margin-right: auto;

  // JavaScript 控制类
  &.js-long-caption {
    text-align: left;
    max-width: 100%;
    margin-left: 0;
    margin-right: 0;
  }

  // 手动覆盖类
  &.force-center {
    text-align: center !important;
    max-width: fit-content !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
}

JavaScript 核心逻辑

function alignFigcaptions() {
  const figcaptions = document.querySelectorAll('figcaption');

  figcaptions.forEach(caption => {
    const text = caption.textContent.trim();
    const effectiveLength = calculateEffectiveLength(text);
    const actuallyWraps = checkIfWraps(text, caption);
    const hasUnevenWrapping = checkUnevenWrapping(text, actuallyWraps);

    if (actuallyWraps && (isMobile || hasUnevenWrapping)) {
      caption.classList.add('js-long-caption');
    } else {
      caption.classList.add('js-short-caption');
    }
  });
}

性能优化

防抖处理

窗口大小变化时使用防抖(200ms)避免频繁重计算:

let resizeTimeout;
window.addEventListener('resize', function() {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(alignFigcaptions, 200);
});

条件跳过

跳过已手动设置对齐方式的元素:

if (caption.classList.contains('force-center') ||
    caption.classList.contains('force-left')) {
  return; // 跳过处理
}

错误容错

使用 try-catch 处理 DOM 操作,并提供 fallback 计算:

try {
  // 实际宽度测量
  textWidth = testElement.offsetWidth;
} catch (error) {
  // fallback: 基于字符数估算
  textWidth = effectiveLength * 12;
}

浏览器兼容性

浏览器 支持版本 说明
Chrome 60+ 完全支持
Firefox 55+ 完全支持
Safari 12+ 完全支持
Edge 79+ 完全支持
IE 不支持 现代特性不兼容

调试和测试

开启调试模式

在 JavaScript 文件中设置调试开关:

const DEBUG_MODE = true; // 开启调试信息

手动重新计算

在浏览器控制台中运行:

// 手动触发重新计算
window.alignFigcaptions();

// 临时禁用自动对齐
window.disableFigcaptionAlignment();

// 重新启用自动对齐
window.enableFigcaptionAlignment();

测试用例

建议测试以下场景:

  • 纯中文短文本
  • 纯英文短文本
  • 中英文混合文本
  • 包含标点符号的文本
  • 极长文本
  • 移动端换行情况
  • 不同屏幕尺寸下的表现

常见问题

Q: 为什么有些短文本还是左对齐?

A: 在移动端,如果短文本会换行(特别是不均匀换行),系统会自动左对齐以避免视觉上的不协调。可以查看控制台调试信息确认判断原因。

Q: 如何调整判断阈值?

A: 修改 JavaScript 文件中的阈值常量:

// 移动端阈值
if (isMobile) threshold = actuallyWraps ? 25 : 35; // 调整这些数值

// 桌面端阈值
else threshold = actuallyWraps ? 60 : 80; // 调整这些数值

Q: 可以禁用某些 figcaption 的自动对齐吗?

A: 可以,添加.force-center.force-left类即可跳过自动检测。

Q: 支持 RTL(从右到左)语言吗?

A: 当前版本主要针对中英文优化,RTL 语言支持需要额外开发。

Q: 为什么移动端更倾向于左对齐?

A: 移动端屏幕较窄,文本更容易换行。为避免出现第二行只有 1-2 个字的尴尬情况,系统在移动端采用更严格的左对齐策略。

更新日志

v2.0.0 (2024-12-20)

  • ✅ 增加实际宽度检测
  • ✅ 添加换行和不均匀换行检测
  • ✅ 优化移动端对齐策略
  • ✅ 改进调试信息显示
  • ✅ 增强错误容错机制

v1.0.0 (2024-12-20)

  • ✅ 初始版本发布
  • ✅ 基础智能对齐功能
  • ✅ 响应式阈值支持
  • ✅ 中英文混合内容优化
  • ✅ 手动覆盖类支持

维护说明

定期检查项目

  1. 测试不同长度的 figcaption 显示效果
  2. 验证响应式行为是否正常
  3. 检查新增内容的对齐效果
  4. 确保 JavaScript 无错误
  5. 测试移动端换行情况

性能监控

  • 页面加载时间影响(应该很小)
  • 窗口调整时的响应速度
  • 大量 figcaption 页面的处理性能
  • 临时 DOM 元素的创建和销毁开销

移动端优化重点

  • 验证不均匀换行检测的准确性
  • 测试不同字体大小下的表现
  • 检查不同设备 pixel ratio 的兼容性

作者: 网站开发团队 最后更新: 2024 年 12 月 20 日 版本: v2.0.0