diff --git a/packages/vuetify/src/components/VFab/VFab.tsx b/packages/vuetify/src/components/VFab/VFab.tsx index f26707bf3de..3398a5604c6 100644 --- a/packages/vuetify/src/components/VFab/VFab.tsx +++ b/packages/vuetify/src/components/VFab/VFab.tsx @@ -54,7 +54,7 @@ export const VFab = genericComponent()({ const el = shallowRef() useResizeObserver(el, entries => { if (!entries.length) return - height.value = entries[0].contentRect.height + height.value = entries[0].target.clientHeight }) const hasPosition = toRef(() => props.app || props.absolute) diff --git a/packages/vuetify/src/components/VFooter/VFooter.tsx b/packages/vuetify/src/components/VFooter/VFooter.tsx index ee728826c48..dfeb1cf5186 100644 --- a/packages/vuetify/src/components/VFooter/VFooter.tsx +++ b/packages/vuetify/src/components/VFooter/VFooter.tsx @@ -52,7 +52,7 @@ export const VFooter = genericComponent()({ const el = shallowRef() useResizeObserver(el, entries => { if (!entries.length) return - autoHeight.value = entries[0].contentRect.height + autoHeight.value = entries[0].target.clientHeight }) const height = computed(() => props.height === 'auto' ? autoHeight.value : parseInt(props.height, 10)) diff --git a/packages/vuetify/src/components/VFooter/__tests__/VFooter.spec.browser.tsx b/packages/vuetify/src/components/VFooter/__tests__/VFooter.spec.browser.tsx new file mode 100644 index 00000000000..a7f2d90419c --- /dev/null +++ b/packages/vuetify/src/components/VFooter/__tests__/VFooter.spec.browser.tsx @@ -0,0 +1,52 @@ +// Components +import { VFooter } from '..' +import { VLayout } from '@/components/VLayout' +import { VMain } from '@/components/VMain' + +// Utilities +import { commands, render, screen } from '@test' + +describe('VFooter', () => { + it('should reserve layout space equal to its rendered height', async () => { + render(() => ( + + Content + Footer + + )) + + const footer = screen.getByCSS('.v-footer') + const main = screen.getByCSS('.v-main') + + await commands.waitStable('.v-footer') + + // Default $footer-padding is 8px 16px, so the content box is 16px shorter + // than the box the footer actually occupies. The layout must reserve the + // latter or the last 16px of VMain content renders underneath the footer. + const rendered = footer.getBoundingClientRect().height + const reserved = parseFloat(getComputedStyle(main).paddingBottom) + + expect(rendered).toBeGreaterThan(0) + expect(reserved).toBe(rendered) + }) + + it('should reserve layout space including custom vertical padding', async () => { + render(() => ( + + Content + Footer + + )) + + const footer = screen.getByCSS('.v-footer') + const main = screen.getByCSS('.v-main') + + await commands.waitStable('.v-footer') + + const rendered = footer.getBoundingClientRect().height + const reserved = parseFloat(getComputedStyle(main).paddingBottom) + + expect(rendered).toBeGreaterThan(80) + expect(reserved).toBe(rendered) + }) +})