尺寸、媒体类型、!important 规则

本文详细介绍了CSS中设置元素尺寸的方法,包括高度、宽度、max-width和min-width属性的使用。同时,讨论了媒体类型的演变,从CSS2的媒体类型到CSS3的媒体查询,以及如何根据设备能力定义样式。最后,阐述了!important规则的作用及其在CSS优先级中的位置,提醒开发者谨慎使用!

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

尺寸

设置高度和宽度

heightwidth 属性用于设置元素的高度和宽度。

height 和 width 属性不包括内边距、边框或外边距。它设置的是元素内边距、边框以及外边距内的区域的高度或宽度。

高度和宽度值

heightwidth 属性可设置如下值:

  • auto - 默认。浏览器计算高度和宽度。

  • length - 以 px、cm 等定义高度/宽度。

  • % - 以包含块的百分比定义高度/宽度。

  • initial - 将高度/宽度设置为默认值。

高度和宽度实例

实例1:

div.percent {
  height: 200px;
  width: 50%;
  background-color: powderblue;
}

请记住,height 和 width 属性不包括内边距、边框或外边距!它们设置的是元素的内边距、边框和外边距内的区域的高度/宽度!  

设置 max-width

max-width 属性用于设置元素的最大宽度。

可以用长度值(例如 px、cm 等)或包含块的百分比(%)来指定 max-width(最大宽度),也可以将其设置为 none(默认值。意味着没有最大宽度)。

在上个案例中,当浏览器窗口小于元素的宽度(500px)时,浏览器会将水平滚动条添加到页面。

在这种情况下,使用 max-width 能够改善浏览器对小窗口的处理:

div.max {
  max-width: 500px;
  height: 100px;
  background-color: powderblue;
}

同理,max-height 属性可以设置元素的最大高度。

设置 min-width

min-width 属性用于设置元素的最小宽度。

在设计响应式表格时,min-width 会更显作用。

例如以下表格:

<div style="width: 100%;">    <table>        <thead>            <tr>                <th>部门</th>                <th>姓名</th>                <th>家庭地址</th>            </tr>        </thead>        <tbody>            <tr>                <td>技术部</td>                <td>张三</td>                <td>赛虹桥街道小行村9号</td>            </tr>            <tr>                <td>业务部</td>                <td>李四</td>                <td>江苏省南京市雨花台区赛虹桥街道菊花里10幢104号</td>            </tr>            <tr>                <td>业务部</td>                <td>王五</td>                <td>赛虹桥街道工农新村25号</td>            </tr>        </tbody>    </table></div>

当浏览器窗口变小时,文本可能会自动换行,对布局造成一定影响:

<div style="width: 500px; overflow: scroll;">    <table>        <thead>            <tr>                <th style="min-width: 80px;">部门</th>                <th style="min-width: 60px;">姓名</th>                <th style="min-width: 400px;">家庭地址</th>            </tr>        </thead>        <tbody>            <tr>                <td style="min-width: 80px;">技术部</td>                <td style="min-width: 60px;">张三</td>                <td style="min-width: 400px;">赛虹桥街道小行村9号</td>            </tr>            <tr>                <td style="min-width: 80px;">业务部</td>                <td style="min-width: 60px;">李四</td>                <td style="min-width: 400px;">江苏省南京市雨花台区赛虹桥街道菊花里10幢104号</td>            </tr>            <tr>                <td style="min-width: 80px;">业务部</td>                <td style="min-width: 60px;">王五</td>                <td style="min-width: 400px;">赛虹桥街道工农新村25号</td>            </tr>        </tbody>    </table></div>

 同理,min-height 属性可以设置元素的最小高度。

 

媒体类型

CSS2 引入了媒体类型

CSS2 中引入了 @media 规则,它让为不同媒体类型定义不同样式规则成为可能。

例如:您可能有一组用于计算机屏幕的样式规则、一组用于打印机、一组用于手持设备,甚至还有一组用于电视,等等。

不幸的是,除了打印媒体类型之外,这些媒体类型从未得到过设备的大规模支持。

CSS3 引入了媒体类型

CSS3 中的媒体查询扩展了 CSS2 媒体类型的概念:它们并不查找设备类型,而是关注设备的能力。

