我想使用媒体查询根据元素所在的 div
元素的大小调整元素的大小。我不能使用屏幕大小,因为 div
就像网页中的小部件一样使用,它的大小可能会有所不同.
更新
看起来现在正在做这方面的工作:https://github.com/ResponsiveImagesCG/cq-demos
经过近 十年 的工作——通过提案、概念验证、讨论和更广泛的 Web 开发人员社区的其他贡献——CSS 工作组终于奠定了 所需的一些基础容器查询 为 written into a future edition of the CSS Containment spec!有关此类功能如何工作和使用的更多详细信息,请查看 Miriam Suzanne 的extensive explainer。
希望不久之后我们就会看到这样一个系统的健壮的跨浏览器实现。这是一个艰苦的等待,但我很高兴,由于循环依赖或无限循环或你有什么,它不再是我们必须接受的 CSS 不可逾越的限制(这些仍然是某些方面的潜在问题提议的设计,但我相信 CSSWG 会找到方法)。
媒体查询并非旨在基于页面中的元素工作。它们被设计为基于设备或 media types 工作(因此它们被称为 媒体 查询)。 width
、height
和其他基于尺寸的媒体功能均指基于屏幕的媒体中视口或设备屏幕的尺寸。它们不能用于引用页面上的某个元素。
如果您需要根据页面上某个 div
元素的大小应用样式,则必须使用 JavaScript 来观察该 div
元素大小的变化,而不是使用媒体查询。
或者,自此答案的原始发布以来引入了更现代的布局技术,例如 flexbox 和自定义属性等标准,您可能根本不需要媒体或元素查询。 Djave provides an example.
我刚刚创建了一个 javascript 垫片来实现这个目标。如果需要,请看一下,这是一个概念验证,但请注意:它是早期版本,仍需要一些工作。
https://github.com/marcj/css-element-queries
从布局的角度来看,使用现代技术是可能的。
它由海顿皮克林(我相信)组成。他在这里详细介绍了该过程:http://www.heydonworks.com/article/the-flexbox-holy-albatross
Chris Coyier 拿起它并在此处进行演示:https://css-tricks.com/putting-the-flexbox-albatross-to-real-use/
为了重申这个问题,我们在下面看到 3 个相同的组件,每个组件由三个标记为 a
、b
和 c
的橙色 div 组成。
后两个块垂直显示,因为它们受限于水平空间,而顶部组件 3 个块是水平布局的。
它使用 flex-basis
CSS 属性和 CSS 变量来创建此效果。
https://i.stack.imgur.com/Hfi7i.png
.panel{
display: flex;
flex-wrap: wrap;
border: 1px solid #f00;
$breakpoint: 600px;
--multiplier: calc( #{$breakpoint} - 100%);
.element{
min-width: 33%;
max-width: 100%;
flex-grow: 1;
flex-basis: calc( var(--multiplier) * 999 );
}
}
Heydon 的文章有 1000 字的详细解释,我强烈建议您阅读。
2021/22 更新
正如其他答案中提到的,容器查询即将到来。它有一个完整的规范,它的用法在 MDN 上有详细说明:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries
并且有一个 polyfill 可以让还不支持它的浏览器加速:
https://github.com/GoogleChromeLabs/container-query-polyfill
这里有一个很好的概述视频:
https://www.youtube.com/watch?v=gCNMyYr7F6w
正如@BoltClock 在接受的答案中所写,目前仅使用 CSS 是不可能的,但您可以使用 JavaScript 解决这个问题。
我创建了一个容器查询(又名元素查询)polyfill 来解决这类问题。它的工作方式与其他脚本略有不同,因此您不必编辑元素的 HTML 代码。您所要做的就是包含脚本并在您的 CSS 中使用它,如下所示:
.element:container(width > 99px) {
/* If its container is at least 100px wide */
}
https://github.com/ausi/cq-prolyfill
几年前我遇到了同样的问题,并资助了一个插件的开发来帮助我的工作。我已将插件作为开源发布,因此其他人也可以从中受益,您可以在 Github 上获取它:https://github.com/eqcss/eqcss
根据我们对页面元素的了解,有几种方法可以应用不同的响应式样式。以下是 EQCSS 插件允许您用 CSS 编写的一些元素查询:
@element 'div' and (condition) {
$this {
/* Do something to the 'div' that meets the condition */
}
.other {
/* Also apply this CSS to .other when 'div' meets this condition */
}
}
那么带有 EQCSS 的响应式样式支持哪些条件呢?
重量查询
最小宽度(以 px 为单位)
最小宽度(%)
最大宽度(以 px 为单位)
最大宽度(%)
高度查询
最小高度(以 px 为单位)
以 % 为单位的最小高度
最大高度(以 px 为单位)
最大高度(%)
计数查询
最小字符
最大字符
最小线
最大线
最小的孩子
最大儿童
特殊选择器
在 EQCSS 元素查询中,您还可以使用三个特殊的选择器来更具体地应用您的样式:
$this(匹配查询的元素)
$parent(匹配查询的元素的父元素)
$root(文档的根元素,)
元素查询允许您从单独的响应式设计模块组成布局,每个模块都对它们在页面上的显示方式有一点“自我意识”。
使用 EQCSS,您可以设计一个从 150 像素宽到 1000 像素宽的小部件看起来不错,然后您可以使用任何模板(在任何网站上)自信地将该小部件放入任何页面的任何侧边栏中,并且
这个问题非常模糊。正如 BoltClock 所说,媒体查询只知道设备的尺寸。但是,您可以将媒体查询与下降选择器结合使用来执行调整。
.wide_container { width: 50em }
.narrow_container { width: 20em }
.my_element { border: 1px solid }
@media (max-width: 30em) {
.wide_container .my_element {
color: blue;
}
.narrow_container .my_element {
color: red;
}
}
@media (max-width: 50em) {
.wide_container .my_element {
color: orange;
}
.narrow_container .my_element {
color: green;
}
}
唯一的其他解决方案需要 JS。
我认为您可以完全使用 css 完成您想要的唯一方法是为您的小部件使用流体容器。如果容器的宽度是屏幕的百分比,那么您可以使用媒体查询来根据容器的宽度设置样式,因为您现在将知道每个屏幕的尺寸是什么容器的尺寸。例如,假设您决定将容器的屏幕宽度设为 50%。然后对于 1200px 的屏幕宽度,您知道您的容器是 600px
.myContainer {
width: 50%;
}
/* you know know that your container is 600px
* so you style accordingly
*/
@media (max-width: 1200px) {
/* your css for 600px container */
}
我也在考虑媒体查询,但后来我发现了这个:
http://www.mademyday.de/css-height-equals-width-with-pure-css.html
使用 CSS 保持 div 的纵横比
只需使用 padding-bottom
的百分比值创建一个包装器 <div>
,如下所示:
div {宽度:100%;底部填充:75%;背景:黄金; /** <-- 用于演示 **/ }
它将导致 <div>
的高度等于其容器宽度的 75%(纵横比为 4:3)。
这种技术也可以与媒体查询和一些关于页面布局的特殊知识相结合,以获得更细粒度的控制。
足以满足我的需要。这也可能足以满足您的需求。
您可以使用 ResizeObserver API。它仍处于早期阶段,因此并非所有浏览器都支持它(但有几个 polyfill 可以帮助您)。
此 API 允许您在调整 DOM 元素大小时附加事件侦听器。
对于我来说,我通过设置 div 的最大宽度来做到这一点,因此对于小部件不会受到影响,并且由于最大宽度样式而调整了大部件的大小。
// assuming your widget class is "widget"
.widget {
max-width: 100%;
height: auto;
}
.widget
只是作为小部件 div 类的示例。
@element
查询。 W3C 有一些关于@media
查询的押韵/原因的很好的文档:w3.org/TR/css3-mediaqueries/#width(此链接将您带到讨论宽度的部分 --- 媒体类型的宽度,而不是其中包含的元素)@container
或@element
,其中子级响应父级大小而不是浏览器/媒体大小。可悲的是,它似乎还没有准备好。