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

使用shadcn下拉菜单时按钮右移、Chrome滚动条消失的Tailwind解决方案

解决shadcn Dropdown Menu触发时按钮偏移与滚动条消失问题

原代码

import { signIn, signOut, useSession } from "next-auth/react";
import { buttonVariants } from "../ui/button";

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

export default function SignInButton() {
  const { data: session } = useSession();

  if (session && session.user) {
    return (
      <DropdownMenu>
        <DropdownMenuTrigger className="right-0 outline py-2 px-2 rounded-md">User</DropdownMenuTrigger>
        <DropdownMenuContent>
          <DropdownMenuLabel>My Account</DropdownMenuLabel>
          <DropdownMenuSeparator />
          <DropdownMenuItem>Subscription</DropdownMenuItem>
          <DropdownMenuItem onClick={() => signOut()}>LogOut</DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    );
  }

  return (
    <button className={buttonVariants({ variant: "outline" })} onClick={() => signIn()}>
      LogIn
    </button>
  );
}

问题描述

使用shadcn的Dropdown Menu组件时,点击触发按钮会出现两个问题:

  1. 触发按钮向右偏移
  2. Chrome浏览器的滚动条消失

解决方案(基于Tailwind CSS)

1. 修复按钮偏移问题

  • 移除冲突定位类:删除DropdownMenuTrigger上的right-0类,该绝对定位类会与Radix UI内部定位逻辑冲突导致偏移。若需按钮靠右,给按钮父容器添加flex justify-end类即可。
  • 替换默认outline样式:原outline类会在按钮获焦时产生边框偏移,改用Tailwind焦点样式类控制视觉效果:focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary,避免不必要的偏移。

2. 解决滚动条消失问题

shadcn的Dropdown基于Radix UI,默认打开时会锁定页面滚动(给body添加overflow:hidden),导致滚动条消失。可通过两种方式处理:

  • 关闭滚动锁定:给DropdownMenu组件添加modal={false}属性,彻底关闭滚动锁定,滚动条将保持显示。
  • 保留滚动锁定但避免页面偏移:若需保留滚动锁定,在全局样式中给body添加scrollbar-gutter-stable类,即使滚动条隐藏,页面布局也不会偏移。

修改后的代码示例

import { signIn, signOut, useSession } from "next-auth/react";
import { buttonVariants } from "../ui/button";

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

export default function SignInButton() {
  const { data: session } = useSession();

  if (session && session.user) {
    return (
      <div className="flex justify-end">
        <DropdownMenu modal={false}>
          <DropdownMenuTrigger className="py-2 px-2 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary">
            User
          </DropdownMenuTrigger>
          <DropdownMenuContent>
            <DropdownMenuLabel>My Account</DropdownMenuLabel>
            <DropdownMenuSeparator />
            <DropdownMenuItem>Subscription</DropdownMenuItem>
            <DropdownMenuItem onClick={() => signOut()}>LogOut</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>
    );
  }

  return (
    <button className={buttonVariants({ variant: "outline" })} onClick={() => signIn()}>
      LogIn
    </button>
  );
}

全局样式配置(可选,保留滚动锁定时使用)

在globals.css中添加:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  body {
    @apply scrollbar-gutter-stable;
  }
}

内容的提问来源于stack exchange,提问作者송상훈

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:50:13