垫子选择面板最小宽度

问题描述 投票:0回答:7

我正在尝试使用多个复选框自定义垫选择。 由于某种原因,面板的最小宽度错误如下:

我不知道它在哪里计算这个最小宽度。 我还尝试添加 panelClass 并覆盖此类的最小宽度, 例如:

<mat-select #multipleSelect (selectionChange)="selectItem($event.value)" panelClass="multiple-panel" multiple>      

&.multiple-panel {
   min-width: 200px !important;
}

但是当打开下拉菜单时,它会以原始宽度打开(如图所示),并在几毫秒后“跳转”到面板类上定义的自定义最小宽度。

我发现垫子选择很难设计。有人知道如何解决这个问题吗?

angular-material angular5 angular-material2 angular-material-6
7个回答
8
投票

您可以通过提供面板类(如您所提到的)来设计您的

mat-select
对话框的样式。
请按照此演示:https://stackblitz.com/edit/angular-matselect-style?file=src/styles.css
查看样式化的
mat-select
组件。

原因:

  • 延迟的原因是对话框的角度,在
    cdk-overlay-pane
    容器内创建一个
    cdk-overlay-container
    ,因此在
    mat-select
    的情况下,它提供了 180px 的最小宽度,该宽度被我们在略有延迟。
  • 是的,打开对话框并将其宽度自定义为面板类中提供的指定宽度有轻微的延迟。但在我正在进行的项目中,延迟是可以接受的。
    因此,您可以找到用于设计
    mat-select
    组件样式的演示,因为我提供了 2 个组件,您可以修改任何 css 属性。
  • 尝试使用
    ::ng-deep
    :host >>>
    来使用样式,如果没有找到任何运气,
    请将样式粘贴到
    style.css
    中。


更新1:
尝试过

css animations
opacity
来顺利打开
mat-select
选项。

.panel-class-applied-on-mat-select {
  animation-name: opacityDelay !important;
  animation-duration: 0.3s !important;
}

@keyframes opacityDelay {
   0%   {opacity: 0;}
  25%  {opacity: 0;}
  50%  {opacity: 0;}
  75%  {opacity: 0;}
  100% {opacity: 1;}
}

更新了 StackBlitz 演示


5
投票

我使用了另一种方法。 只是将这段代码添加到全局样式中。

.mat-select-panel {
// some your code
  &.ng-animating {
       visibility: hidden;
    }
  }

您可以尝试此解决方案 DEMO StackBlitz
不透明度的 hack 并没有修复选择关闭时的跳跃宽度。


3
投票

请对我宽容点S.O.这是我第一次贡献。 :)

调试控制台后,遇到这个问题。网上解决方案不太清楚。所以我在这里发布我的以防其他人遇到这个问题。

我发现infix类有一个永久设置的宽度。如果您取消设置它,并可以选择在值的右侧添加一些填充,您会发现这将解决问题。使用

:host
时添加
::ng-deep
进行封装。

重要注意事项:

::ng-deep
在 Angular v14 后将被永久弃用。
@Component()
注解中有一个名为
encapsulation
的属性,可以用来关闭组件的视图封装,而不是使用
::ng-deep

::ng-deep
弃用的解决方案:

@Component({
  selector: 'app-selector-name',
  template: `<div>Hello World!</div>`,
  encapsulation: ViewEncapsulation.None,
  styles: [
    `
      :host mat-form-field .mat-form-field-infix {
        width: unset;
      }
      :host mat-form-field .mat-select-value {
        padding-right: 0.5rem; /* 8px */ 
        /* Alternatively, for TailwindCSS: @apply pr-2 */
      }
      :host .random-class {
         /* some encapsulated styling... */
      }
      .another-random-class {
         /* some non-encapsulated styling... */
      }
    `
  ]
})

如果您不关心

::ng-deep
的弃用,则解决方案:

      :host ::ng-deep mat-form-field .mat-form-field-infix {
        width: unset;
      }
      :host ::ng-deep mat-form-field .mat-select-value {
        padding-right: 0.5rem; /* 8px */
      }

1
投票

您需要在组件装饰器中将 viewEncapsulation 更改为 none。然后添加以下 css 以删除过渡效果。查看 Angular 文档中的 viewEncapsulation https://angular.io/guide/component-styles#view -封装

@Component({
selector: 'app-selector',
templateUrl: './template.html',
styleUrls: ['./template.css'],
encapsulation: ViewEncapsulation.None
})
//CSS
.cdk-overlay-connected-position-bounding-box .cdk-overlay-pane .mat-select-panel.ng-animating {
display: none;
}

1
投票

我也面临同样的问题,现在找到了非常适合我的解决方案。尝试使用 ::ng-deep 设置面板的最小宽度,如下所示。

::ng-deep .mat-select-panel {
  min-width: calc(100% + 14px) !important;
}

这对我有用。


0
投票

尝试这种方式:在代码中为您的垫选择定义一个面板类,然后在全局/应用程序样式文件中添加:

.panel-class-name .mat-select-panel {
 // add your styling here
}

它对我来说很有用,为材质组件添加一些特定于组件的样式。


0
投票

来自 Angular GitHub 问题,JoeMellon 建议使用此解决方法

@ly000 同样的困境,所以我花了一些时间来实现这一点的最佳方法 - 我们可以利用 has 选择器,并且仅在其子级具有 mat-mdc-select-panel 类时才获取 cdk 窗格。

 .cdk-overlay-pane:has(.mat-mdc-select-panel) { min-width: fit-content; }

我尝试了一下,它完全符合我的要求:它使下拉菜单的大小与触发它的组件的大小相同,除非下拉菜单中的内容更宽,然后下拉菜单变得更宽以适应。

我做的唯一改变是指定

::ng-deep
,所以我的结果是:

// Make the minimum width of a dropdown fit the content with no wrapping
::ng-deep .cdk-overlay-pane:has(.mat-mdc-select-panel) {
    min-width: fit-content;
}

我正在使用 Angular Material 17。

© www.soinside.com 2019 - 2024. All rights reserved.