You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Strapi CKEditor插件搭配Next.js时图片缩放功能不生效问题

问题根因

这个现象不是配置遗漏,是CKEditor图片缩放功能的默认行为和浏览器响应式图片渲染逻辑冲突导致的:

  • CKEditor在执行缩放操作时,仅给外层<figure>标签写入了对应缩放比例的内联宽度和image image_resized类名
  • 内层<img>标签默认生成的sizes="100vw"属性会告知浏览器:这张图始终占满100%视口宽度,浏览器会按这个规则选图、渲染,自然会溢出固定宽度的父级<figure>容器

解决方案

你可以从Strapi侧源头修正或者前端侧兼容处理两个方向解决,优先选第一个方案,历史存量内容用第二个方案兼容即可。

方案1:Strapi侧CKEditor配置修正(推荐)

  1. 打开Strapi项目中CKEditor的配置入口,通常为src/admin/app.js中的自定义editor配置段,或者CKEditor插件的可视化配置页
  2. 新增图片元素的属性同步逻辑,在图片插入、缩放时自动把img标签的sizes属性同步为父figure的宽度值,参考配置:
// src/admin/app.js 内的CKEditor配置示例
export default {
  ckeditor: {
    config: {
      image: {
        // 保留你原有的缩放尺寸、工具栏配置
        resizeUnit: '%',
        resizeOptions: [
          { name: 'resizeImage:original', value: null, label: '原始尺寸' },
          { name: 'resizeImage:25', value: '25', label: '25%宽度' },
          { name: 'resizeImage:50', value: '50', label: '50%宽度' },
          { name: 'resizeImage:75', value: '75', label: '75%宽度' },
        ],
        toolbar: ['resizeImage']
      },
      // 新增元素插入/更新时的属性处理
      on: {
        change: (evt) => {
          const editor = evt.source;
          editor.model.document.on('change:data', () => {
            const figures = editor.editing.view.document.getRoot().getChildren();
            for (const figure of figures) {
              if (figure.is('element', 'figure') && figure.hasClass('image_resized')) {
                const figureWidth = figure.getStyle('width');
                const img = figure.getChild(0);
                if (img?.is('element', 'img') && figureWidth) {
                  img.setAttribute('sizes', figureWidth);
                }
              }
            }
          })
        }
      }
    }
  }
}
  1. 重启Strapi服务、重建admin面板后,新生成的缩放图片会自动写入匹配的sizes属性,不会再出现溢出问题。

如果你使用的是版本号低于4.0的@ckeditor/strapi-plugin-ckeditor插件,直接升级到最新稳定版即可原生修复这个sizes不同步的已知问题,不需要额外写自定义逻辑。


方案2:Next.js前端侧兼容处理

适合不想调整Strapi配置、需要兼容历史已生成富文本内容的场景,根据你的渲染方式选对应处理即可:

  • 如果你用dangerouslySetInnerHTML直接渲染富文本HTML,直接在全局CSS中加入以下样式即可修复,不需要修改HTML解析逻辑:
/* 富文本容器样式 */
.rich-content figure.image.image_resized {
  display: inline-block;
  width: fit-content;
  margin: 1rem 0;
}
.rich-content figure.image.image_resized img {
  max-width: 100%;
  width: 100%;
  height: auto;
  object-fit: contain;
}
  • 如果你用html-react-parser/react-html-parser类库把富文本解析为React节点渲染,可以在解析规则中直接修正img标签的sizes属性,示例:
import parse from 'html-react-parser';
import Image from 'next/image';

export default function RichContent({ html }) {
  const parseOptions = {
    replace: (domNode) => {
      // 匹配缩放后的figure标签
      if (
        domNode.type === 'tag' &&
        domNode.name === 'figure' &&
        domNode.attribs.class?.includes('image_resized')
      ) {
        // 提取figure的宽度值
        const widthMatch = domNode.attribs.style?.match(/width:\s*(\d+)px/);
        const resizedWidth = widthMatch ? Number(widthMatch[1]) : undefined;
        // 找到内部的img节点
        const imgNode = domNode.children?.find(child => child.name === 'img');
        if (imgNode && resizedWidth) {
          // 覆写sizes属性
          imgNode.attribs.sizes = `(max-width: ${resizedWidth}px) 100vw, ${resizedWidth}px`;
          // 如果你要替换为next/image组件,可以在这里返回自定义节点
        }
      }
    }
  }

  return <div className="rich-content">{parse(html, parseOptions)}</div>
}

内容的提问来源于stack exchange,提问作者altho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:18:34