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

如何实现元素悬停时显示内容并替换为Lucide图标

实现GitHub风格标题悬停显示图标效果

问题

当前使用rehype-autolink-headings的wrap模式为标题添加锚点,通过CSS的::after伪元素显示#符号,但该符号始终可见。需要实现仅在标题悬停时显示图标,并将#替换为lucide-react的图标。

解决方案

方法1:纯CSS实现(无需修改React组件)

直接通过CSS伪元素和悬停状态控制图标显示,使用Lucide图标的SVG Data URI作为内容:

/* 锚点容器样式,确保图标对齐 */
.section_heading {
  position: relative;
  display: inline-flex;
  align-items: center;
}

/* 默认隐藏图标 */
.section_heading::after {
  content: "";
  /* Lucide Hash图标SVG Data URI,可替换为其他图标 */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='4' y1='9' x2='20' y2='9'%3E%3C/line%3E%3Cline x1='4' y1='15' x2='20' y2='15'%3E%3C/line%3E%3Cline x1='10' y1='3' x2='8' y2='21'%3E%3C/line%3E%3Cline x1='16' y1='3' x2='14' y2='21'%3E%3C/line%3E%3C/svg%3E");
  width: 16px;
  height: 16px;
  margin-left: 8px;
  opacity: 0;
  transition: opacity 0.2s ease;
}

/* 悬停时显示图标 */
.section_heading:hover::after {
  opacity: 1;
}

方法2:自定义MDX组件实现(支持React特性)

通过自定义MDX标题组件插入Lucide图标,用Tailwind的group类控制悬停显示,适合需要动态调整图标的场景:

  1. 导入Lucide图标
import { Hash } from 'lucide-react';
  1. 自定义标题组件
const components = useMDXComponents({
  h1: (props) => (
    <h1 {...props} className="group">
      {props.children}
      <Hash className="ml-2 opacity-0 group-hover:opacity-100 transition-opacity" size={16} />
    </h1>
  ),
  h2: (props) => (
    <h2 {...props} className="group">
      {props.children}
      <Hash className="ml-2 opacity-0 group-hover:opacity-100 transition-opacity" size={16} />
    </h2>
  ),
  h3: (props) => (
    <h3 {...props} className="group">
      {props.children}
      <Hash className="ml-2 opacity-0 group-hover:opacity-100 transition-opacity" size={14} />
    </h3>
  ),
  // 按需添加h4、h5、h6组件
});

完整代码示例

import remarkGfm from 'remark-gfm';
import rehypeSlug from 'rehype-slug';
import rehypeAutolinkHeadings from "rehype-autolink-headings";
import { Hash } from 'lucide-react';

type Params = {
  params: {
    slug: string;
  };
};

export default async function PostPage({ params }: Params) {
  const source = await getPostBySlug(params.slug);
  
  // 自定义MDX标题组件,添加悬停图标
  const components = useMDXComponents({
    h1: (props) => (
      <h1 {...props} className="group">
        {props.children}
        <Hash className="ml-2 opacity-0 group-hover:opacity-100 transition-opacity" size={16} />
      </h1>
    ),
    h2: (props) => (
      <h2 {...props} className="group">
        {props.children}
        <Hash className="ml-2 opacity-0 group-hover:opacity-100 transition-opacity" size={16} />
      </h2>
    ),
    h3: (props) => (
      <h3 {...props} className="group">
        {props.children}
        <Hash className="ml-2 opacity-0 group-hover:opacity-100 transition-opacity" size={14} />
      </h3>
    ),
  });

  const { content, frontmatter } = await compileMDX<{ title: string, subtitle: string, part: string }>({
    source: source,
    components: components,
    options: {
      parseFrontmatter: true,
      mdxOptions: {
        remarkPlugins: [remarkGfm],
        rehypePlugins: [
          rehypeSlug,
          [rehypeAutolinkHeadings, {
            behaviour: "wrap",
            properties: {
              className: ['section_heading'],
            },
          }]
        ]
      }
    },
  });

  return (
    <article className="px-4 sm:px-6 md:px-8">
      <div className="relative max-w-3xl mx-auto">
        <div className="prose prose-lg prose-p:mb-2 text-justify dark:prose-invert max-w-3xl">
          <div className="prose-strong:text-gray-900 dark:prose-em:text-slate-400 dark:prose-strong:text-slate-400 prose-em:text-gray-900">
            {content}
          </div>
        </div>
      </div>
    </article>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 23:12:33