412

我想使用媒体查询根据元素所在元素的大小调整元素的大小div。我不能使用屏幕大小,因为div它就像网页中的小部件一样使用,并且它的大小可能会有所不同。

更新

看起来现在正在做这方面的工作: https ://github.com/ResponsiveImagesCG/cq-demos

4

11 回答 11

298

经过近十年的工作——通过提案、概念验证、讨论和更广泛的 Web 开发人员社区的其他贡献——CSS 工作组终于奠定了将容器查询写入未来版本所需的一些基础工作。 CSS 遏制规范!有关此类功能如何工作和使用的更多详细信息,请查看 Miriam Suzanne 的详尽解释

希望不久之后我们就会看到这样一个系统的健壮的跨浏览器实现。这是一个艰苦的等待,但我很高兴,由于循环依赖或无限循环或你有什么,我们不再必须接受它作为 CSS 的不可克服的限制(这些仍然是某些方面的潜在问题)提议的设计,但我相信 CSSWG 会找到方法)。


媒体查询并非旨在基于页面中的元素工作。它们被设计为基于设备或媒体类型工作(因此它们被称为媒体查询)。width, height, 和其他基于尺寸的媒体功能都指基于屏幕的媒体中视口或设备屏幕的尺寸。它们不能用于引用页面上的某个元素。

如果您需要根据页面上某个div元素的大小应用样式,则必须使用 JavaScript 来观察该div元素大小的变化,而不是使用媒体查询。

或者,自此答案的原始发布以来引入了更现代的布局技术,例如 flexbox 和自定义属性等标准,您可能根本不需要媒体或元素查询。Djave 提供了一个示例。

于 2012-09-07T13:39:26.097 回答
123

我刚刚创建了一个 javascript 垫片来实现这个目标。如果需要,请看一下,这是一个概念验证,但请注意:它是早期版本,仍需要一些工作。

https://github.com/marcj/css-element-queries

于 2013-06-02T03:29:27.493 回答
41

iframe 内的媒体查询可以用作元素查询。我已经成功地实现了这一点。这个想法来自Zurb最近一篇关于响应式广告的帖子。没有Javascript!

于 2014-07-16T19:25:53.797 回答
37

从布局的角度来看,使用现代技术是可能的。

它由海顿皮克林(我相信)组成。他在这里详细介绍了这个过程:http ://www.heydonworks.com/article/the-flexbox-holy-albatross

Chris Coyier 拿起它并在此处进行演示:https ://css-tricks.com/putting-the-flexbox-albatross-to-real-use/

为了重申这个问题,我们在下面看到了 3 个相同的组件,每个组件由三个标记为 和 的橙色adivb组成c

后两个块垂直显示,因为它们受限于水平空间,而顶部组件 3 个块是水平布局的。

它使用flex-basisCSS 属性和 CSS 变量来创建这种效果。

最后一个例子

.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

于 2019-09-26T13:49:20.013 回答
27

正如@BoltClock 在接受的答案中所写,目前仅使用 CSS 是不可能的,但您可以使用 JavaScript 解决这个问题。

我创建了一个容器查询(又名元素查询)prolyfill 来解决这类问题。它的工作方式与其他脚本略有不同,因此您不必编辑元素的 HTML 代码。您所要做的就是包含脚本并在您的 CSS 中使用它,如下所示:

.element:container(width > 99px) {
    /* If its container is at least 100px wide */
}

https://github.com/ausi/cq-prolyfill

于 2015-10-05T13:35:06.390 回答
18

几年前我遇到了同样的问题,并资助了一个插件的开发来帮助我的工作。我已将插件作为开源发布,因此其他人也可以从中受益,您可以在 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(文档的根元素,<html>

元素查询允许您从单独的响应式设计模块组成布局,每个模块都对它们在页面上的显示方式有一点“自我意识”。

使用 EQCSS,您可以设计一个从 150 像素宽到 1000 像素宽的小部件看起来不错,然后您可以使用任何模板(在任何网站上)自信地将该小部件放入任何页面的任何侧边栏中,并且

于 2015-11-12T19:26:12.767 回答
8

这个问题非常模糊。正如 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。

于 2012-09-07T17:49:13.783 回答
4

我认为您可以完全使用 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 */
}
于 2015-06-17T09:05:29.430 回答
3

我也在考虑媒体查询,但后来我发现了这个:

<div>只需为 的百分比值创建一个包装器padding-bottom,如下所示:

div {
  width: 100%;
  padding-bottom: 75%;
  background:gold; /** <-- For the demo **/
}
<div></div>

它将导致<div>高度等于其容器宽度的 75%(纵横比为 4:3)。

这种技术也可以与媒体查询和一些关于页面布局的特殊知识相结合,以获得更细粒度的控制。

足以满足我的需要。这也可能足以满足您的需求。

于 2017-07-30T23:46:37.387 回答
3

您可以使用ResizeObserver API。它仍处于早期阶段,因此并非所有浏览器都支持它(但有几个 polyfill 可以帮助您)。

此 API 允许您在调整 DOM 元素大小时附加事件侦听器。

演示 1 -演示 2

于 2019-10-23T10:55:57.423 回答
0

对于我来说,我通过设置 div 的最大宽度来做到这一点,因此对于小部件不会受到影响,并且由于最大宽度样式而调整了大部件的大小。

  // assuming your widget class is "widget"
  .widget {
    max-width: 100%;
    height: auto;
  }
于 2018-01-24T08:28:14.637 回答