Files
ulthon_information/public/static/css/phone-image-templates.css
augushong b6f2e9ef09 fix(phone-image): 移除不存在的layui dropdown依赖,改用纯JS下拉菜单
layui 2.x没有内置dropdown模块,导致整个页面JS回调不执行。
- layui.use依赖从['form','layer','dropdown']改为['form','layer']
- 用纯jQuery实现toggle下拉菜单替代dropdown.render()
- 添加more-dropdown-menu CSS hover样式
2026-05-11 23:20:20 +08:00

1006 lines
22 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ============================================
Phone Image Template System
用于生成手机端分享图片的CSS框架
渲染宽度540px, html2canvas scale=2 输出1080px
注意: 仅使用html2canvas兼容的CSS属性
支持: flexbox, border-radius, box-shadow, background-color,
font, padding, margin, border, position(relative/absolute/fixed)
不支持: transform, filter, clip-path, backdrop-filter,
CSS grid, object-fit, position:sticky, CSS animations
============================================ */
/* --- CSS Custom Properties (小红书经典风格) --- */
:root {
/* 字号 */
--pi-font-size-base: 14px;
--pi-font-size-title: 26px;
--pi-font-size-subtitle: 16px;
--pi-font-size-small: 12px;
/* 行高 */
--pi-line-height: 1.8;
/* 间距 */
--pi-spacing: 20px;
--pi-spacing-sm: 10px;
--pi-spacing-lg: 30px;
--pi-spacing-xs: 5px;
/* 颜色 */
--pi-color-text: #333333;
--pi-color-text-light: #666666;
--pi-color-text-lighter: #999999;
--pi-color-bg: #ffffff;
--pi-color-accent: #1890ff;
--pi-color-border: #eeeeee;
/* 圆角 */
--pi-radius: 12px;
/* 字体 */
--pi-font-family: 'Source Han Sans', 'SourceHanSans-Normal', sans-serif;
}
/* ============================================
Base Container
固定540px宽度的最外层容器
============================================ */
.phone-image-container {
width: 540px;
background: var(--pi-color-bg);
color: var(--pi-color-text);
font-family: var(--pi-font-family);
font-size: var(--pi-font-size-base);
line-height: var(--pi-line-height);
overflow: hidden;
position: relative;
}
/* ============================================
Page Container
每一页的容器, 尺寸由 size class 控制
============================================ */
.phone-image-page {
overflow: hidden;
box-sizing: border-box;
position: relative;
}
/* 水印 - 位于每页右下角的半透明文字 */
.page-watermark {
position: absolute;
bottom: 60px;
right: 20px;
font-size: 12px;
color: rgba(0, 0, 0, 0.3);
pointer-events: none;
white-space: nowrap;
}
/* ============================================
Size Variants
两种主流手机图片尺寸
============================================ */
/* 小红书尺寸 540x720 (输出1080x1440) */
.size-xiaohongshu .phone-image-page {
width: 540px;
height: 720px;
}
/* 抖音尺寸 540x960 (输出1080x1920) */
.size-douyin .phone-image-page {
width: 540px;
height: 960px;
}
/* ============================================
Page Type Variants
三种页面类型: 封面页/内容页/总结页
============================================ */
/* --- 封面页/首页 --- */
.page-cover {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: var(--pi-spacing-lg);
text-align: center;
}
.page-cover .cover-title {
font-size: 28px;
font-weight: normal;
letter-spacing: 2px;
line-height: 1.5;
margin-bottom: var(--pi-spacing);
color: var(--pi-color-text);
word-break: break-word;
}
.page-cover .cover-subtitle {
font-size: var(--pi-font-size-subtitle);
color: var(--pi-color-text-light);
margin-bottom: var(--pi-spacing);
}
.page-cover .cover-image {
width: 100%;
margin-bottom: var(--pi-spacing);
}
.page-cover .cover-meta {
font-size: var(--pi-font-size-small);
color: var(--pi-color-text-lighter);
margin-top: var(--pi-spacing-sm);
}
/* --- 封面页 - 无封面图装饰排版 --- */
.page-cover.no-cover-image {
justify-content: center;
padding: var(--pi-spacing-lg);
}
.page-cover.no-cover-image .cover-decor-line {
position: absolute;
left: 30px;
right: 30px;
height: 2px;
background: var(--pi-color-border);
}
.page-cover.no-cover-image .cover-decor-top {
top: 80px;
}
.page-cover.no-cover-image .cover-decor-bottom {
bottom: 80px;
}
.page-cover.no-cover-image .cover-no-img-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: var(--pi-spacing) 0;
}
.page-cover.no-cover-image .cover-no-img-title {
font-size: 36px;
font-weight: bold;
line-height: 1.4;
color: var(--pi-color-text);
word-break: break-word;
margin-bottom: var(--pi-spacing);
padding: 0 20px;
}
.page-cover.no-cover-image .cover-decor-divider {
width: 60px;
height: 3px;
background: var(--pi-color-accent);
margin-bottom: var(--pi-spacing);
}
.page-cover.no-cover-image .cover-no-img-desc {
font-size: var(--pi-font-size-subtitle);
color: var(--pi-color-text-light);
line-height: 1.8;
margin-bottom: var(--pi-spacing);
padding: 0 30px;
word-break: break-word;
}
.page-cover.no-cover-image .cover-no-img-meta {
display: flex;
gap: 15px;
font-size: var(--pi-font-size-small);
color: var(--pi-color-text-lighter);
flex-wrap: wrap;
justify-content: center;
}
/* --- 内容页图片强制约束 --- */
.page-content img {
max-width: 100% !important;
height: auto !important;
display: block;
margin: 10px 0;
}
/* --- 内容页 --- */
.page-body {
display: flex;
flex-direction: column;
padding: var(--pi-spacing);
}
/* 内容页 - 页头区域 */
.page-header {
border-bottom: none;
padding-bottom: 0;
margin-bottom: 20px;
}
.page-header .page-title {
font-size: 20px;
font-weight: normal;
letter-spacing: 1px;
color: #666;
line-height: 1.4;
word-break: break-word;
}
.page-header .page-subtitle {
font-size: var(--pi-font-size-subtitle);
color: var(--pi-color-text-light);
margin-top: var(--pi-spacing-sm);
}
/* 内容页 - 正文区域 */
.page-content {
flex: 1;
overflow: hidden;
word-break: break-word;
line-height: 2.0;
}
.page-content p {
text-indent: 2em;
margin-bottom: 16px;
color: #333;
}
.page-content h2 {
font-weight: normal;
font-size: 18px;
letter-spacing: 1px;
margin-top: 24px;
margin-bottom: 12px;
color: #333;
}
.page-content h3 {
font-weight: normal;
font-size: 16px;
margin-top: 20px;
margin-bottom: 10px;
color: #555;
}
.page-content h4 {
font-size: 14px;
font-weight: bold;
margin-top: var(--pi-spacing-sm);
margin-bottom: 5px;
}
.page-content h5 {
font-size: 13px;
font-weight: bold;
margin-top: var(--pi-spacing-sm);
margin-bottom: 5px;
}
.page-content h6 {
font-size: 12px;
font-weight: bold;
margin-top: var(--pi-spacing-sm);
margin-bottom: 5px;
color: var(--pi-color-text-light);
}
.page-content blockquote {
border-left: 1px solid #ccc;
font-style: normal;
color: #888;
padding-left: 15px;
margin: var(--pi-spacing-sm) 0;
}
.page-content ul,
.page-content ol {
padding-left: var(--pi-spacing);
margin-bottom: var(--pi-spacing-sm);
}
.page-content li {
margin-bottom: 5px;
}
/* 内容页 - 页脚区域 */
.page-footer {
border-top: none;
padding-top: 0;
margin-top: var(--pi-spacing-sm);
font-size: 11px;
color: #bbb;
display: flex;
justify-content: space-between;
align-items: center;
}
/* --- 总结页/尾页 --- */
.page-summary {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: var(--pi-spacing-lg);
text-align: center;
}
.page-summary .summary-title {
font-weight: normal;
letter-spacing: 2px;
font-size: 22px;
margin-bottom: var(--pi-spacing);
color: var(--pi-color-text);
}
.page-summary .summary-text {
font-size: var(--pi-font-size-subtitle);
color: #aaa;
font-weight: normal;
margin-bottom: var(--pi-spacing);
line-height: 1.6;
}
.page-summary .summary-qr {
margin-bottom: var(--pi-spacing-sm);
}
.page-summary .summary-footer {
font-size: var(--pi-font-size-small);
color: #ccc;
}
/* ============================================
Font Variants
============================================ */
.font-source-han-sans {
--pi-font-family: 'Source Han Sans', 'SourceHanSans-Normal', sans-serif;
}
/* ============================================
Article Images
文章内图片样式
============================================ */
/* 行内图片, 有边距 */
.article-image {
max-width: 100%;
height: auto;
display: block;
margin: var(--pi-spacing) 0;
}
/* 全宽图片, 无边距 */
.article-image-full {
width: 100%;
height: auto;
display: block;
margin: 0;
}
/* ============================================
Page Number Indicator
页码指示器
============================================ */
.page-number-indicator {
position: absolute;
bottom: 10px;
right: 15px;
font-size: var(--pi-font-size-small);
color: var(--pi-color-text-lighter);
}
/* ============================================
Vertical Alignment (逐页对齐)
============================================ */
.page-body.valign-center .page-content {
display: flex;
flex-direction: column;
justify-content: center;
}
/* ============================================
Content Flow (中间栏内容流)
所有元素按实际尺寸纵向排列
============================================ */
.content-flow {
width: 540px;
padding: 20px;
box-sizing: border-box;
background: #fff;
min-height: 100%;
}
.content-flow-block {
position: relative;
margin-bottom: 0;
}
.content-flow-block img {
max-width: 100%;
height: auto;
display: block;
}
/* --- 分页插入区域 --- */
.break-inserter {
height: 20px;
border-top: 1px dashed #ddd;
display: flex;
align-items: center;
justify-content: center;
margin: 2px 0;
cursor: pointer;
}
.break-inserter:hover {
border-color: var(--pi-color-accent);
background: rgba(24, 144, 255, 0.05);
}
.break-inserter-btn {
opacity: 0;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--pi-color-accent);
color: #fff;
font-size: 14px;
line-height: 20px;
text-align: center;
border: none;
cursor: pointer;
padding: 0;
}
.break-inserter:hover .break-inserter-btn {
opacity: 1;
}
/* --- 已插入的分页标记 --- */
.page-break-marker {
height: 30px;
background: #fff3f3;
border: 1px dashed #ff4d4f;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
margin: 4px 0;
position: relative;
}
.page-break-marker .break-marker-label {
font-size: 12px;
color: #ff4d4f;
user-select: none;
}
.page-break-marker .remove-break-btn {
position: absolute;
right: 8px;
top: 50%;
margin-top: -10px;
width: 20px;
height: 20px;
border-radius: 50%;
background: #ff4d4f;
color: #fff;
font-size: 14px;
line-height: 20px;
text-align: center;
border: none;
cursor: pointer;
padding: 0;
opacity: 0;
}
.page-break-marker:hover .remove-break-btn {
opacity: 1;
}
/* ============================================
Preview Thumbnails (缩略图容器)
============================================ */
.preview-thumbnails {
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 20px;
height: 100%;
padding: 0 10px;
}
.preview-thumb-item {
position: relative;
flex-shrink: 0;
text-align: center;
}
.preview-thumb-item img {
display: block;
border: 1px solid #e0e0e0;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.preview-thumb-page-num {
display: block;
text-align: center;
font-size: 12px;
color: #999;
margin-top: 6px;
}
.thumb-alignment-toggle {
position: absolute;
top: 8px;
right: 8px;
z-index: 10;
opacity: 0;
width: 24px;
height: 24px;
border-radius: 4px;
background: rgba(0, 0, 0, 0.06);
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #666;
user-select: none;
border: none;
padding: 0;
cursor: pointer;
transition: opacity 0.2s;
}
.preview-thumb-item:hover .thumb-alignment-toggle {
opacity: 1;
}
.thumb-alignment-toggle:hover {
background: rgba(0, 0, 0, 0.1);
}
.thumb-alignment-toggle.active-center {
opacity: 1;
background: rgba(24, 144, 255, 0.15);
color: #1890ff;
}
/* ============================================
Content Flow Code Blocks (中间栏代码块样式)
仅用于编辑区中间栏, 不影响渲染页面
============================================ */
/* 表格美化样式html2canvas兼容 */
.page-content table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 13px; }
.page-content th { background-color: #f0f0f0; font-weight: bold; padding: 8px 10px; border: 1px solid #ddd; text-align: left; }
.page-content td { padding: 8px 10px; border: 1px solid #ddd; }
.page-content tr:nth-child(even) td { background-color: #f9f9f9; }
.content-flow pre {
background: #f5f5f5;
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 12px;
overflow-x: auto;
font-size: 13px;
line-height: 1.6;
margin: 10px 0;
}
.content-flow code {
font-family: 'Courier New', Consolas, monospace;
font-size: 13px;
}
.content-flow pre code {
background: none;
border: none;
padding: 0;
}
/* 中间栏表格样式 */
.content-flow-block table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 13px; }
.content-flow-block th { background-color: #f0f0f0; font-weight: bold; padding: 8px 10px; border: 1px solid #ddd; text-align: left; }
.content-flow-block td { padding: 8px 10px; border: 1px solid #ddd; }
.content-flow-block tr:nth-child(even) td { background-color: #f9f9f9; }
/* ============================================
Page Layout Shell (页面布局外壳)
两栏布局:左侧编辑器 + 右侧预览
这些样式替代 phone-image.html 中的 inline style
============================================ */
/* --- 顶部操作栏(限定 body > 直接子元素,避免与模板 .page-header 冲突) --- */
body > .page-header {
background: #fff;
padding: 10px 20px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
height: 52px;
box-sizing: border-box;
z-index: 100;
position: relative;
}
body > .page-header-left {
display: flex;
align-items: center;
gap: 10px;
}
body > .page-header-left h3 {
margin: 0;
font-size: 16px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 300px;
color: var(--pi-color-text);
}
body > .page-header-right {
display: flex;
align-items: center;
gap: 8px;
}
/* 操作栏按钮统一样式 */
body > .page-header-right .layui-btn {
font-size: 13px;
border-radius: 2px;
}
body > .page-header-right .layui-btn i {
font-size: 13px;
margin-right: 3px;
}
/* 按钮组去掉多余边框 */
body > .page-header-right .layui-btn-group {
margin: 0;
vertical-align: middle;
}
body > .page-header-right .layui-btn-group .layui-btn {
border-radius: 0;
margin: 0;
}
body > .page-header-right .layui-btn-group .layui-btn:first-child {
border-radius: 2px 0 0 2px;
}
body > .page-header-right .layui-btn-group .layui-btn:last-child {
border-radius: 0 2px 2px 0;
}
/* 返回按钮 */
body > .page-header-left .layui-btn-primary:hover {
color: var(--pi-color-accent);
border-color: var(--pi-color-accent);
}
/* 主操作按钮 hover */
body > .page-header-right .layui-btn-normal:hover {
opacity: 0.85;
}
body > .page-header-right .layui-btn:not(.layui-btn-primary):not(.layui-btn-normal):hover {
opacity: 0.9;
}
/* 更多下拉菜单可读性优化 */
.layui-dropdown-menu {
min-width: 130px;
font-size: 13px;
}
.layui-dropdown-menu li {
padding: 8px 16px;
cursor: pointer;
transition: background 0.15s;
}
.layui-dropdown-menu li:hover {
background: rgba(24, 144, 255, 0.06);
color: var(--pi-color-accent);
}
.more-dropdown-menu li:hover {
background: rgba(24, 144, 255, 0.06);
color: var(--pi-color-accent);
}
/* --- 主布局两栏 --- */
.main-layout {
display: flex;
height: calc(100vh - 52px);
}
/* ============================================
Editor Area (wangeditor 编辑区)
左侧编辑栏容器与工具栏
============================================ */
.content-flow-area {
width: 540px;
overflow-y: auto;
border-right: 1px solid #e8e8e8;
background: #fafafa;
flex-shrink: 0;
}
#editor-toolbar {
width: 540px;
border-bottom: 1px solid #e8e8e8;
background: #fff;
position: sticky;
top: 0;
z-index: 10;
box-sizing: border-box;
}
#editor-text-area {
width: 540px;
min-height: 300px;
padding: 10px;
background: #fff;
box-sizing: border-box;
}
/* ============================================
Editor Content Typography (编辑器内排版样式)
与截图输出区域staging的视觉保持一致
作用域: #editor-text-area 内部元素
============================================ */
#editor-text-area {
font-family: var(--pi-font-family);
font-size: var(--pi-font-size-base);
line-height: var(--pi-line-height);
color: var(--pi-color-text);
}
/* 编辑区标题字号 — 与 .page-content h2~h6 对齐 */
#editor-text-area h1 {
font-size: 22px;
font-weight: bold;
letter-spacing: 1px;
margin-top: 24px;
margin-bottom: 12px;
color: var(--pi-color-text);
line-height: 1.4;
}
#editor-text-area h2 {
font-weight: normal;
font-size: 18px;
letter-spacing: 1px;
margin-top: 24px;
margin-bottom: 12px;
color: #333;
}
#editor-text-area h3 {
font-weight: normal;
font-size: 16px;
margin-top: 20px;
margin-bottom: 10px;
color: #555;
}
#editor-text-area h4 {
font-size: 14px;
font-weight: bold;
margin-top: var(--pi-spacing-sm);
margin-bottom: 5px;
}
#editor-text-area h5 {
font-size: 13px;
font-weight: bold;
margin-top: var(--pi-spacing-sm);
margin-bottom: 5px;
}
#editor-text-area h6 {
font-size: 12px;
font-weight: bold;
margin-top: var(--pi-spacing-sm);
margin-bottom: 5px;
color: var(--pi-color-text-light);
}
/* 编辑区段落 */
#editor-text-area p {
text-indent: 2em;
margin-bottom: 16px;
color: #333;
}
/* 编辑区图片 */
#editor-text-area img {
max-width: 100% !important;
height: auto !important;
display: block;
margin: 10px 0;
}
/* 编辑区表格 */
#editor-text-area table {
width: 100%;
border-collapse: collapse;
margin: 10px 0;
font-size: 13px;
}
#editor-text-area th {
background-color: #f0f0f0;
font-weight: bold;
padding: 8px 10px;
border: 1px solid #ddd;
text-align: left;
}
#editor-text-area td {
padding: 8px 10px;
border: 1px solid #ddd;
}
#editor-text-area tr:nth-child(even) td {
background-color: #f9f9f9;
}
/* 编辑区代码块 */
#editor-text-area pre {
background: #f5f5f5;
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 12px;
overflow-x: auto;
font-size: 13px;
line-height: 1.6;
margin: 10px 0;
}
#editor-text-area code {
font-family: 'Courier New', Consolas, monospace;
font-size: 13px;
}
#editor-text-area pre code {
background: none;
border: none;
padding: 0;
}
/* 编辑区引用 */
#editor-text-area blockquote {
border-left: 1px solid #ccc;
font-style: normal;
color: #888;
padding-left: 15px;
margin: var(--pi-spacing-sm) 0;
}
/* 编辑区列表 */
#editor-text-area ul,
#editor-text-area ol {
padding-left: var(--pi-spacing);
margin-bottom: var(--pi-spacing-sm);
}
#editor-text-area li {
margin-bottom: 5px;
}
/* ============================================
Divider / 分割线视觉样式 (wangeditor divider)
在编辑器中显示为分页标记提示
============================================ */
/* wangeditor divider 元素 — 虚线分页标记 */
.content-flow-area [data-w-e-type="divider"],
#editor-text-area [data-w-e-type="divider"],
#editor-text-area hr.w-e-textarea-divider,
#editor-text-area hr {
border: none;
border-top: 2px dashed var(--pi-color-accent);
margin: 15px 0;
padding: 8px 0;
text-align: center;
position: relative;
height: 0;
background: transparent;
clear: both;
}
/* 分页标记文字提示(通过 ::after 伪元素)
注意: wangeditor divider 是 void 元素,::after 可能不生效
如不生效需在 JS 中插入额外 span 提示元素 */
.content-flow-area [data-w-e-type="divider"]::after,
#editor-text-area [data-w-e-type="divider"]::after,
#editor-text-area hr.w-e-textarea-divider::after,
#editor-text-area hr::after {
content: '-- 分页标记 --';
display: inline-block;
font-size: 12px;
color: var(--pi-color-accent);
background: #fafafa;
padding: 0 10px;
position: relative;
top: -8px;
line-height: 1.8;
}
/* 分割线 hover 高亮(编辑态) */
.content-flow-area [data-w-e-type="divider"]:hover,
#editor-text-area [data-w-e-type="divider"]:hover,
#editor-text-area hr.w-e-textarea-divider:hover,
#editor-text-area hr:hover {
border-color: #40a9ff;
}
/* ============================================
Settings Dialog (设置弹框表单样式)
============================================ */
.settings-form {
padding: 20px 20px 0;
}
.settings-form .layui-form-item {
margin-bottom: 15px;
}
.settings-form .layui-form-label {
width: 60px;
font-size: 13px;
color: var(--pi-color-text-light);
}
.settings-form .layui-input-block {
margin-left: 90px;
}
.settings-form .layui-input {
border-radius: 2px;
font-size: 13px;
}
.settings-form .layui-select {
border-radius: 2px;
}
.settings-form .layui-form-select dl {
font-size: 13px;
}
/* ============================================
Preview Area (右侧预览区域)
============================================ */
.paginated-preview-area {
flex: 1;
overflow-x: auto;
overflow-y: hidden;
padding: 20px;
background: #f5f5f5;
}
#paginated-preview {
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 20px;
height: 100%;
padding: 0 10px;
}