How can I set modals height to be equal to its content

Hello guys,

I have a modal which should have height based on its content, since content could differ from modal to modal. Modal is shown from bottom of the page and is not full screen.

How can I achieve modal behaviour where modals height is equal to its content. Currently whenever modal is opened I calculate height of modals content and then set modals height to it, but this is very bad IMO since it does this on every modal open. If i set height to something like auto or content-fit it is not shown. There must be easier way to do this.

Hi
if CSS can deliver what you need, you can target the modal via the below sample code:

.my-custom-modal-css .modal-wrapper {
   height: 20%;
   top: 80%;
   position: absolute; 
   display: block;  
}

Regards,

Tom

Thanks for reply, but you set height to fixed 20%, i need it to change as content inside modal change. But what might help is that i was targeting modal class and not modal wrappet, i will try my css on modal wrapper and let you know how it went.

Correct. That is why I said “if css can do it”. The code sample is to show the css selector you need to target the right element in the DOM. This is generally the issue with modal.

if there is CSS code that can do what you want, put it in your scss (global.scss?) to target the element as shown earlier. And make sure the modal is opened with the designated class attached to it - using the properties needed to open a modal.

So:

.my-custom-modal-css .modal-wrapper {
  .... HERE YOUR MAGICAL CSS 
}
1 Like

Ahh sorry. I tried it with targeting .modal-wrapper. No success, when setting its height to auto modal just disappears. I do not know any other way to do this.

Edit: I found dozens of answers online but none of them seem to work ,at least for Ionic 5.

Is there even a solution for this? Team?

I am on Ionic 5 and have the following Vue component named PopupMessage for all my auto-sized modals. I adapted the code from here.

By default, it has an auto height but I can pass in an override height/width as well.

CSS

ion-modal.auto-height {
    --height: auto;
}
ion-modal.auto-height .ion-page {
    position: relative;
    display: block;
    contain: content;
}
ion-modal.auto-height .ion-page .inner-content {
    max-height: 80vh;
    overflow: auto;
}

Vue Component

<template>
    <IonModal
        :css-class="[cssClass, 'auto-height']"
        :is-open="isOpen"
        @will-present="initialize"
        @did-present="$emit('onDidPresent')"
        @did-dismiss="$emit('onDidDismiss')"
    >
        <div class="inner-content">
            <div class="p-4">
                <slot />
            </div>
        </div>
    </IonModal>
</template>

<style>
.popup-message-modal {
    --border-radius: theme('borderRadius.lg');
}
</style>

<script lang="ts">
import { defineComponent } from 'vue'
import { IonModal } from '@ionic/vue'
export default defineComponent({
    name: 'PopupMessage',
    components: {
        IonModal,
    },
    emits: {
        onDidPresent: null,
        onDidDismiss: null,
    },
    props: {
        cssClass: {
            type: String,
            required: false,
            default: 'popup-message-modal',
        },
        isOpen: {
            type: Boolean,
            required: true,
        },
        height: {
            type: String,
            required: false,
            default: '',
        },
        width: {
            type: String,
            required: false,
            default: '95%',
        },
    },
    setup(props) {
        const initialize = (): void => {
            const modalRef = document.querySelector(`ion-modal.${props.cssClass}`) as HTMLElement

            if (props.height) {
                modalRef.style.setProperty('--height', props.height)
            }

            if (props.width) {
                modalRef.style.setProperty('--width', props.width)
            }
        }

        return {
            initialize,
        }
    },
})
</script>

Usage

<PopupMessage :is-open="isOpen" @on-did-dismiss="dismissPopup">
    <div>Some inner content here</div>
</PopupMessage>
2 Likes

If @twestrick 's great code suggestion does not work, maybe use the inspector to inspect the class of the modal elements. But I think the CSS selectors he is showing are way better than mine :slight_smile:

It works perfectly when I have one modal.

I have created component like yours(PopupMessage) called Modal.

This is the structure(simplified)

<Modal>
everything as you put in your PopupMessage
<slot>
</Modal>

Then in a page i call this and send content of modal as a slot. This content has another component inside it but it is not rendered as the 1st one, 1st one is rendered as and the 2nd one is just , like it doesnt recognize it is an modal. Dont know why.

Edit: Maybe this image can explain it better

Edit2: i just edited your css to target .auto-height and not ion-modal.auto-height and it works now.

Thank you so much, I initially saw the code you used as reference but i didnt know what to do with it.
To be honest I actually do not know how this works.

Thanks a lot for replies , appreciated! @twestrick @Tommertom

2 Likes