Skip to content

Change in behavior with @tailwindcss/postcss@4.1.4 #18626

@benddailey

Description

@benddailey

What version of Tailwind CSS are you using?

v4.1.4

What build tool (or framework if it abstracts the build tool) are you using?

postcs: 8.5.3, vite: 6.2, vue: 3.5.13

What version of Node.js are you using?

v20.19.3

What browser are you using?

Chrome

What operating system are you using?

Debian 12

Reproduction URL
Modal.vue

<script setup>
import { computed, onMounted, onUnmounted, ref, watch } from "vue"

const props = defineProps({
	show: {
		type: Boolean,
		default: false,
	},
	maxWidth: {
		type: String,
		default: "2xl",
	},
	closeable: {
		type: Boolean,
		default: true,
	},
})

const emit = defineEmits(["close"])
const dialog = ref()
const showSlot = ref(props.show)

watch(
	() => props.show,
	() => {
		if (props.show) {
			document.body.style.overflow = "hidden"
			showSlot.value = true
			dialog.value?.showModal()
		} else {
			document.body.style.overflow = null
			setTimeout(() => {
				dialog.value?.close()
				showSlot.value = false
			}, 200)
		}
	},
)

const close = () => {
	if (props.closeable) {
		emit("close")
	}
}

const closeOnEscape = (e) => {
	if (e.key === "Escape" && props.show) {
		close()
	}
}

onMounted(() => document.addEventListener("keydown", closeOnEscape))

onUnmounted(() => {
	document.removeEventListener("keydown", closeOnEscape)
	document.body.style.overflow = null
})

const maxWidthClass = computed(() => {
	return {
		sm: "sm:max-w-sm",
		md: "sm:max-w-md",
		lg: "sm:max-w-lg",
		xl: "sm:max-w-xl",
		"2xl": "sm:max-w-2xl",
	}[props.max_width]
})
</script>

<template>
	<dialog
		class="z-50 m-0 min-h-full min-w-full overflow-y-auto bg-transparent backdrop:bg-transparent"
		ref="dialog"
	>
		<div
			class="fixed inset-0 overflow-y-auto px-4 py-6 sm:px-0 z-50"
			scroll-region
		>
			<transition
				enter-active-class="ease-out duration-300"
				enter-from-class="opacity-0"
				enter-to-class="opacity-100"
				leave-active-class="ease-in duration-200"
				leave-from-class="opacity-100"
				leave-to-class="opacity-0"
			>
				<div
					v-show="show"
					class="fixed inset-0 transform transition-all"
					@click="close"
				>
					<div class="absolute inset-0 bg-gray-500 opacity-75" />
				</div>
			</transition>

			<transition
				enter-active-class="ease-out duration-300"
				enter-from-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
				enter-to-class="opacity-100 translate-y-0 sm:scale-100"
				leave-active-class="ease-in duration-200"
				leave-from-class="opacity-100 translate-y-0 sm:scale-100"
				leave-to-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
			>
				<div
					v-show="show"
					class="mb-6 bg-white rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full sm:mx-auto"
					:class="maxWidthClass"
				>
					<slot v-if="showSlot" />
				</div>
			</transition>
		</div>
	</dialog>
</template>

Describe your issue
After upgrading tailwind past version 4.1.3 our modals began rendering behind the backdrop as seen in the screenshots. I have worked this down to being an issue with tailwindcss/postcss as I can reproduce the issue with leaving all other dependencies as in and just running "npm install @tailwindcss/postcss@4.1.4". After stop and starting my vite process after the upgrade the problem appears.

Modal 4.1.3 =
Image

Modal 4.1.4 =
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions