CSS:动态类/属性和媒体查询 - 如何解决这个难题?

Bla*_*bam 7 css php html5 css3 media-queries

编写插件的扩展我可以使用PHP更改HTML元素的所有属性.

$attributes["style"] .= 'padding-left:10px;';
array_push($attributes["class"], "long-container");
array_push($attributes["class"], "super smooth");
$attributes["data-whatever"] = "great";
Run Code Online (Sandbox Code Playgroud)

现在我想给用户一个动态输入div的宽高比的可能性(@Web_Designer在这里的答案中描述了如何做到这一点的解决方案:用CSS保持div的宽高比).

在我可以更改第三方插件输出的函数中,我编写了以下代码,用于根据输入计算宽度高度比.由于箱子的高度是:

if( !empty( $args['stretchy-desktop'] ) ) {
    $sd = array_map('trim',explode(":",$args['stretchy-desktop']));

    if(count($sd)==2) {
        $sd[0] = floatval(str_replace(",",".",$sd[0]));
        $sd[1] = floatval(str_replace(",",".",$sd[1]));

        if($sd[0]>0 && $sd[1]>0) {
            $padding = ($sd[1] / $sd[0])*100;
            array_push($attributes['class'], 'stretchy-desktop');
            $attributes['style'] .= 'padding-bottom:'.$padding.'%;';
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

好吧?然而,现在用户希望有可能为移动设备输入不同的重量高度比以及移动设备的不同动态最小高度,这就是我被困住了.

1)现在无法提供内联@media查询,否则我的解决方案就是这样(是否可以将CSS @media规则内联?):

$attributes['style'] .= '@media (min-width:540px) {padding-bottom:'.$padding.'%;}@media (max-width:539px) {padding-bottom:'.$padding_mobile.';}';
Run Code Online (Sandbox Code Playgroud)

2)现在无法在CSS中使用HTML属性值(使用HTML5数据属性的CSS值),否则我的解决方案将是这样的:

$attributes['data-desktoppadding'] = $padding;
$attributes['data-mobilepadding'] = $padding_mobile;
Run Code Online (Sandbox Code Playgroud)

在CSS中:

@media (min-width:540px) {
.long-container {
padding-bottom: attr(data-desktoppadding);
}
}

@media (max-width:539px) {
.long-container {
padding-bottom: attr(data-mobilepadding);
}
}
Run Code Online (Sandbox Code Playgroud)

3)由于值是动态数字,我无法为每个可能的现有float定义CSS类.

当然我可以使用JavaScript,但我们都知道显着的缺点(包括丑陋的页面加载).

你能想到任何针对这种困境的CSS解决方案吗?

Kod*_*son 5

这是我提出的解决方案.它涉及在目标元素周围创建一个包装div.基本上,它的工作方式是为外部div分配移动模式的内联样式,并为内部div分配桌面模式的内联样式.当浏览器窗口调整大小低于桌面视图的阈值时,它会将内部div(桌面)内联样式重置为默认值,以便外部div(移动)内联样式接管.当浏览器窗口调整大小超过阈值时,它会将外部div(移动)内联样式重置为默认值,以便内部div(桌面)内联样式接管.它覆盖内联样式的方法是使用!important CSS媒体查询中规则集中的关键字.

我认为不言而喻,以下代码段中的内联样式将替换为您的内容$attributes['style'].但由于你将拥有独立的移动和桌面风格,我想它会是$attributes['style-mobile']$attributes['style-desktop'].

@media (min-width:540px) {
    .padding-mobile {
        padding-bottom:0 !important;
        width: auto !important;
    }
}
			
@media (max-width:539px) {
    .padding-desktop {
        padding-bottom:0 !important;
        width: auto !important;
    }
}
Run Code Online (Sandbox Code Playgroud)
<div class="padding-mobile" style="width:100%;background-color:red;padding-bottom:100%;">
    <div class="padding-desktop" style="width:50%;background-color:red;padding-bottom:25%;">
				
				
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)


Jus*_*ent 5

一种适用于大多数主流浏览器的优雅方法是使用自定义属性。它们基本上是 CSS 中的变量。截至撰写本文时(2017-03-27),只有 IE 和 Edge 不支持此功能,尽管他们正在努力支持 Edge。

您可以将变量添加到$attributes['style']并实际将它们应用到媒体查询内的样式表中。然后浏览器动态地使用它们。

我已经实现了一个演示作为片段,但因为在JSFiddle上更改视口大小更容易,所以也有一个演示的副本。请注意,这里的响应断点是在 CSS 中定义的,变量是在元素的内联样式中定义的。

.container {
  width: 200px;
}

.block {
  position: relative;
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 0;
  padding: 10px;
  padding-bottom: var(--desktop-ratio);
  background: #bada55;
  color: #444;
}

@media (min-width: 540px) {
  .mobile {
    display: none;
  }
}

@media (max-width: 539px) {
  .desktop {
    display: none;
  }
  
  .block {
    padding-bottom: var(--mobile-ratio);
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div class="block" style="--desktop-ratio: 56.25%; --mobile-ratio: 200%;";>
  My aspect ratio is set via custom properties. It is <span class="mobile">1:2</span><span class="desktop">16:9</span>.
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

(至少目前)显然不可能使用变量设置断点。那是,

@media (min-width: var(--breakpoint)) { ... }
Run Code Online (Sandbox Code Playgroud)

显然目前至少 Firefox 和 Chrome 还不能理解。

 


 

或者,基于Kodos Johnson的答案:如果只有一个断点,则可以使用padding-bottom padding-top。两者之一定义小屏幕上的宽高比,另一个定义大屏幕上的宽高比。这消除了添加包装元素的需要。这是一个基于Kodos 答案的示例。

@media (min-width: var(--breakpoint)) { ... }
Run Code Online (Sandbox Code Playgroud)
@media (min-width:540px) {
    .block {
        padding-top: 0 !important;
    }
}
			
@media (max-width:539px) {
    .block {
        padding-bottom: 0 !important;
    }
}
Run Code Online (Sandbox Code Playgroud)