媒体查询可用于检查许多事情,例如:

  • 视口的宽度和高度

  • 设备的宽度和高度

  • 方向(平板电脑/手机处于横向还是纵向模式)

  • 分辨率

使用媒体查询是一种流行的技术,可以向台式机、笔记本电脑、平板电脑和手机(例如 iPhone 和 Android 手机)提供定制的样式表。

 

媒体查询语法

媒体查询由一种媒体类型组成,并可包含一个或多个表达式,这些表达式可以解析为 true 或 false。

@media not|only mediatype and (expressions) {
  CSS-Code;
}

如果指定的媒体类型与正在显示文档的设备类型匹配,并且媒体查询中的所有表达式均为 true,则查询结果为 true。当媒体查询为 true 时,将应用相应的样式表或样式规则,并遵循正常的级联规则。

除非使用 not 或 only 运算符,否则媒体类型是可选的,且隐含 all 类型。

你还可以针对不同的媒体使用不同的样式表:

<link rel="stylesheet" media="mediatype and|not|only (expressions)" href="print.css">

CSS3媒体类型

描述
all用于所有媒体类型设备。
print用于打印机。
screen用于计算机屏幕、平板电脑、智能手机等等。
speech用于大声“读出”页面的屏幕阅读器。

媒体查询的简单实例

使用媒体查询的一种方法是在样式表内有一个备用的 CSS 部分。

下面的例子在视口宽度为 480 像素或更宽时将背景颜色更改为浅绿色(如果视口小于 480 像素,则背景颜色会是粉色):

body {
	background-color: pink;    
}

@media screen and (min-width: 480px) {
  body {
    background-color: lightgreen;
  }
}

 下例显示了一个菜单,如果视口的宽度为 480 像素或更宽,则该菜单会浮动到页面的左侧(如果视口小于 480 像素,则该菜单将位于内容的顶部):

#leftsidebar { width: 100%; float: none; }#main { margin-left: 0; }​@media screen and (min-width: 480px) {  #leftsidebar { width: 200px; float: left; }  #main { margin-left: 216px; }}

菜单的媒体查询

在本例中,我们使用媒体查询来创建响应式导航菜单,该菜单在不同的屏幕尺寸上会有所不同。

.topnav {
    overflow: hidden;
    background-color: #dddddd;
}

.topnav a {
    color: #333333;
	line-height: 50px;
    float: left;
    display: block;
    text-align: center;
    padding: 0 16px;
    text-decoration: none;
}

.topnav a.on {
    color: white;
    background-color: darkcyan;
}

@media screen and (max-width: 600px) {
    .topnav a {
	   	text-align: left;
		line-height: 40px;
        float: none;
        width: 100%;
    }
}

列的媒体查询

媒体查询的常见用法是创建弹性布局。在本例中,我们创建了一个布局,该布局在四列、两列和全宽列之间变化,具体取决于不同的屏幕尺寸:

.column {
	width: calc(25% - 20px);
	float: left;
	color: white;
	font-size: 30px;
	line-height: 50px;
	text-align: center;
	background-color: lightgray;
	margin: 0 10px;
}

@media screen and (max-width: 992px) {
    .column {
        width: calc(50% - 20px);
    }
}

@media screen and (max-width: 600px) {
    .column {
        width: 100%;
    }
}

更现代的创建列布局方法是使用 CSS Flexbox。

!important 规则

CSS 中的 !important 规则用于增加样式的权重。

!important 与优先级无关,但它与最终的结果直接相关,使用一个 !important 规则时,此声明将覆盖任何其他声明。

实例:

#myid {
  background-color: blue;
}
 
.myclass {
  background-color: gray;
}
 
p {
  background-color: red !important;
}

 

[解析]  以上实例中,尽管 ID 选择器和类选择器具有更高的优先级,但文本段落背景颜色将显示为红色,因为 !important 规则会覆盖 background-color 属性。

使用 !important 是一个坏习惯,应该尽量避免,因为这破坏了样式表中的固有的级联规则,使得调试找 bug 变得更加困难了。

当两条相互冲突的带有 !important 规则的声明被应用到相同的元素上时,拥有更大优先级的声明将会被采用。

实例:

#myid {
  background-color: blue !important;
}
 
.myclass {
  background-color: gray !important;
}
 
