ui icon indicating copy to clipboard operation
ui copied to clipboard

[bug]: Layout Shift when Opening Select Component

Open alwalxed opened this issue 2 years ago • 78 comments

https://github.com/shadcn-ui/ui/assets/119763173/ce8560fa-2d8f-4970-aaa8-0dfb8d40eebe

alwalxed avatar Jul 20 '23 12:07 alwalxed

Can you provide a sandbox with the issue? Do you have overflow rules on <html> rather than <body>?

rollakal avatar Jul 20 '23 13:07 rollakal

Can you provide a sandbox with the issue? Do you have overflow rules on <html> rather than <body>?

Layout screenshot

Page screenshot (1)

Component screenshot (2)

alwalxed avatar Jul 20 '23 14:07 alwalxed

Try to remove overflow-x-hidden on <html>. Cant really reproduce the issue from screenshots. So i guess that could fix it.

rollakal avatar Jul 20 '23 14:07 rollakal

Try to remove overflow-x-hidden on <html>. Cant really reproduce the issue from screenshots. So i guess that could fix it.

I actually added it when you commented on your previous comment to test it out, but it didn't work. It's kinda puzzling.

alwalxed avatar Jul 20 '23 14:07 alwalxed

Can you share a sandbox?

rollakal avatar Jul 20 '23 15:07 rollakal

I had the same issue, removing the class of body to a new div under the body solved the issue.

cheng-dai avatar Jul 22 '23 16:07 cheng-dai

@chengd42 thanks bro, that also solves my problem with dialog.

ahmedivy avatar Jul 31 '23 18:07 ahmedivy

@chengd42 thanks!

dim-anis avatar Aug 15 '23 15:08 dim-anis

@ahmedivy this issue can be closed as completed. @shadcn

dan5py avatar Aug 15 '23 16:08 dan5py

I have the same issue and this is my code:

   <html lang="en">
      <body>
        {children}
      </body>
    </html>
  )

ivanhueso avatar Aug 30 '23 19:08 ivanhueso

if for some reason anyone wants to solve this without moving all of body's classes into a new child div you can add "min-w-full" to body. added the ! for overkill

body { @apply !min-w-full; }

voidoperator avatar Sep 03 '23 20:09 voidoperator

It seems like the solution provided above didn't resolve my issue. Here's what worked for me: I found that the problem was caused by the container of the select component being centered using mx-auto. Instead, I fixed it by making it fixed and centrally positioned using the left and right properties. It's not the cleanest solution, but it did the job.

alwalxed avatar Sep 08 '23 04:09 alwalxed

https://github.com/shadcn-ui/ui/assets/125253203/071e7c51-4e3b-459f-a22d-87bd66c20f0d

i get the same issue but more drastic.

ssssylassss avatar Sep 22 '23 01:09 ssssylassss

c4bee2075a0940265dce10d721b22300.mp4 i get the same issue but more drastic.

I get the same problem, i able to work around it, below are the example.

<div className='items-center flex my-8 container'> // parent container
      <p>Content</p>
      <div className='flex gap-4 flex-1 justify-end items-center'> // (dropdown component) in className don't forget "flex-1"
                        <ModeToggle />
                        <DropdownMenu>
                            <DropdownMenuTrigger>
                                <Avatar>
                                    <AvatarImage src="https://github.com/shadcn.png" />
                                    <AvatarFallback>CN</AvatarFallback>
                                </Avatar>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent align='end'>
                                <DropdownMenuLabel>My Account</DropdownMenuLabel>
                                <DropdownMenuSeparator />
                                <DropdownMenuItem>Profile</DropdownMenuItem>
                                <DropdownMenuItem>Billing</DropdownMenuItem>
                                <DropdownMenuItem>Team</DropdownMenuItem>
                                <DropdownMenuItem>Subscription</DropdownMenuItem>
                            </DropdownMenuContent>
                        </DropdownMenu>
          </div>
</div>

danetreab avatar Sep 27 '23 14:09 danetreab

What I think causes this is radix ui which is used by shadcn, it altering the styling, this causes to hide all other elements scrollbar that causes their parent to take the size where the scrollbar is located. In this case the body which style is set to w-full ( take all available space ). So whenever the scrollbar disappears, the body will take that space that's why it shifts

There's couple of solutions I tested out myself, but this one works for me

Make the body width to viewport and hide the overflow horizontally

  • global.css
body {
    margin: 0;
    padding: 0;
}

html,body,:root {
    height: 100%;
}
  • layout.tsx
<body className="w-screen overflow-x-hidden ...otherstyles">

</body>

I also changed my custom navbar w-screen as it is also affected by the shifting

  • nav.tsx
<header className="fixed top-0 w-screen ...otherstyles">

Here's gif of what I experience & the fix

https://github.com/shadcn-ui/ui/assets/48374007/3dfab276-94d3-4f03-980f-df45fd44f6b0

