ChatGPT解决这个技术问题 Extra ChatGPT

媒体查询可以根据 div 元素而不是屏幕调整大小吗?

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

更新

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

您的小部件的大小如何变化?您的页面是固定宽度(例如 960 像素)且视口高于 1024 像素,还是两者都是流畅的?这还不清楚,知道会很有用
小部件的大小可能会有所不同,就像我们在 facebook 应用程序中显示的一样,我们显示的小部件与我们在普通网页上显示的小部件不同
这工作得很好,并且是一个相对较小的构建(约 4kb 缩小)github.com/tysonmatanich/elementQuery
好问题。我遇到的最相关的案例是具有许多插件和许多主题的产品/解决方案/框架。一些插件适用于某些主题,但有时您必须在自定义 CSS 中“修复它们”才能使用特定主题。如果插件开发人员可以选择根据屏幕大小和容器大小进行不同的设计,那么插件和主题的组合会更好,并且需要更少的自定义 CSS hack。

B
BoltClock

经过近 十年 的工作——通过提案、概念验证、讨论和更广泛的 Web 开发人员社区的其他贡献——CSS 工作组终于奠定了 所需的一些基础容器查询written into a future edition of the CSS Containment spec!有关此类功能如何工作和使用的更多详细信息,请查看 Miriam Suzanne 的extensive explainer

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

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

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

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


我听说过某种方法可以使用带有媒体查询的函数来从包含元素中获取大小。有什么方法可以将它与媒体查询结合起来调整元素的大小?
您必须使用 JS 定期获取元素的宽度并做出相应的反应(定期 = 每秒左右,否则会减慢某些浏览器的速度;因此 = 如果您想要最快的方法,可以通过切换类来设置小部件的样式)。
要在本地完成此操作,我们需要 @element 查询。 W3C 有一些关于 @media 查询的押韵/原因的很好的文档:w3.org/TR/css3-mediaqueries/#width(此链接将您带到讨论宽度的部分 --- 媒体类型的宽度,而不是其中包含的元素)
这就是我正在寻找的 @container@element,其中子级响应父级大小而不是浏览器/媒体大小。可悲的是,它似乎还没有准备好。
M
Marc J. Schmidt

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

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


D
Djave

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

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

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

为了重申这个问题,我们在下面看到 3 个相同的组件,每个组件由三个标记为 abc 的橙色 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 );
  }
}

Demo

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


h
haddnin

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


H
Hexodus

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

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

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

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


C
Community

几年前我遇到了同样的问题,并资助了一个插件的开发来帮助我的工作。我已将插件作为开源发布,因此其他人也可以从中受益,您可以在 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 像素宽的小部件看起来不错,然后您可以使用任何模板(在任何网站上)自信地将该小部件放入任何页面的任何侧边栏中,并且


c
cimmanon

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


R
Roumelis George

我认为您可以完全使用 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 */
}

不,它在屏幕上看起来很难看。屏幕尺寸变化更快,但元素出现在屏幕上的时间更晚且更小。
H
Hendy Irawan

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

http://www.mademyday.de/css-height-equals-width-with-pure-css.html

使用 CSS 保持 div 的纵横比

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

div {宽度:100%;底部填充:75%;背景:黄金; /** <-- 用于演示 **/ }

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

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

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


J
José Salgado

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

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

Demo 1 - Demo 2


草案规范有一个 polyfill。 github.com/juggle/resize-observer
Heydon 的文章提供了一个示例实现。在页面上搜索“ResizeObserver”:heydonworks.com/article/the-flexbox-holy-albatross
J
Jacky Choo

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

  // assuming your widget class is "widget"
  .widget {
    max-width: 100%;
    height: auto;
  }

问题提到小部件的大小可能会有所不同,当容器很宽时,设置 max-width 不会改变小部件的大小。 .widget 只是作为小部件 div 类的示例。