The popups can have their -Z offset by some multiplier of the number of popups currently shown. Make sure that you have a full-screen sized collider under your popup (for each popup) that does nothing. Mentally, you're layering up the layers of a cake, with each popup getting closer to the camera, and the frosting layer being a full-screen collider that intercepts interactions and prevents lower-level layers for receiving any events.
[EDIT: just noticed you said you don't want to use the full-screen collider]
In this case you'll want all popups to have the same class script. Part of that class would be a private static reference that indicates which dialog is top-most and receives interaction. Part of the process of instancing a new popup would be setting that variable. You'd likely need a simple stack or queue, really, so that as topmost dialogs are dismissed you could find the reference to the next one down in the stack. Simply make sure that your OnClick (and other interactions) check if "this" dialog is the top-most, and return without action if it is not.
I wrote a class specifically for the "is part of a dialog" logical case, which each logical window (parent gameobject) I call a "StoreChildrenRecursively" function that adds the parent and all children to a HashTable using the object transform's InstanceID as the key, and the window's root gameobject transform InstanceID as the value for all of them. Then I can do a hashtable lookup of something like IsChildOfWindow(windowGameObject, targetGameObject) and do a simple hashtable lookup to determine if it is. That way you can track interaction at the "window" (or panel) level and not have to independently track every sub-widget. I use this on pop-up menus that will auto-close if the mouse leaves the window area.
Anyhow, I'm getting a bit far afield from your original question. The behavior you want is fairly easy to code, as long as all dialogs share a common script class that helps track state and provides a means to get back a boolean of whether or not the clicked/touched item is a child of the topmost popup.