I am working on a Vue application where I use a dialog (el-dialog from Element Plus) to display a form. The form has two main sections:
Scrollable content at the top (UnitConversion and other fields). A bottom section (StockImageUpload, StockPricing, and StockDescription) that must always stay fixed at the bottom of the dialog.
I used position: absolute to keep the bottom section fixed at the bottom of the dialog. However, when the dialog size shrinks (e.g., due to a smaller screen or window resize), the bottom section overlaps with the scrollable content, hiding buttons and other fields.
Here is a simplified version of my components:
BaseDialog.vue component
<template>
<el-dialog
v-model="dialogVisible"
:append-to-body="true"
>
<slot name="toolbar"></slot>
<slot></slot>
</el-dialog>
</template>
<style lang="scss">
.base-dialog {
max-width: none;
max-height: none;
margin: 20px !important;
display: flex;
flex-direction: column;
height: calc(100vh - 40px);
overflow: hidden;
:deep(.el-dialog__header) {
background: $primary-color;
margin: 0;
padding: $spacing-unit * 2;
.el-dialog__title {
color: white;
font-weight: bold;
}
}
:deep(.el-dialog__body) {
display: flex;
flex-direction: column;
padding: $spacing-unit * 3;
overflow: hidden;
height: 100%;
flex: 1;
}
}
</style>
StockForm.vue component
<template>
<el-form class="stock-form">
<div class="unit-conversion-section">
<UnitConversion :stock="form" />
</div>
<div class="bottom-section">
<div class="image-section">
<StockImageUpload />
</div>
<div class="pricing-section">
<StockPricing />
</div>
<div class="description-section">
<StockDescription />
</div>
</div>
<style scoped>
.stock-form {
margin-bottom: $spacing-unit * 3;
.unit-conversion-section {
margin-bottom: 80px;
}
.bottom-section {
position: absolute;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
gap: 20px;
}
}
</style>
UnitConversion.vue component
<template>
<div class="unit-conversion">
<!-- Conversion for Secondary -->
<div class="conversion-row">
<div class="conversion-section">
<el-button
class="var-ise-button"
type="danger"
@click="toggleSection('secondary')"
>
{{ t("stock.buttons.existSecond") }}
</el-button>
<div class="conversion-fields" v-show="showSections.secondary">
<el-form-item :label="t('stock.labels.unit')">
<el-select v-model="stock.secondaryUnit" class="w-100">
<el-option label="PAKET" value="PAKET" />
<el-option label="ADET" value="ADET" />
<el-option label="GALON" value="GALON" />
</el-select>
</el-form-item>
...
<style lang="scss" scoped>
.unit-conversion {
margin-top: 36px;
gap: $spacing-unit;
.conversion-row {
display: flex;
gap: $spacing-unit;
flex-direction: column;
}
.conversion-section {
display: flex;
align-items: center;
gap: 15px;
height: 60px;
.var-ise-button {
max-width: 250px;
min-width: 150px;
min-height: 42px;
align-items: center;
justify-content: center;
flex-basis: 30%;
padding: 0 20px;
}
}
.el-button {
height: 40px;
}
.conversion-fields {
display: flex;
gap: $spacing-unit * 3;
flex: 1;
.el-form-item {
flex: 1;
white-space: nowrap;
:deep(.el-form-item__label) {
font-size: 12px;
}
}
}
.w-100 {
width: 80%;
}
}
</style>
How can I ensure that the bottom section remains fixed at the bottom while the top section scrolls properly without being overlapped? Is there a way to dynamically adjust the layout or make the dialog scrollable in a way that accommodates both sections?
Any suggestions or guidance on CSS or JavaScript-based solutions would be appreciated