I hope this helps 😄

Jervx avatar Oct 16 '23 14:10 Jervx

I encountered the same issue and was able to resolve it by removing all classes from the body element and adding a child div:

BEFORE:

<html>
    <body className='container mx-auto'>
         {children}
    </body>
</html>

AFTER:

<html>
    <body>
        <div className='container mx-auto'>
             {children}
        </div>
    </body>
</html>

andp97 avatar Oct 21 '23 12:10 andp97

@rollakal solved the issue man. thanks much.

AnikKDev avatar Oct 26 '23 10:10 AnikKDev

I have the same issue and this is my code:

   <html lang="en">
      <body>
       <div> {children} </div>
      </body>
    </html>
  )

make another div in body and pass children and also remove the body css from global css or your main file

ani-ali avatar Nov 23 '23 06:11 ani-ali

that worked for me, that data attribute is added once the select is open

body[data-scroll-locked]{
  min-width: 100%;
}

alexqs96 avatar Mar 03 '24 20:03 alexqs96

Does anyone have a plain CSS solution? I'm not using Next, I'm using Vite, and my application isn't wrapped in a single-body tag. If there's no other solution I'll do that, but I don't feel like adding layouts JUST for this yk?

fernandortec avatar Mar 08 '24 19:03 fernandortec

Does anyone have a plain CSS solution? I'm not using Next, I'm using Vite, and my application isn't wrapped in a single-body tag. If there's no other solution I'll do that, but I don't feel like adding layouts JUST for this yk?

if u are using vite try to add this to your css

body[data-scroll-locked] #root{ min-width: 100%; }

alexqs96 avatar Mar 08 '24 19:03 alexqs96

Does anyone have a plain CSS solution? I'm not using Next, I'm using Vite, and my application isn't wrapped in a single-body tag. If there's no other solution I'll do that, but I don't feel like adding layouts JUST for this yk?

if u are using vite try to add this to your css

body[data-scroll-locked] #root{ min-width: 100%; }

the layout shift still appears, its because when i close the select, the vertical scrolling of the page appears, i need to find a way to remove all vertical scrolls when dialog is open

fernandortec avatar Mar 11 '24 22:03 fernandortec

Does anyone have a plain CSS solution? I'm not using Next, I'm using Vite, and my application isn't wrapped in a single-body tag. If there's no other solution I'll do that, but I don't feel like adding layouts JUST for this yk?

if u are using vite try to add this to your css body[data-scroll-locked] #root{ min-width: 100%; }

the layout shift still appears, its because when i close the select, the vertical scrolling of the page appears, i need to find a way to remove all vertical scrolls when dialog is open

Please have you been able to fix this? I'm facing the same issue.

Christianey avatar Mar 12 '24 20:03 Christianey

Does anyone have a plain CSS solution? I'm not using Next, I'm using Vite, and my application isn't wrapped in a single-body tag. If there's no other solution I'll do that, but I don't feel like adding layouts JUST for this yk?

if u are using vite try to add this to your css body[data-scroll-locked] #root{ min-width: 100%; }

the layout shift still appears, its because when i close the select, the vertical scrolling of the page appears, i need to find a way to remove all vertical scrolls when dialog is open

Please have you been able to fix this? I'm facing the same issue.

I haven't, yet, I believe by the end of this week I'll try to debug it and maybe fix it, but I'm still left with no answers

fernandortec avatar Mar 12 '24 21:03 fernandortec

Okay. I've spent quite a while on this and I can't really figure out what is wrong. I just noticed that if I remove some elements from the page it works fine. Please share your solution if you fix it. Thanks.

Christianey avatar Mar 12 '24 21:03 Christianey

I have the same issue. I have a Select component inside Dialog, when I open the dialog, the data-scroll-locked property is added to the body. When I open the select component, the same property seems to be added, but when I close the select component, it removes the property, even when the dialog is still open.

IvarK avatar Mar 13 '24 13:03 IvarK

I faced a similar issue, but with vertical layout shift. The cause was what @IvarK mentions - the rule body[data-scroll-locked] that is being applied once it opens. Overriding the vertical padding there fixed it for me.

developedbygeo avatar Mar 20 '24 20:03 developedbygeo

I have the same issue. I have a Select component inside Dialog, when I open the dialog, the data-scroll-locked property is added to the body. When I open the select component, the same property seems to be added, but when I close the select component, it removes the property, even when the dialog is still open.

I'm experiencing this exact issue. Did you find a solution?

dmaslan avatar Mar 28 '24 16:03 dmaslan

Pass something like this in comp if you are facing the same issue with dropdown

<DropdownMenu modal={false}>

For select you can do this

html {
  overflow-x: hidden;
}

7hourspg avatar Apr 23 '24 06:04 7hourspg

Ideally we won't need to worry about layout shifts. Hopefully this won't be the case in the future :D

YO-SC avatar Apr 24 '24 14:04 YO-SC