简体   繁体   English

如何使 html 元素响应其父视口而不是浏览器视口?

[英]how to make html elements respond to their parent viewport rather than browser viewport?

I'm working on a Vue poject and I let the user choose the width and height of app main container by clicking on each device specific icon (mobile, tablet, laptop and desktop).我正在开发一个 Vue 项目,我让用户通过单击每个设备特定的图标(移动设备、平板电脑、笔记本电脑和台式机)来选择应用程序主容器的宽度和高度。 something like firefox responsive tool.类似于 Firefox 响应工具。 how can I force elements inside the main container respond to it's own viewport rather than browser viewport?如何强制主容器内的元素响应它自己的视口而不是浏览器视口?
I'm using UIKit width component to define my breakpoints.我正在使用 UIKit 宽度组件来定义我的断点。 I know I can achieve this by adding/removing classes dynamically, but my Vue components are added dynamicallly by the user, so it's more complex.我知道我可以通过动态添加/删除类来实现这一点,但是我的 Vue 组件是由用户动态添加的,所以它更复杂。
I thought there might be a more generic way to do this.我认为可能有一种更通用的方法来做到这一点。 here's the sample code ( number of visible slides changes in defferent viewports and if my component is a grid element items inside it should wrap ( based on container width ) ):这是示例代码(不同视口中可见幻灯片的数量发生变化,如果我的组件是网格元素,它内部的项目应该包装(基于容器宽度)):

 <div id="main-container" :style="{width: deviceWidth, height: deviceHeight}"> <!-- Dynamically added component --> <div class="uk-position-relative uk-visible-toggle uk-light" uk-slider> <!-- UIKit Width classes --> <ul class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m"> <li> <img src="../../img/01.jpg" alt=""> <div class="uk-position-center uk-panel"><h1>1</h1></div> </li> <li> <img src="../../img/02.jpg" alt=""> <div class="uk-position-center uk-panel"><h1>2</h1></div> </li> <li> <img src="../../img/03.jpg" alt=""> <div class="uk-position-center uk-panel"><h1>3</h1></div> </li> <li> <img src="../../img/04.jpg" alt=""> <div class="uk-position-center uk-panel"><h1>4</h1></div> </li> </ul> <a class="uk-position-center-left uk-position-small uk-hidden-hover" href="#" uk-slidenav-previous uk-slider-item="previous"></a> <a class="uk-position-center-right uk-position-small uk-hidden-hover" href="#" uk-slidenav-next uk-slider-item="next"></a> </div> </div>

Explanation解释

This is a very simple, and minimal answer, it's literally been written to simply illustrate how you can tackle your problem, but as you can see within this answer, pressing the different buttons makes the containing element grow/shrink.这是一个非常简单且最少的答案,它实际上只是为了说明您如何解决问题而编写的,但是正如您在此答案中所见,按下不同的按钮会使包含元素增大/缩小。

As you can see within this solution, all of the elements that are responsive will respond based on the parent element's size.正如您在此解决方案中所见,所有响应元素都将根据父元素的大小进行响应。 It's really easy to achieve this if you use fixed sizes, like in my example.如果您使用固定尺寸,就很容易实现这一点,就像我的例子一样。

Although, take note, I only selected to use a very minimal implementation, no use of Vue or anything sophisticated, this is a simple solution, using native technologies only.尽管请注意,我只选择使用非常小的实现,没有使用 Vue 或任何复杂的东西,但这是一个简单的解决方案,仅使用本地技术。

Edit编辑

After having learned exactly what you're looking for, the long story short is that there's no clean & easy way to do that, at least to my knowledge, your best bet would be to simply change & alter the classes, that, by far makes the most sense.准确了解您正在寻找的内容之后,长话短说是没有简单易行的方法可以做到这一点,至少据我所知,您最好的选择是简单地更改和更改课程,到目前为止最有意义。

Because your question is somewhat vague, to me it appears that you're trying to execute logic similar to what @arieljuod has stated, where you're trying to run media queries on specific DOM elements rather than the user's viewport.因为您的问题有些含糊,所以在我看来,您似乎正在尝试执行类似于@arieljuod 所说的逻辑,您尝试在特定 DOM 元素而不是用户的视口上运行媒体查询。

