Flexbox布局中实现表单在Banner与Footer间自适应垂直对齐
Let's fix this vertical alignment issue properly. The problem with your current approach is that using absolute positioning on login-layout__positioner takes it out of the normal document flow, which breaks its spatial relationship with the banner and footer. Plus, hardcoding values like top: -6.5% isn't responsive for different form heights or screen sizes.
Since you're already using flexbox to stick the footer to the bottom, we can extend that same logic to center your form perfectly between the banner and footer. Here's how to do it:
Step 1: Restructure the HTML
First, adjust your HTML to follow a clear flex hierarchy. The banner, form container, and footer should all be direct children of the main flex body:
<div class="app-layout__body"> <!-- Banner stays fixed at the top --> <div class="banner__container"> <div class="wrapper banner__top"> <div class="grid"> <div class="grid__item large--one-third banner__grid-item-left">logo</div> <div class="grid__item large--two-thirds "> <h2 class="banner__heading-right"> </h2> </div> </div> </div> </div> <!-- This container fills the space between banner and footer --> <div class="app-layout__container"> <div class="wrapper login-layout__positioner"> <div class="grid__item medium--two-thirds login-layout__form"> <div class="login-layout__inner__container"> <div class="grid"> <div class="grid__item "> <h2 class="">Sign In</h2> </div> </div> <form> <div> <div class="grid"> <div class="grid__item "> <div class="form-group form-control__input"> <label for="email" id="email-label" class="label__default label__strong label__double-margin">Email</label> <div class="input-wrapper"> <input type="text" autocomplete="off" class="input__default form-control" id="email" name="email" aria-invalid="false" aria-describedby="email-error" value=""> </div> </div> </div> </div> <div class="grid"> <div class="grid__item "> <div class="form-group form-control__input"> <label for="password" id="password-label" class="label__default label__strong label__double-margin">Password</label> <div class="input-wrapper "> <input type="password" autocomplete="off" class="input__default form-control" id="password" name="password" value=""> </div> </div> </div> </div> <div class="grid login__button__container"> <div class="grid__item large--two-thirds "><a tabindex="0" href="/business/forgotten-password">Forgotten your password?</a></div> <div class="grid__item medium--one-third "> <button class="button__default button__primary" type="submit">LOGIN</button> </div> </div> </div> </form> </div> </div> </div> </div> <!-- Footer stays fixed at the bottom --> <footer class="footer__footer"> <div class="wrapper"> <div class="grid"> <div class="grid__item "> <ul> <li><a target="_blank" href="/static/about">About</a></li> <li><a target="_blank" href="/static/accessibility">Accessibility</a></li> <li><a target="_blank" href="/static/cookies">Cookies</a></li> <li><a target="_blank" href="/static/privacy">Privacy</a></li> </ul> </div> </div> </div> </footer> </div>
Step 2: Update the CSS
Now modify your styles to leverage flexbox for dynamic centering, removing the problematic absolute positioning:
/* Base layout - preserve sticky footer foundation */ html, body, #global__root, .global__main-content { height: 100%; margin: 0; /* Remove default body margin to eliminate gaps */ } .app-layout__body { height: 100vh; display: flex; flex-direction: column; } /* This container grows to fill available space between banner and footer */ .app-layout__container { flex: 1 0 auto; display: flex; /* Convert to flex container */ align-items: center; /* Vertically center child elements */ justify-content: center; /* Horizontally center child elements */ padding: 20px 0; /* Add vertical padding to prevent form touching edges on small screens */ } /* Remove absolute positioning from form wrapper */ .login-layout__positioner { width: 100%; /* Ensure it uses full width of the flex container */ } /* Keep existing banner styles */ .banner__container { color: #fff; background-color: #0065bd; } .banner__top { padding-top: 22px; } /* Form styling adjustments */ .login-layout__form { padding-left: 0; margin: 0 auto; /* Center form horizontally within its wrapper */ } .medium--eight-twelfths { width: 66.666%; } .login-layout__inner__container { padding: 0px 30px 30px; } /* Clean up footer styles */ .footer__footer { text-align: center; color: #fff; background-color: #0065bd; font-weight: 700; font-size: 16px; padding: 16px 0; margin-top: 0; /* Remove margin since flex handles spacing automatically */ } .footer__footer ul { list-style: none; margin-left: 0; padding-left: 0; } .footer__footer a, .footer__footer a:hover, .footer__footer a:focus, .footer__footer a:active { outline: 0; color: #fff; }
Key Changes Explained:
- Clear Flex Hierarchy: The banner, form container, and footer are now direct children of
app-layout__body, so flexbox can properly manage their spacing. - Flex Centering: By making
app-layout__containera flex box withalign-items: centerandjustify-content: center, the form will automatically center vertically and horizontally—no matter how tall the form is. - Removed Absolute Positioning: No more hardcoded
topvalues; flexbox handles dynamic spacing for all screen sizes. - Responsive Padding: The vertical padding on
app-layout__containerensures the form doesn't touch the banner or footer on small devices. - Cleaned Footer Styles: Duplicate properties and unnecessary margins are removed to keep the layout consistent.
This solution will work seamlessly for any form height and is fully responsive across all screen sizes.
内容的提问来源于stack exchange,提问作者dagda1

