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

CSS实现点击按钮仅内部宽度变化 外层宽度与阴影异常问题

按钮按下交互阴影异常修复

问题说明

  • 预期效果:用户按下按钮时,仅按钮内部容器宽度发生变化,外层整体容器(黑色背景区域)宽度保持固定
  • 现存问题:点击按钮时,按钮阴影出现不符合预期的异常变动
    预期按钮变化效果

原有实现代码

HTML 部分

<button class="btn btn__primary" type="button">
    Continue
    <i class="fa-solid fa-sparkles m-l-8px"></i>
</button>

SCSS 部分

.btn {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    padding: 12px;
    font-family: $aeonik_bold;
    font-size: 15px;
    line-height: 100%;
    letter-spacing: 0.55px;
    border: 1.5px solid $button_border_color;
    box-sizing: border-box;
    border-radius: 4px;
    box-shadow: -1px 1px 0px 1.5px $button_border_color;
    text-decoration: none;
    transition: all 0.3s;
    animation-timing-function: ease-in-out;
    animation-duration: 150ms;
    cursor: pointer;
    width: 100%;

    &:active {
        box-shadow: none;
        background-color: #5a44ff;
        animation-timing-function: ease-in-out;
        animation-duration: 150ms;
    }
    &:focus {
        box-shadow: none;
        background-color: #5a44ff;
        animation-timing-function: ease-in-out;
        animation-duration: 150ms;
    }
    &:disabled {
        background: #d9dbe9;
        border: 1.5px solid #d9dbe9;
        box-sizing: border-box;
        border-radius: 4px;
        cursor: default;
    }

    &__primary {
        background-color: $purple_resting;
        color: white;
        animation-timing-function: ease-in-out;
        animation-duration: 150ms;

        &:not(:disabled) {
            &:hover {
                background-color: #6955ff;
                border: 1.5px solid #170f49;
                box-sizing: border-box;
                border-radius: 4px;
                box-shadow: -0.5px 0.5px 0px 1px $button_border_color;
                animation-timing-function: ease-in-out;
                animation-duration: 150ms;
            }
        }
    }
}

问题原因

  • 代码中使用了transition: all 0.3s,会给所有可动画属性加上过渡效果,阴影属性也被包含在内
  • hover、active、focus状态下反复修改box-shadow、border的参数,甚至直接将阴影设为none,不同状态下阴影的偏移量、扩展半径参数不统一,最终导致阴影出现跳变动效
  • 直接修改按钮本身的阴影、边框属性,会改变按钮的视觉占位,和“外层容器固定不动”的需求冲突

修复方案

核心修改逻辑:外层按钮的阴影、边框、整体尺寸全程固定,仅调整内部视觉属性实现按下效果,过渡效果只绑定需要变化的属性。
修正后的SCSS核心代码:

.btn {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    padding: 12px;
    font-family: $aeonik_bold;
    font-size: 15px;
    line-height: 100%;
    letter-spacing: 0.55px;
    // 边框、阴影固定,所有交互状态下不修改
    border: 1.5px solid $button_border_color;
    box-sizing: border-box;
    border-radius: 4px;
    box-shadow: -1px 1px 0px 1.5px $button_border_color;
    text-decoration: none;
    // 替换原有的transition: all,只过渡需要变化的属性,排除阴影、边框
    transition: background-color 0.15s ease-in-out, padding 0.15s ease-in-out;
    cursor: pointer;
    width: 100%;

    &:active {
        // 删除原有的box-shadow: none,保持阴影不变
        background-color: #5a44ff;
        // 微调上下内边距模拟按下位移效果,不改变外层整体尺寸
        padding: 13px 12px 11px 12px;
    }
    &:focus {
        // 删除原有的box-shadow: none,保持阴影不变
        background-color: #5a44ff;
        padding: 13px 12px 11px 12px;
    }
    &:disabled {
        background: #d9dbe9;
        border: 1.5px solid #d9dbe9;
        box-shadow: none;
        box-sizing: border-box;
        border-radius: 4px;
        cursor: default;
    }

    &__primary {
        background-color: $purple_resting;
        color: white;

        &:not(:disabled) {
            &:hover {
                background-color: #6955ff;
                // 删除hover状态下修改border、box-shadow的代码,保持外层样式固定
            }
        }
    }
}

修复后效果:

  • 外层按钮的阴影、边框、整体宽度完全固定,不会出现阴影异常跳动的问题
  • 按下时仅通过内边距微调实现内部视觉位移,符合“内部动、外层不动”的需求
  • 仅对必要属性做过渡,动效更流畅,性能更好

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:36:28