关于height:100%无效的解决办法与细节

本文探讨了CSS中使用100%高度布局时遇到的问题及解决方案,特别是当父容器未显式设置高度时子元素无法正确继承高度的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         我们知道,对于块级元素浏览器总是默认使其宽度等于父容器宽度的100%不需要自己设定,但是对宽度的计算就并非这样了,当没有显式得定义容器的高度时,其高度由其包裹的内容决定,当显示得定义高度时,容器的高度就为设定的值,使用overflow可以对超出高度的内容进行处理。

         有时我们不明确高度,需要使用height:100%来设定高度时,有时并不能达到预期的效果,主要原因就是当我们使用height:100%时,浏览器会去寻找其父容器的高度来确定这个height:100%具体应该是什么值,当我们没有为父容器显式得定义高度时,浏览器就无法获取相应的值,所以不能达到预期的效果,

         所以,使height:100%生效的根本解决办法就是父级一定要有显式定义的高度

         大家有可能主要到那两个红红的显式,为什么要说显式呢,因为大家常用到的还有一个与Heigh相关的属性:min-height,用来控制元素的最小高度,当我们在父元素使用Min-height来定义最小高度时,子元素使用height:100%也是无法获取高度的,详见如下例子

<body>
<div style="min-height: 500px">
    <div style="height: 100%;background-color: #000"></div>
</div>
</body>


我们可以清除得看见,父元素的高度确实变成了500px,但是子元素并没有获取相应的高度,但如果为父元素添加一个显式的hegiht,如height:2px;这时,子元素就能够正确获取高度(注意,父元素不能使用height:100%,因为同上所讲,其父元素body是没有高度的,所以同样获取不到高度,除非将body.html都加上height:100%,其中html的height:100%获取的是浏览器可视区域的高度)。


      查阅了w3cCSS手册,也并没有发现对此的解释,个人认为是应为height默认取值auto,根据子元素来撑起其高度,但是在这种情况下,子元素又依赖于父元素的高度,所以取值为0。若对此各位有更好的见解,欢迎在下方评论提出。


<template> <div class="login-container"> <div class="login-box"> <!-- 头部Logo标题 --> <div class="login-header"> <div class="login-logo"> <i class="fas fa-shield-alt"></i> </div> <h2>停车场管理系统</h2> </div> <!-- 登录表单 --> <div class="login-form"> <!-- 用户名输入 --> <div class="form-group"> <label for="username">用户名</label> <div class="input-group"> <i class="fas fa-user"></i> <input type="text" id="username" v-model="form.username" placeholder="请输入用户名" :class="{'error': error.value.username}" > </div> <p class="error-message" v-if="error.username">{{ error.value.username }}</p> </div> <!-- 密码输入 --> <div class="form-group"> <label for="password">密码</label> <div class="input-group"> <i class="fas fa-lock"></i> <input type="password" id="password" v-model="form.password" placeholder="请输入密码" :class="{'error': error.value.password}" > </div> <p class="error-message" v-if="error.password">{{ error.value.password }}</p> </div> <!-- 登录按钮 --> <button class="btn btn-primary btn-block" @click="handleLogin" :disabled="loading" > <span v-if="loading"> <i class="fas fa-spinner fa-spin"></i> 登录中... </span> <span v-else> 登录 <i class="fas fa-sign-in-alt"></i> </span> </button> <!-- 版本信息 --> <div class="login-footer"> <p>版本号: 1.0.0</p> </div> </div> </div> </div> </template> <script setup> import { ref, reactive,onMounted } from 'vue'; import { login } from '@/services/loginService.js'; // 引入登录服务 import {useRoute, useRouter} from 'vue-router'; // 路由跳转 // 响应式数据 const form = reactive({ username: '', password: '' }); //状态管理 const loading = ref(false); const error = ref({ username: '', password: '', general: '' }); const router = useRouter(); // 初始化路由实例 const route = useRoute(); // 表单验证 const validateForm = () => { let isValid = true; if (!form.username) { error.value.username = '请输入用户名'; isValid = false; } else { error.value.username = ''; } if (!form.password) { error.value.password = '请输入密码'; isValid = false; } else { error.value.password = ''; } return isValid; }; // 登录处理 const handleLogin = async () => { // 重置错误信息 error.value = { username: '', password: '', general: '' }; //验证表单 if (!validateForm()) { return; } loading.value = true; try { // 调用登录接口APi(对接 loginService.js) const response = await login(form.username, form.password); //处理后端响应 if (response.code === 200 && response.data) { //存储用户信息 localStorage.setItem('token', response.data.token || ''); localStorage.setItem('userId', response.data.id || ''); localStorage.setItem('userType', response.data.type || ''); localStorage.setItem('username', response.data.username || ''); localStorage.setItem('isLoggedIn', 'true'); console.log('登录成功'); // 登录成功,跳转到首页 const redirect = route.query.redirect || '/home'; router.push(redirect); } } catch (err) { if (err.code === 1005) { error.value.general = '用户名或密码错误'; } else { error.value.general = err.message || '登录失败,请稍后重试'; } } finally { loading.value = false; } }; // 页面加载时检查登录状态 onMounted(() => { const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'; if (isLoggedIn) { router.push('/home'); } }); </script> <style scoped> .login-container { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f5f5f5; background-image: url('https://picsum.photos/id/1048/1920/1080'); background-size: cover; background-position: center; position: relative; } .login-container::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); } .login-box { background-color: white; border-radius: 10px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); width: 400px; max-width: 90%; padding: 40px; position: relative; z-index: 1; } .login-logo { text-align: center; margin-bottom: 30px; } .login-logo i { font-size: 48px; color: #1abc9c; margin-bottom: 10px; } .login-logo h2 { color: #2c3e50; font-size: 24px; } .form-group { margin-bottom: 20px; } .form-group label { display: block; margin-bottom: 8px; color: #2c3e50; font-weight: 500; } .input-group { display: flex; align-items: center; border: 1px solid #ddd; border-radius: 4px; padding: 10px; } .input-group i { width: 25px; color: #999; } .input-group input { flex: 1; border: none; outline: none; padding-left: 10px; font-size: 16px; } .remember-me { display: flex; align-items: center; } .remember-me input { margin-right: 8px; } .btn-block { width: 100%; margin-top: 20px; } .login-footer { text-align: center; margin-top: 20px; color: #999; font-size: 14px; } .error-message { color: #e74c3c; margin-bottom: 15px; text-align: center; } </style>@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; // 用户登录 @PostMapping("/login") public Resp<User> login(@RequestBody LoginForm loginForm) { User user = userService.login(loginForm.getUsername(), loginForm.getPassword()); return Resp.ok(user); }
最新发布
06-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值