52

So I've been trying to adopt Materials Accordion in my Web Application development.

However having some troubles getting the header to expand in size as the content grows.

My header is expected to have quite a few number of lines to give a summary and not just a 1 liner.

If I hard-code the material header height it causes the animation to go hay-wire.

Below is a sample code

<mat-accordion [displayMode]="displayMode" [multi]="multi" class="mat-expansion-demo-width">
    <mat-expansion-panel #panel1 [hideToggle]="hideToggle">
        <mat-expansion-panel-header>Section 1</mat-expansion-panel-header>
        <p>This is the content text that makes sense here.</p>
    </mat-expansion-panel>
</mat-accordion>
::ng-deep .mat-expansion-panel-header
{
    height: 190px !important;
}

If I do the above the height gets set, but the animation for expand and collapse goes weird.

How should I go about this?

James Skemp
  • 8,018
  • 9
  • 64
  • 107
Alex Sim
  • 617
  • 1
  • 6
  • 13
  • 1
    @faisal or @alex-sim can either of you add an example of how multiple lines in the header would look like in the code? If I try to add multiple lines in the `mat-panel-title` or `mat-panel-description` elements they end up overlayed and I can't figure out how to add additional content in `mat-expansion-panel-header` that will actually appear under the first line. – somada141 Nov 03 '18 at 05:42

6 Answers6

124

You dont have to use ::ng-deep. You can use [collapsedHeight] and [expandedHeight] on your mat-expansion-panel-header.

<mat-accordion [displayMode]="displayMode" [multi]="multi" class="mat-expansion-demo-width">
    <mat-expansion-panel #panel1 [hideToggle]="hideToggle">
        <mat-expansion-panel-header [collapsedHeight]="'190px'" [expandedHeight]="'190px'">
            Section 1
        </mat-expansion-panel-header>
        <p>This is the content text that makes sense here.</p>
    </mat-expansion-panel>
</mat-accordion>

Link to StackBlitz Demo.

FAISAL
  • 33,618
  • 10
  • 97
  • 105
  • Hi! Thank you for the amazingly fast response! We just figured it out right as you posted your answer https://github.com/angular/material2/commit/11e2239a868c8070458bc9fe52f3afe8bdea61da I referred to this, but I got confused on the .ts portion as I'm not familiar with it. However, we have hardcorded the height as per what you have shown! – Alex Sim Apr 10 '18 at 06:58
  • 1
    @AlexSim see the demo to get an idea how to bind it to a variable. – FAISAL Apr 10 '18 at 07:01
  • 3
    Thx ! Works perfectly ! – Wenakari Feb 04 '19 at 12:22
  • Thanks great solution – core114 Mar 06 '19 at 08:42
  • 8
    If your rows of text vary per header, you can pass in the empty string and it will automatically collapse to the height of your text. Example: `[collapsedHeight]="''" [expandedHeight]="''"`. Then you can add padding to `mat-expansion-panel-header` as needed. This works for me in Material 5.2.4. – cs_pupil Mar 25 '19 at 21:37
  • 2
    Just to be nitpicky here, You don't actually have to surround these attributes with braces [] since you're not binding the property to a variable or expression. You could instead just do collapsedHeight="190px". Also, I like cs_pupil's solution as it offloads the height to the css (where it should be in my opinion) instead of the ts. – BAM5 Jun 15 '19 at 16:12
38

As of today with Material 7.0.2, If you want to have the header follow some generic height:auto rule, this fix height might not be your solution. (for instance to follow the size of the text in the header in responsive situations)

enter image description here

in these situations, it's much better to have an auto height defined in css:

  mat-expansion-panel {
    mat-expansion-panel-header {
      height: auto!important; 
    }
  }

and define

  <mat-expansion-panel-header collapsedHeight="*" expandedHeight="*">

as explained in https://github.com/angular/material2/pull/9313

ForestG
  • 17,538
  • 14
  • 52
  • 86
  • 3
    This should be the correct answer :) it gives flexibility for the lines to grow as much as needed. – John Mersal Mar 25 '19 at 14:44
  • This is excellent! Just remember for those upgrading from 7.0.0 to 7.0.2 for this fix (or from any other version) make sure dependent libraries are updated as well. I had to update @angular/cdk to 7.0.2. Otherwise, I was getting various "function is not defined" errors. – harmonickey Jul 28 '19 at 07:41
  • 4
    This is the most elegant way of creating a dynamic mat-expansion-panel-header, but from what I experienced, the `collapsedHeight="*" expandedHeight="*"` is not necessary. – Satria Jul 03 '20 at 10:35
  • 2
    Absolutely the preferred way to solve the problem. Also I can confirm that as of now ( Angular 11.0.5 and Angular Material 11.0.3) `collapsedHeight` `expandedHeight` and the `!important` attribute are not necessary at all. So, at the end. a `.mat-expansion-panel-header { height: auto;}` is sufficient. I would also add some `padding-bottom` and `padding-top` to make it cleaner. – Alessandro Prete Dec 22 '20 at 19:09
19

That's what workerd for me, no css simply adding thowe to mat-expansion-panel-header

<mat-expansion-panel-header [collapsedHeight]="'auto'" [expandedHeight]="'auto'">
Matis
  • 201
  • 2
  • 5
  • 3
    This is the correct answer though one should add padding top/bottom of 12px via CSS to keep the padding of the header, which was previously achieved by the fixed height. – Thomas Weber Apr 06 '20 at 14:30
8

Adding a general options/settings to set height for all panels across application:

MatExpansionPanelDefaultOptions

import { NgModule } from '@angular/core';
import { MAT_EXPANSION_PANEL_DEFAULT_OPTIONS } from '@angular/material';

@NgModule({
    providers: [
        {
            provide: MAT_EXPANSION_PANEL_DEFAULT_OPTIONS,
            useValue: {
                hideToggle: true,
                expandedHeight: '50px',
                collapsedHeight: '50px'
            }
        }
    ]
})
export class AppMaterialModule {}
Felix
  • 3,999
  • 3
  • 42
  • 66
1

For Material 15, adding the following to the component CSS mimics the default padding, with a height that allows the content to be completely visible:

.mat-expansion-panel-header {
  height: auto;
  padding: 12px 24px; /* replacing with 1em looks fine to me */
}
James Skemp
  • 8,018
  • 9
  • 64
  • 107
0

To have multiple lines in a panel header, I just used display: flex; flex-direction:column on the header and it worked just fine.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109