p {
  background-color: red !important;
}

使用建议:

  • 一定要优先考虑使用样式规则的优先级来解决问题而不是 !important

  • 只有在需要覆盖全站或外部 CSS 的特定页面中使用 !important

  • 永远不要在你的插件中使用 !important

  • 永远不要在全站范围的 CSS 代码中使用 !important

<script lang="ts" setup> import { ref, onMounted, nextTick } from 'vue' import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus' import { useRouter } from 'vue-router' import request from '@/utils/request' import type { ResultModel } from '@/api/model/model' // 类型定义 interface PasswordForm { oldPassword: string newPassword: string confirmPassword: string } interface LoginUser { id: number username: string // 增加用户名字段 name: string role: string } // API调用(修改参数结构) const updatePasswordApi = (data: { username: string; password: string; newPassword: string }) => request.put<any, ResultModel>('/emps/update', data) const router = useRouter() const loginName = ref('管理员') const loginRole = ref('管理员') const username = ref('') // 存储用户名 const showPasswordDialog = ref(false) const passwordForm = ref<PasswordForm>({ oldPassword: '', newPassword: '', confirmPassword: '', }) const passwordFormRef = ref<FormInstance>() const loading = ref(false) // 密码验证规则 const passwordRules: FormRules<PasswordForm> = { oldPassword: [ { required: true, message: '请输入旧密码', trigger: 'blur' }, { min: 6, max: 20, message: '密码长度6-20个字符', trigger: 'blur' }, ], newPassword: [ { required: true, message: '请输入新密码', trigger: 'blur' }, { min: 6, max: 20, message: '密码长度6-20个字符', trigger: 'blur' }, { validator: (_, value, callback) => { if (value === passwordForm.value.oldPassword) { callback(new Error('新密码不能与旧密码相同')) } else { callback() } }, trigger: 'blur', }, ], confirmPassword: [ { required: true, message: '请确认新密码', trigger: 'blur' }, { validator: (_, value, callback) => { if (value !== passwordForm.value.newPassword) { callback(new Error('两次输入的密码不一致')) } else { callback() } }, trigger: 'blur', }, ], } // 初始化用户信息(增加用户名获取) onMounted(() => { const token = localStorage.getItem('token') if (token) { try { const loginUser: LoginUser = JSON.parse(token) loginName.value = loginUser.name || '管理员' loginRole.value = loginUser.role || '管理员' username.value = loginUser.username || '' // 获取用户名 } catch (e) { console.error('解析token失败:', e) } } }) // 打开修改密码对话框(保持不变) const openPasswordDialog = () => { showPasswordDialog.value = true passwordForm.value = { oldPassword: '', newPassword: '', confirmPassword: '' } nextTick(() => { if (passwordFormRef.value) { passwordFormRef.value.resetFields() } }) } // 提交修改密码(调整跳转逻辑) const submitPassword = async () => { if (!passwordFormRef.value) return try { await passwordFormRef.value.validate() loading.value = true const response = await updatePasswordApi({ username: username.value, password: passwordForm.value.oldPassword, newPassword: passwordForm.value.newPassword, }) if (response.code === 1) { ElMessage.success('密码修改成功,请重新登录') showPasswordDialog.value = false passwordFormRef.value.resetFields() // 直接跳转到登录页面,不显示退出确认 localStorage.removeItem('token') router.push('/login') } else { ElMessage.error(response.msg || '密码修改失败') } } catch (error) { console.error('修改密码失败:', error) ElMessage.error('请求失败,请稍后重试') } finally { loading.value = false } } // 修改退出登录方法(保持原有的确认提示) const logout = () => { ElMessageBox.confirm('确定要退出登录吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', center: true, }) .then(() => { localStorage.removeItem('token') router.push('/login') ElMessage.success('退出登录成功') }) .catch(() => {}) } </script> <template> <div class="common-layout"> <el-container class="layout-container"> <!-- 优化后的头部 --> <el-header class="header"> <div class="header-content"> <div class="logo-section"> <div class="logo"></div> <span class="title">AI教学管理系统</span> </div> <div class="user-section"> <div class="user-info"> <el-avatar class="user-avatar" :size="36"> {{ loginName.charAt(0) }} </el-avatar> <div class="user-details"> <div class="user-name">{{ loginName }}</div> <div class="user-role">{{ loginRole }}</div> </div> </div> <div class="header-tools"> <el-tooltip content="修改密码" placement="bottom"> <el-button class="tool-btn" type="text" @click="openPasswordDialog"> <el-icon class="icon"><EditPen /></el-icon> </el-button> </el-tooltip> <el-tooltip content="退出登录" placement="bottom"> <el-button class="tool-btn" type="text" @click="logout"> <el-icon class="icon"><SwitchButton /></el-icon> </el-button> </el-tooltip> </div> </div> </div> </el-header> <el-container class="main-container"> <!-- 侧边栏 --> <el-aside class="aside"> <el-scrollbar class="menu-scrollbar"> <el-menu router default-active="/index" class="side-menu" background-color="#2c3e50" text-color="#ecf0f1" active-text-color="#f39c12" > <el-menu-item index="/index"> <el-icon><Menu /></el-icon> <span>首页</span> </el-menu-item> <el-sub-menu index="2" class="menu-group"> <template #title> <el-icon><Document /></el-icon> <span>班级学员管理</span> </template> <el-menu-item index="/stu"> <el-icon><UserFilled /></el-icon> <span>学员管理</span> </el-menu-item> <el-menu-item index="/clazz"> <el-icon><HomeFilled /></el-icon> <span>班级管理</span> </el-menu-item> </el-sub-menu> <el-sub-menu index="3" class="menu-group"> <template #title> <el-icon><Avatar /></el-icon> <span>部门管理</span> </template> <el-menu-item index="/emp"> <el-icon><Avatar /></el-icon> <span>员工管理</span> </el-menu-item> <el-menu-item index="/dept"> <el-icon><HelpFilled /></el-icon> <span>部门管理</span> </el-menu-item> </el-sub-menu> <el-sub-menu index="4" class="menu-group"> <template #title> <el-icon><PieChart /></el-icon> <span>数据统计管理</span> </template> <el-menu-item index="/report/emp"> <el-icon><InfoFilled /></el-icon> <span>员工信息统计</span> </el-menu-item> <el-menu-item index="/report/stu"> <el-icon><Share /></el-icon> <span>学员信息统计</span> </el-menu-item> <el-menu-item index="/log"> <el-icon><Clock /></el-icon> <span>日志信息统计</span> </el-menu-item> </el-sub-menu> </el-menu> </el-scrollbar> </el-aside> <!-- 主内容区 --> <el-main class="main-content"> <router-view></router-view> </el-main> </el-container> </el-container> <!-- 修改密码对话框 --> <el-dialog v-model="showPasswordDialog" title="修改密码" width="500px" center :close-on-click-modal="false" > <el-form ref="passwordFormRef" :model="passwordForm" :rules="passwordRules" label-width="100px" label-position="right" > <el-form-item label="旧密码" prop="oldPassword"> <el-input v-model="passwordForm.oldPassword" type="password" placeholder="请输入当前密码" show-password clearable /> </el-form-item> <el-form-item label="新密码" prop="newPassword"> <el-input v-model="passwordForm.newPassword" type="password" placeholder="6-20位字符" show-password clearable /> </el-form-item> <el-form-item label="确认密码" prop="confirmPassword"> <el-input v-model="passwordForm.confirmPassword" type="password" placeholder="请再次输入新密码" show-password clearable /> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button @click="showPasswordDialog = false">取消</el-button> <el-button type="primary" @click="submitPassword" :loading="loading"> 确认修改 </el-button> </div> </template> </el-dialog> </div> </template> <style scoped> /* 布局基础样式 */ .common-layout { height: 100vh; display: flex; flex-direction: column; background-color: #f5f7fa; } .layout-container { height: 100%; display: flex; flex-direction: column; } /* 头部样式 - 优化版 */ .header { background: linear-gradient(135deg, #2c3e50 0%, #1a2530 100%); color: white; height: 64px; padding: 0; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); z-index: 1000; position: relative; } .header-content { display: flex; justify-content: space-between; align-items: center; height: 100%; padding: 0 30px; max-width: 1600px; margin: 0 auto; width: 100%; } .logo-section { display: flex; align-items: center; gap: 15px; } .logo { width: 40px; height: 40px; background: linear-gradient(135deg, #3498db, #8e44ad); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); } .title { font-size: 1.8rem; font-weight: 700; letter-spacing: 1px; background: linear-gradient(to right, #f39c12, #f1c40f); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .user-section { display: flex; align-items: center; gap: 20px; } .user-info { display: flex; align-items: center; gap: 12px; padding: 5px 15px; border-radius: 30px; background: rgba(255, 255, 255, 0.1); transition: all 0.3s ease; } .user-info:hover { background: rgba(255, 255, 255, 0.15); } .user-avatar { background: linear-gradient(135deg, #3498db, #8e44ad); display: flex; align-items: center; justify-content: center; font-weight: bold; color: white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .user-details { display: flex; flex-direction: column; } .user-name { font-weight: 600; font-size: 15px; letter-spacing: 0.5px; } .user-role { font-size: 12px; color: #bdc3c7; margin-top: 2px; } .header-tools { display: flex; gap: 8px; } .tool-btn { color: #ecf0f1; font-size: 18px; padding: 8px; transition: all 0.3s ease; border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; } .tool-btn:hover { background-color: rgba(255, 255, 255, 0.15); transform: translateY(-2px); } .tool-btn .icon { transition: transform 0.3s ease; } .tool-btn:hover .icon { transform: scale(1.2); } /* 侧边栏样式 */ .aside { background-color: #2c3e50; color: #ecf0f1; height: 100%; width: 240px !important; transition: width 0.3s ease; border-right: 1px solid #34495e; } .menu-scrollbar { height: calc(100vh - 64px); } .menu-scrollbar .el-scrollbar__bar.is-vertical { width: 6px; right: 2px; border-radius: 4px; background-color: rgba(255, 255, 255, 0.1); } .menu-scrollbar .el-scrollbar__thumb { background-color: rgba(255, 255, 255, 0.3); border-radius: 4px; transition: background-color 0.3s ease; } .menu-scrollbar .el-scrollbar__thumb:hover { background-color: rgba(255, 255, 255, 0.5); } .side-menu { background-color: transparent; border-right: none; padding: 15px 0; } .side-menu .el-menu-item, .side-menu .el-sub-menu .el-sub-menu__title { margin: 6px 10px; padding: 12px 20px; font-size: 14px; color: #ecf0f1; border-radius: 6px; transition: all 0.3s ease; height: 48px; display: flex; align-items: center; } .side-menu .el-menu-item:hover, .side-menu .el-sub-menu .el-sub-menu__title:hover { background-color: #34495e; transform: translateX(5px); } .side-menu .el-menu-item.is-active { background: linear-gradient(90deg, rgba(52, 152, 219, 0.3), transparent); color: #f39c12 !important; font-weight: bold; border-left: 3px solid #f39c12; } .menu-group .el-menu-item { font-size: 13px; padding-left: 50px !important; color: #dcdcdc; transition: all 0.3s ease; height: 42px; } .menu-group .el-menu-item:hover { background-color: #3a5267; transform: translateX(5px); } .menu-group .el-menu-item.is-active { background-color: #3a5267; color: #f1c40f; font-weight: 600; } /* 主内容区样式 */ .main-content { background-color: #f0f2f5; padding: 20px; flex: 1; overflow-y: auto; border-radius: 8px 8px 0 0; box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.05); } /* 对话框样式 */ .dialog-footer { display: flex; justify-content: center; padding: 10px 20px 0; } /* 响应式设计 */ @media (max-width: 992px) { .aside { width: 200px !important; } .header-content { padding: 0 20px; } .title { font-size: 1.5rem; } .user-info .user-name { display: none; } } @media (max-width: 768px) { .aside { width: 64px !important; } .logo-section .title, .user-info .user-details, .el-sub-menu .el-sub-menu__title span, .el-menu-item span { display: none; } .el-sub-menu .el-sub-menu__title, .el-menu-item { justify-content: center; padding: 0 !important; } .el-icon { margin-right: 0 !important; font-size: 20px; } .menu-group .el-menu-item { padding-left: 20px !important; justify-content: flex-start; } } </style> 优化一下页面自适应大小,页面缩小之后右上角的退出登录会被挡住
最新发布
07-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值