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


317

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

更新资料

看来现在正在对此进行处理:https : //github.com/ResponsiveImagesCG/cq-demos


2
我认为这个问题太简短,无法得到一个好的答案。也许您可以提供一个示例来说明您要做什么?也许使用jsfiddle.net来测试您的想法并允许其他人帮助您?通常,没有任何理由要问您,使用CSS无需媒体查询就可以实现所需的结果。您可以为字体使用百分比尺寸和ems来缩放嵌套元素。但是也许我只需要看一下您的html代码和CSS的示例以更好地理解?
BenSwayne 2012年

1
小部件的大小如何变化?您的页面是固定宽度的(例如960px),还是视口大于1024px?尚不清楚,这将是有用的
FelipeAls 2012年

3
实际上,我当前的项目也有类似情况。对于较宽的设备,将以2列布局显示项目列表;对于较窄的设备,将以1列布局显示项目列表,但是无论如何,单个项目将以1列布局显示。列表和单个版本都有两个相当宽和短的元素。在更广泛的设备上,这两个元素并排显示最佳。理想情况下,窄设备:始终垂直,宽设备:始终平行,介于(取决于1或2行)之间:垂直或平行。浮动是简单的解决方案,但是宽度也需要根据布局而变化。
cimmanon 2012年

1
LESS将被编译为CSS,因此,如果CSS不支持,LESS也将无法为您提供帮助。
jvannistelrooy,2014年

3
链接不再有效?
mix3d

Answers:


228

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

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


我听说某种方式可以将函数与媒体查询一起使用,以从包含元素中获取大小。有什么办法可以将它与媒体查询结合起来以调整元素的大小?
Yazz.com 2012年

1
您必须使用JS来定期获取元素的宽度并做出相应的反应(周期性地=大约每秒,否则会减慢某些浏览器的速度;因此=如果想要最快的方法,则通过切换类样式化窗口小部件)。
FelipeAls 2012年

6
要在本地完成此操作,我们需要@element查询。W3C拥有有关@media查询的押韵/原因的一些很好的文档:w3.org/TR/css3-mediaqueries/#width(此链接将您带到讨论宽度的部分---介质类型的宽度,而不是其中包含的元素)
道森2012年

有机会使其在电子邮件中起作用吗?当容器div太小时(即,例如Gmail桌面版电子邮件空间太小而无法适应2列设计,例如由于窗口大小调整),我试图将移动样式应用于电子邮件。
列夫

顺便说一句,@ element查询将使css成为图灵的完整语言
尼克,

117

我刚刚创建了一个JavaScript填充程序来实现此目标。如果需要,请看一下,这是一个概念证明,但请注意:这是一个早期版本,仍然需要一些工作。

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


5
谢谢,我印象深刻
Yazz.com 2013年

5
这难以置信。结合响应式引导程序,我正在做一些很棒的工作,而仅@media无法实现。做得好。
2015年

3
您挽救了我们的生命
Broda Noel '18

哇,真的很好,让事情变得容易
得多

凉。有问题。此插件检测到-需要min-width更新哪些元素属性;我需要手动编写启用了min-width续订的CSS类列表,标记的元素吗?
亚历山大·贡恰洛夫

38

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


我认为这是最好的解决方案,因为媒体查询在iframe中有效。
emfi

25

如@BoltClock在接受的答案中所写,当前仅靠CSS是不可能的,但是您可以使用JavaScript来解决。

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

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

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


2
它充满了JS。目标是仅具有CSS功能。
格林

13
Prolyfills(和polyfills)通常写在JS来启用浏览器不支持的又一个特点。Prolyfill的目标是,在CSS中支持此功能后,它就会过时。
ausi

3
@ius在问题中没有提到“仅CSS”。您是如何得出这个结论的?
ausi

1
@ius,除非您无法在CSS中完成,所以在CSS之外提供解决方案是完全合理的。比“不,你不能”要好得多;)
韦斯利·史密斯

1
@ DelightedD0D在我发表评论后,他更改了答案,我对更改投了+1票。当前的回答对我来说还可以,因为这表明仅CSS不可能做到这一点。
ius

17

几年前,我遇到了同样的问题,并资助了一个插件的开发以帮助我的工作。我已将该插件作为开源发布,因此其他人也可以从中受益,您可以在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
  • 最大宽度 %

高度查询

  • 最小高度in px
  • 最小高度in %
  • 最大高度 px
  • 最大高度 %

计数查询

  • 最小字符
  • 最大字符数
  • 最小线
  • 最大线数
  • 最小的孩子
  • 最大儿童

特殊选择器

在EQCSS元素查询中,您还可以使用三个特殊的选择器,这些选择器使您可以更具体地应用样式:

  • $this (与查询匹配的元素)
  • $parent (与查询匹配的元素的父元素)
  • $root(文档的根元素<html>

元素查询使您可以根据各个响应式设计模块来构成布局,每个模块对它们在页面上的显示方式都有一些“自我意识”。

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


1
不错的项目!我看看您做了什么
Yazz.com 2015年

@innovati我在寻找一种对元素进行查询的方法时发现了这篇文章。我似乎无法正常工作。你介意看我的票吗?github.com/eqcss/eqcss/issues/96
Andrew Newby

10

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

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

克里斯·科耶尔(Chris Coyier)挑选了它,并在此处通过演示进行了工作:https : //css-tricks.com/putting-the-flexbox-albatross-to-real-use/

要重申的问题,下面我们看到同样的组件3,每个组成的标记三个橘的div abc

后两个块垂直显示,因为它们限制在水平空间中,而顶部组件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个单词详细解释,我强烈建议您阅读。


Heydon的文章中提到的那件事……看起来和工作起来就像魔术!谢谢您的回复,太棒了。
ptyskju

2
这是每个绊脚石的人都在寻找的答案
TehShrike

7

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


47
这个问题一点也不模糊。实际上,这是一个很好的问题。不幸的是,没有好的答案。
stepanian '16

2
使用这种方法进行糟糕的维护。
Totty.js,2017年

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 */
}

不,它在屏幕上看起来很丑。屏幕尺寸变化更快,但是元素出现在屏幕上的位置随后变小了。
格林

3

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

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

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

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

该技术还可以与媒体查询和有关页面布局的一些专门知识相结合,以实现更精细的控制。

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


2

您可以使用ResizeObserver API。它仍处于早期阶段,因此尚不被所有浏览器支持(但是可以使用多种polyfill来帮助您)。

基本上,此API允许您将事件侦听器附加到DOM元素的调整大小。

演示1 - 演示2


规范草案有一个polyfill。github.com/juggle/resize-observer
Trevor Karjanis

Heydon的文章提供了此示例实现。在页面上搜索“ ResizeObserver”:heydonworks.com/article/the-flexbox-holy-albatross
Gabe Rogan

0

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

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

该问题提到小部件的大小可能会有所不同,当容器较宽时,设置max-width不会更改小部件的大小。.widget只是小部件的div类的一个示例。
Jacky Choo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.