IE11中mat-button-toggle点击后高度异常变化问题咨询
这个问题我之前在做Angular Material项目兼容IE11时碰到过,算是IE11字体渲染和盒模型计算的老bug了,咱们来拆解下原因和解决办法:
问题根源
IE11对CSS字体属性的处理有个奇葩的 quirks:当mat-button-toggle触发状态变化(比如点击后添加checked类)时,IE11会错误地重新计算内部辅助元素(.mat-button-toggle-focus-overlay和.mat-button-toggle-ripple)的高度。具体来说:
- 初始渲染时,这些元素的高度是基于按钮默认字体计算的48px;
- 点击后触发状态变更,IE11重新解析字体相关属性,把这两个元素的高度算成了52px,直接撑大了父容器
mat-button-toggle; - 你提到的禁用再启用
font-family能恢复,其实是强制触发了一次正确的重绘,让IE11重新计算了正确的高度。
另外,垂直布局的mat-button-toggle-group会把这个bug放大,因为垂直方向的尺寸变化比水平方向更容易被用户察觉到。
可行解决方案
这里有几个经过项目验证的办法,按推荐优先级排序:
1. 强制固定内部元素高度(最直接)
直接给那两个出问题的内部元素设置固定高度,覆盖IE11的错误计算值。为了不影响其他浏览器,建议用IE专属的媒体查询:
/* 只针对IE11生效的样式 */ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { .mat-button-toggle .mat-button-toggle-focus-overlay, .mat-button-toggle .mat-button-toggle-ripple { height: 48px !important; } }
这个办法从根源上阻止了IE11乱改高度,几乎不会有副作用。
2. 预触发正确的字体重绘
通过给mat-button-toggle设置一个不影响视觉的字体样式,让IE11在初始渲染时就计算正确的高度:
.mat-button-toggle { /* 用inherit强制IE11正确解析字体继承,避免后续重绘出错 */ font-family: inherit !important; }
如果CSS方式不行,也可以用JS在组件初始化时强制触发重绘:
import { AfterViewInit, ElementRef, ViewChild } from '@angular/core'; // 组件类中 @ViewChild('toggleGroup') toggleGroup: ElementRef; ngAfterViewInit() { // 只在IE11中执行 if (document.documentMode === 11) { const toggles = this.toggleGroup.nativeElement.querySelectorAll('.mat-button-toggle'); toggles.forEach((el: HTMLElement) => { // 强制触发重绘的小技巧 el.style.display = 'none'; void el.offsetHeight; // 触发重绘 el.style.display = ''; }); } }
记得在模板里给mat-button-toggle-group加上模板引用变量:<mat-button-toggle-group #toggleGroup ...>
3. 替换为IE友好的替代布局(备选)
如果上面的办法都不生效,可以考虑把垂直的mat-button-toggle-group换成用Flex布局垂直排列的mat-button-group,不过这个方案只适合不需要mat-button-toggle-group单选互斥功能的场景,需要调整组件结构。
内容的提问来源于stack exchange,提问作者testing