I'm sorry to inform you that to my knowledge there's no clean and easy way to achieve this, not to say that there isn't a way, I'm sure someone has found a way, but a clean, concise, easy to read, solution, I highly doubt there's such a solution.很抱歉地通知您,据我所知,没有干净且简单的方法可以实现这一目标,并不是说没有办法,我确定有人已经找到了方法,而是一种干净、简洁、易于实现的方法阅读,解决方案,我非常怀疑是否有这样的解决方案。

 const clickHandler = txt => { let clName = ''; switch (txt) { case 'Desktop': clName = 'desktop'; break; case 'Tablet': clName = 'tablet'; break; case 'Mobile': clName = 'mobile'; break; default: clName = 'desktop'; } document.getElementById("app").className = clName; }; document.querySelectorAll("#sizes button").forEach(btn => { btn.onclick = () => clickHandler(btn.textContent); });
 #sizes { width: 100%; display: block; overflow: auto; } #sizes button { float: left; margin: 15px; padding: 15px; border: 1px solid black; background: white; box-sizing: border-box; width: calc(33.33% - 30px); } #app { height: 100vh; background: #eee; } #app.desktop { width: 960px; } #app.tablet { width: 700px; } #app.mobile { width: 320px; } .col-2 { display: block; overflow: auto; } .col-2>* { float: left; width: calc(50% - 30px); padding: 15px; margin: 15px; box-sizing: border-box; border: 1px solid black; } /* Just for a demo */ #redBlock { background: red; height: 100px; width: 75%; }
 <!-- UIkit CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/css/uikit.min.css" /> <!-- UIkit JS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit-icons.min.js"></script> <div id="sizes"> <button>Desktop</button> <button>Tablet</button> <button>Mobile</button> </div> <div id="app" class="desktop"> <div class="col-2"> <p>Hello</p> <p>World!</p> </div> <div id="redBlock"></div> <div uk-slider> <div class="uk-position-relative uk-visible-toggle uk-light"> <ul class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m"> <li> <img src="https://getuikit.com/docs/images/slider1.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>1</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider2.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>2</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider3.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>3</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider4.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>4</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider5.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>5</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider1.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>6</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider2.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>7</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider3.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>8</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider4.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>9</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider5.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>10</h1> </div> </li> </ul> <a class="uk-position-center-left uk-position-small uk-hidden-hover" href="#" uk-slidenav-previous uk-slider-item="previous"></a> <a class="uk-position-center-right uk-position-small uk-hidden-hover" href="#" uk-slidenav-next uk-slider-item="next"></a> </div> <ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin"></ul> </div> </div>

Possible Solution可能的解决方案

What I would do in this scenario is as stated above, alter classes on the slider, like so, I mean you could use extra/additional logic to check the user's width & whatnot, but this is possibly the most simplistic approach possible.在这种情况下我会做的是如上所述,改变滑块上的类,就像这样,我的意思是你可以使用额外/额外的逻辑来检查用户的宽度等,但这可能是最简单的方法。

 const clickHandler = txt => { const slider = document.getElementById("mySlider"); let clName = ''; switch (txt) { case 'Desktop': clName = 'desktop'; slider.className = 'uk-slider-items uk-child-width-1-4'; break; case 'Tablet': clName = 'tablet'; slider.className = 'uk-slider-items uk-child-width-1-3'; break; case 'Mobile': clName = 'mobile'; slider.className = 'uk-slider-items uk-child-width-1-2'; break; default: clName = 'desktop'; slider.className = 'uk-slider-items uk-child-width-1-4'; } document.getElementById("app").className = clName; }; document.querySelectorAll("#sizes button").forEach(btn => { btn.onclick = () => clickHandler(btn.textContent); });
 #sizes { width: 100%; display: block; overflow: auto; } #sizes button { float: left; margin: 15px; padding: 15px; border: 1px solid black; background: white; box-sizing: border-box; width: calc(33.33% - 30px); } #app { height: 100vh; background: #eee; } #app.desktop { width: 960px; } #app.tablet { width: 700px; } #app.mobile { width: 320px; } .col-2 { display: block; overflow: auto; } .col-2>* { float: left; width: calc(50% - 30px); padding: 15px; margin: 15px; box-sizing: border-box; border: 1px solid black; } /* Just for a demo */ #redBlock { background: red; height: 100px; width: 75%; }
 <!-- UIkit CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/css/uikit.min.css" /> <!-- UIkit JS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit-icons.min.js"></script> <div id="sizes"> <button>Desktop</button> <button>Tablet</button> <button>Mobile</button> </div> <div id="app" class="desktop"> <div class="col-2"> <p>Hello</p> <p>World!</p> </div> <div id="redBlock"></div> <div uk-slider> <div class="uk-position-relative uk-visible-toggle uk-light"> <ul id="mySlider" class="uk-slider-items uk-child-width-1-4"> <li> <img src="https://getuikit.com/docs/images/slider1.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>1</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider2.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>2</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider3.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>3</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider4.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>4</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider5.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>5</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider1.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>6</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider2.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>7</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider3.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>8</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider4.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>9</h1> </div> </li> <li> <img src="https://getuikit.com/docs/images/slider5.jpg" alt=""> <div class="uk-position-center uk-panel"> <h1>10</h1> </div> </li> </ul> <a class="uk-position-center-left uk-position-small uk-hidden-hover" href="#" uk-slidenav-previous uk-slider-item="previous"></a> <a class="uk-position-center-right uk-position-small uk-hidden-hover" href="#" uk-slidenav-next uk-slider-item="next"></a> </div> <ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin"></ul> </div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM