CKEditor 5 图片样式(Image Styles)完全指南:语义化样式与表现型样式的配置与实现
【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5
图片样式(Image Styles)是 CKEditor 5 中控制图片外观的核心特性。它通过为图片附加 CSS 类或在行内(inline)与块级(block)图片类型之间切换来调整图片表现,内置语义化样式与表现型样式两套体系,并支持通过config.image.styles与config.image.toolbar深度定制 UI。阅读本文后,你将掌握图片样式的工作机制、默认样式表、自定义样式与下拉菜单配置,以及与之配套的内容 CSS 编写方法,能够为你的编辑器集成量身定制图片排版方案。
本指南基于仓库中的官方文档 packages/ckeditor5-image/docs/features/images-styles.md 展开,并结合 imageconfig.ts、imagestyle/utils.ts 等源码进行佐证。
图片样式如何工作:CSS 类与图片类型
图片样式功能的工作机制包含两个层面:
- 应用 CSS 类:为图片添加某个预定义样式或自定义样式对应的 CSS 类,或移除图片上已有的样式相关 CSS 类;
- 管理 HTML 表示:在行内与块级图片类型之间切换。应用某个样式时,图片类型可能随之改变,这取决于该样式的具体配置。
关于最终样式效果,需要明确一个分工:CKEditor 5 编辑器只负责管理样式类名,而实际外观样式由集成方(integrator)负责编写。编辑器内部自带一套默认内容样式(见下文),但只作用于编辑器内的展示;集成方需要在自己的目标页面上为这些类名编写相应的 CSS。编辑器默认内容样式的源码位于 packages/ckeditor5-image/theme/index-content.css,关于编辑器内容样式的通用配置方法,可参考 docs/getting-started/setup/css.md。
图片类(Image classes)的添加与移除
应用到图片上的样式,要么添加一个样式相关类,要么移除它,具体行为取决于对应的 {@link module:image/imageconfig~ImageStyleOptionDefinition 样式定义}。只有带isDefault: true标记的定义才会移除图片上已有的样式相关类。
需要特别注意的是,ImageStyle插件本身不提供为"新插入图片"自动应用默认 CSS 类的机制。新插入图片的初始外观应由集成方通过定义合适的内容样式来处理。如果需要定制默认外观,可以覆盖以下两条 CSS 规则:
.ck-content .image-inline—— 行内图片;.ck-content .image—— 块级图片。
行内图片与块级图片
编辑器支持以**行内(inline)或块级(block)**两种形式显示图片:
- 行内图片表现为行内 HTML 元素,可以像普通文本一样插入到段落中间或链接内部:
- 在可编辑区域内为
<span class="image-style-class"><img></img></span>; - 通过 {@link module:core/editor/editor~Editor#getData
getData()} 取出的 HTML 内容中为<img class="image-style-class"></img>。
- 在可编辑区域内为
- 块级图片只能插入在段落、表格、媒体等块元素之间,其 HTML 表示为
<figure class="image image-style-class"><img></img></figure>。
通过应用或移除样式,即可在两种图片类型之间切换。每个定义的样式选项都提供了它可作用的图片类型列表(modelElements)。当执行imageStyle命令时,如果当前图片类型不在目标样式的支持列表中,命令会自动触发图片类型转换(见 imagestylecommand.ts 中的shouldConvertImageType逻辑)。
新插入图片时,编辑器默认会根据插入上下文(当前光标位置、所选插件等)自动选择最优的图片类型。你可以通过image.insert.type配置(可选值为'block'、'inline'、'auto',默认'block',参见 imageconfig.ts)来控制新插入图片的默认类型。CKEditor 5 同时支持块级与行内图片,也可以只启用其中一种类型。
默认配置依赖已加载插件
从 imagestyle/utils.ts 的getDefaultStylesConfiguration()可以看出,默认样式列表取决于加载了哪些图片编辑插件:
- 同时加载
ImageBlockEditing与ImageInlineEditing(通常的默认配置)时,可用选项为'inline'、'alignLeft'、'alignRight'、'alignCenter'、'alignBlockLeft'、'alignBlockRight'、'block'、'side'; - 仅加载
ImageBlockEditing时,可用选项为'block'、'side'; - 仅加载
ImageInlineEditing时,可用选项为'inline'、'alignLeft'、'alignRight'。
同时在normalizeStyles()中,配置会被规范化并校验:如果某个样式定义的modelElements与已加载插件不匹配,该样式会被过滤掉,并在控制台输出image-style-missing-dependency警告(见 imagestyle/utils.ts)。
UI:工具栏按钮与默认图片工具栏
ImageStyle插件会为每个定义的样式(包括默认样式和自定义样式)在 {@link module:ui/componentfactory~ComponentFactory 组件工厂} 中以imageStyle:图片样式名的名字注册一个按钮,例如imageStyle:block、imageStyle:side。你可以通过这个名称把它添加到图片工具栏或主工具栏中。
默认图片工具栏已经预置了标准配置:
- 经典(classic)、行内(inline)、气泡(balloon)与气泡块(balloon block)编辑器类型,默认 UI 是一组应用语义化样式的按钮,用于支持结构化内容创作;
- 文档编辑器(document)类型的 UI 则使用多个按钮应用表现型样式,同时使用语义化样式(如
block)来把图片外观重置为默认状态。
此外你还可以创建完全自定义的图片样式 UI,自定图标(icon)与提示(tooltip),并把图片样式按钮分组进自定义下拉菜单,详见下文配置样式一节。
两种样式设计思路
CKEditor 5 提供两种基本的图片样式设计思路:
- 语义化样式(Semantical styles):某个样式直接定义图片的类型与用途,例如"头像"(avatar)、"横幅"(banner)或"表情图标"(emoticon)。它关注图片在内容中的语义角色;
- 表现型样式(Presentational styles):让用户可以独立、任意地控制图片的大小和对齐。它关注图片的呈现外观。
需要说明的是,这一区分是纯理论性的:两种样式的配置方式完全一致,都通过 {@link module:image/imageconfig~ImageConfig#stylesImageConfig#styles} 配置完成。
语义化样式(Semantical styles)
语义化样式让用户从开发者预定义的一组"外观方案"中挑选。用户不能单独设置边框、对齐、外边距、宽度等属性,而只能选择集成方预先定义好的样式。这让集成方能够把大量外观属性一次性打包,既控制了用户最终能做出的样式选择,也简化了用户操作。
以下示例展示了一个基础配置的编辑器,包含三种图片:
- 块级图片(
block):无样式相关 CSS 类的块级图片表示; - 行内图片(
inline):无样式相关 CSS 类的行内图片表示; - 侧边图片(
side):应用了image-style-sideCSS 类的语义化样式。
你可以通过点击图片后弹出的上下文工具栏(contextual toolbar)来切换单张图片的样式。
设计语义化样式时有几点建议与警告:
- 先想清楚你的系统需要支持哪些用例,再据此定义语义化选项。定义清晰有用的样式是良好用户体验与可移植输出的基础。例如示例中的 "side image" 在宽屏上以浮动图片显示,在低分辨率屏幕(如移动端浏览器)上则以普通图片显示;
- 语义化样式可以手动图片缩放功能(images-resizing)组合使用,但这两个特性并不是为一起使用而设计的——语义化样式通常也会影响图片尺寸。如果希望启用图片缩放,请改用表现型样式;也可以自定义语义化样式,确保它与图片缩放特性不冲突。
表现型样式(Presentational styles)
表现型样式不关联内容的特殊含义,直接控制图片的视觉呈现。默认提供的表现型样式决定图片的对齐行为。预设的表现型图片样式按图片在文档中的显示方式分组到下拉菜单中:
- 行内图片(inline):显示在文本行内。它是行内图片的默认样式,不向图片应用任何 CSS 类;
- 被文本环绕的图片(wrap text):应用 CSS
float属性的图片,可以是行内模式或块级模式。为保证 HTML 输出合法,带<figure>标签的块级图片只能放置在段落前后,而不能插入段落中间。包含两种样式:'align-left'—— 图片左对齐并让文本环绕;'align-right'—— 图片右对齐并让文本环绕。
- 放置在段落之间的图片(break text):不带
float属性的块级图片。包含三种样式:'align-block-left'—— 块级图片左对齐;'align-block-right'—— 块级图片右对齐;'block'—— 居中块级图片,是块级图片的默认样式,不向图片应用任何 CSS 类。
同样地,点击图片后通过上下文工具栏即可切换样式。表现型样式应该与可选的图片缩放特性搭配使用:图片宽度由缩放特性控制,对齐由样式特性控制。
需要注意两个边界情况:
- 如果在使用默认表现型样式时没有启用图片缩放特性,图片将始终保持原始尺寸(最大不超过编辑器宽度的 100%),对齐效果可能不明显;
- 如果不想启用图片缩放,可以使用语义化样式来设定图片尺寸。
在文档编辑器中,这组按钮和样式默认可用,无需额外定制。最基本的文档编辑器配置如下:
import { DecoupledEditor } from 'ckeditor5'; DecoupledEditor.create( { root: { element: document.querySelector( '#editor' ) } } ).then( /* ... */ );⚠️目前不能同时给一张图片应用多个样式(类)。如果需要为图片叠加多条 CSS 规则(例如同时有红色边框和左对齐),应该考虑使用语义化样式。
图片缩放与样式联动
表现型样式示例通常会搭配图片缩放特性一起使用。你可以通过config.image.resizeOptions定义缩放选项(参见 imageconfig.ts 的完整文档),例如:
image: { resizeUnit: '%', resizeOptions: [ { name: 'resizeImage:original', value: null }, { name: 'resizeImage:50', value: '50' }, { name: 'resizeImage:75', value: '75' } ] }上述配置让用户可以把图片宽度设置为原始尺寸(最大为编辑器窗口宽度的 100%)、50% 或 75%,也可以拖动缩放手柄(resize handles)自定义尺寸。
配置样式
在编辑器配置中定义图片样式有三种方式:
- 直接引用某个预定义默认样式(传字符串名称即可,如
'side'); - 修改某个默认样式——可以改变它应用到图片上的类、图标、提示文字以及支持的图片类型;
- 定义一个全新的自定义图片样式。
复用(或修改)预定义样式还有一个额外好处:CKEditor 5 会为这些按钮标题提供官方翻译。
完整配置示例与 API 参考,见 {@link module:image/imageconfig~ImageConfig#styles
config.image.styles} 的文档注释(imageconfig.ts),以及仓库中的官方示例片段 packages/ckeditor5-image/docs/_snippets/features/image-style-custom.js。
自定义样式与下拉菜单示例
下面的配置来自官方示例,展示了:完全自定义的图片样式、自定义图片工具栏(含声明式下拉菜单ImageStyleDropdownDefinition),以及对部分默认样式的修改:
ClassicEditor .create( { // ... 其他配置项 ... image: { styles: { // 定义图片的自定义样式选项。 options: [ { name: 'side', icon: sideIcon, title: 'Side image', className: 'image-side', modelElements: [ 'imageBlock' ] }, { name: 'margin-left', icon: leftIcon, title: 'Image on left margin', className: 'image-margin-left', modelElements: [ 'imageInline' ] }, { name: 'margin-right', icon: rightIcon, title: 'Image on right margin', className: 'image-margin-right', modelElements: [ 'imageInline' ] }, // 修改默认行内与块级图片样式的图标和标题, // 以反映其真实外观。 { name: 'inline', icon: inlineIcon }, { name: 'block', title: 'Centered image', icon: centerIcon } ] }, toolbar: [ { // 把"图标式"图片样式按钮分组到一个下拉菜单。 name: 'imageStyle:icons', title: 'Alignment', items: [ 'imageStyle:margin-left', 'imageStyle:margin-right', 'imageStyle:inline' ], defaultItem: 'imageStyle:margin-left' }, { // 把"图片式"样式按钮分组到另一个下拉菜单。 name: 'imageStyle:pictures', title: 'Style', items: [ 'imageStyle:block', 'imageStyle:side' ], defaultItem: 'imageStyle:block' }, '|', 'toggleImageCaption', 'linkImage' ] } } ) .then( /* ... */ ) .catch( /* ... */ );这个编辑器除了正确展示自定义图片样式(image-margin-right、image-margin-left、image-side等类)之外,还提供了默认的内容样式,保证标题、段落、链接、题注(caption)以及新插入图片的外观一致性。
配套内容 CSS
样式类名本身不会产生视觉效果,必须配合内容 CSS。下面是官方示例中最核心的图片样式 CSS 规则,完整的样式表可参考示例片段 packages/ckeditor5-image/docs/_snippets/features/image-style-custom.js 所引用的 HTML 模板:
/* 定义块级图片的默认内容样式。 这就是新插入、没有任何样式特定类的图片的样子。 */ .ck-content .image { margin-top: 50px; margin-bottom: 50px; } .ck-content .image img { border-radius: 50%; width: 180px; height: 180px; object-fit: cover; filter: grayscale(100%) brightness(70%); box-shadow: 10px 10px 30px #00000078; } .ck-content .image::before { content: ''; width: 100%; height: 100%; background-color: #1138b0; top: 5%; left: 5%; position: absolute; border-radius: 50%; } .ck-content .image::after { content: ''; width: 200%; height: 200%; background-image: url(../../assets/img/image-context.svg); background-size: contain; background-repeat: no-repeat; position: absolute; top: -60%; pointer-events: none; left: -60%; } /* 定义行内图片的默认内容样式。 */ .ck-content .image-inline { margin: 0 4px; vertical-align: middle; border-radius: 12px; } .ck-content .image-inline img { width: 24px; max-height: 24px; min-height: 24px; filter: grayscale(100%); } /* 定义放置在编辑区侧边的图片的自定义内容样式。 */ .ck-content .image.image-side { float: right; margin-right: -200px; margin-left: 50px; margin-top: -50px; } .ck-content .image.image-side img { width: 360px; height: 360px; } /* 定义放置在编辑器页边距的图片的自定义内容样式。 */ .ck-content .image-inline.image-margin-left, .ck-content .image-inline.image-margin-right { position: absolute; margin: 0; top: auto; } .ck-content .image-inline.image-margin-left { left: calc( -12.5% - var(--icon-size) / 2 ); } .ck-content .image-inline.image-margin-right { right: calc( -12.5% - var(--icon-size) / 2 ); } .ck-content .image-inline.image-margin-left img, .ck-content .image-inline.image-margin-right img { filter: none; } /* 定义图片题注(caption)的自定义内容样式。 */ .ck-content .image > figcaption { z-index: 1; position: absolute; bottom: 20px; left: -20px; font-style: italic; border-radius: 41px; background-color: #ffffffe8; color: #1138b0; padding: 5px 12px; font-size: 13px; box-shadow: 0 0 18px #1a1a1a26 }除了编辑器自带的默认内容样式(packages/ckeditor5-image/theme/index-content.css 中定义了image-style-align-left、image-style-align-right、image-style-side、image-style-block-align-left、image-style-block-align-right等类的浮动与间距规则)之外,集成方需要在自己的目标页面上复制一份类似的 CSS,才能保证最终输出内容中的图片样式生效。
自定义样式选项的属性
无论是对默认样式做部分修改,还是定义全新的样式,都要遵循ImageStyleOptionDefinition结构(见 imageconfig.ts):
name(必填):样式唯一名称。它用于引用默认样式或定义自定义样式、作为imageStyle属性存储在模型中的图片元素上、作为imageStyle命令的值,以及注册按钮(imageStyle:{name});icon(必填):按钮使用的 SVG 图标(XML 字符串),或DEFAULT_ICONS中的某个键('full'、'left'、'right'、'center'、'inlineLeft'、'inlineRight'、'inline',见 imagestyle/utils.ts)。未定义时继承对应默认样式的值;title(必填):样式的标题(tooltip 文案)。设置为ImageStyleUI#localizedDefaultStylesTitles中的某个标题会自动翻译为编辑器语言。未定义时继承默认值;className(可选):样式在视图中的 CSS 类名,仅用于非默认样式。未定义时继承默认值;modelElements(必填):该样式支持的模型元素名称列表,可选[ 'imageBlock' ]、[ 'imageInline' ]或[ 'imageBlock', 'imageInline' ]。它决定了样式可作用于哪种图片类型;如果当前选中图片的模型元素不在列表中,执行imageStyle命令时会自动改变图片类型。未定义时继承默认值;isDefault(可选):设为true时,该样式将成为modelElements所列模型元素的默认样式。默认样式不会向视图元素应用任何 CSS 类,执行时会移除imageStyle属性。未定义时继承默认值。
默认样式中的'inline'和'block'都带有isDefault: true标记(见 imagestyle/utils.ts 与 imagestyle/utils.ts),这也解释了为什么它们是"清除所有类"的默认样式。
内置样式一览
ImageStyle插件根据已加载插件提供一组默认样式。下表完整呈现了这些样式的可用性以及应用后产生的图片行为:
| 样式名称 | 必需插件 | 转换结果 | 应用的类 | 类型 |
|---|---|---|---|---|
"block" | ImageBlock | block | 移除所有类(默认样式) | 语义化 |
"inline" | ImageInline | inline | 移除所有类(默认样式) | 语义化 |
"side" | ImageBlock | block | image-style-side | 语义化 |
"alignLeft" | 任意 | - | image-style-align-left | 表现型 |
"alignRight" | 任意 | - | image-style-align-right | 表现型 |
"alignBlockLeft" | ImageBlock | block | image-style-align-block-left | 表现型 |
"alignBlockRight" | ImageBlock | block | image-style-align-block-right | 表现型 |
"alignCenter" | ImageBlock | block | image-style-align-center | 表现型 |
表中"转换结果"列指的是应用该样式后图片在 HTML 中的表示类型:"block" 表示转换为<figure>块级表示,"inline" 表示转换为行内表示,"-" 表示保持原图片类型不变。
此外,当行内与块级编辑插件都加载时,插件还提供了两个预定义下拉菜单imageStyle:wrapText(包含alignLeft、alignRight)与imageStyle:breakText(包含alignBlockLeft、block、alignBlockRight),见 imagestyle/utils.ts。
安装与启用
ImageStyle是@ckeditor/ckeditor5-image包中的官方插件。启用步骤与图片功能整体的安装方式一致,具体可参考图片功能安装指南。简单来说,只要你的编辑器配置中加载了ImageBlock/ImageInline(通常通过Image插件一并引入)与ImageStyle插件,样式功能即默认启用。上文提到的编辑器默认配置示例(经典、行内、气泡编辑器使用语义化样式按钮,文档编辑器使用表现型样式按钮)正是基于这些插件的默认加载情况。
公共 API
{@link module:image/imagestyle~ImageStyleImageStyle} 插件(imagestyle.ts)注册以下 API:
- 每个已定义样式的按钮,例如
'imageStyle:block'、'imageStyle:side',可在图片工具栏中使用(参见图片功能概览中的上下文工具栏部分); 'imageStyle'命令(imagestylecommand.ts),接受基于image.styles配置的值(例如'block'、'side'):
editor.execute( 'imageStyle', { value: 'side' } );命令执行时的底层行为(见 imagestylecommand.ts)概括如下:
- 若目标样式要求图片类型转换而当前模式(schema)不允许,命令会直接跳过执行,避免图片停留在其当前类型不支持的样式上;
- 若目标样式要求的图片类型与当前不同,先执行
imageTypeInline或imageTypeBlock命令完成类型转换; - 若目标样式是默认样式(
isDefault: true)或未指定样式,则移除模型中的imageStyle属性;否则设置imageStyle属性为目标样式名; - 默认情况下还会调用
setImageNaturalSizeAttributes()为图片设置自然的width/height属性(可通过setImageSizes: false关闭)。
从模型到视图的转换由 imagestyle/converters.ts 中的模型到视图属性转换器完成:把imageStyle属性值映射为对应样式的className,并负责移除旧类、添加新类;反向转换(视图到模型)则从 HTML 类名还原出imageStyle属性,并额外处理了floatCSS 样式到imageStyle属性的归一化(normalizeFloatToDefinitionStyle)。
小结
图片样式特性把"图片外观管理"抽象为"样式名 ↔ CSS 类 ↔ 图片类型"三层映射:样式定义(ImageStyleOptionDefinition)承载名称、图标、标题、类名与支持的图片类型;imageStyle命令与模型属性负责状态流转;模型-视图转换器负责类名的读写;最终由集成方编写的内容 CSS 呈现视觉效果。掌握这套机制后,你可以从默认的 8 种样式出发,逐步构建出完全贴合业务需求的语义化或表现型图片样式体系。若需调试样式命令与编辑器内部状态,建议使用官方的 CKEditor 5 inspector 开发调试工具。
【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考