【问题标题】:Is it possible to keep the width of the parent element when position: fixed is applied?应用 position: fixed 时是否可以保持父元素的宽度?
【发布时间】:2013-04-07 18:21:00
【问题描述】:

当我们将position:fixed 应用于一个元素时,它会占用文档的out of the normal flow,因此它不尊重它的父元素宽度。 有没有办法让它继承它的父宽度如果这被声明为百分比? (下面的工作用例)

let widthis = $('.box').width();
$('.dimensions').text(`width is ${widthis}`);

$('button').on('click', function() {
  $('.box').toggleClass('fixed');
  let widthis = $('.box').width();
  $('.dimensions').text(`width is ${widthis}`);
});
.container {
  max-width: 500px;
  height: 1000px;
}

.box {
  background-color: lightgreen;
}

.fixed {
  position: fixed;
}

.col-1 {
  border: 1px solid red;
  float: left;
  width: 29%;
}

.col-2 {
  border: 1px solid pink;
  float: left;
  width: 69%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click this to toggle position fixed for the left column</button>
<div class="container">
  <div class="col-1">
    <div class="box">
      fixed content<br>
      <span class="dimensions"></span>
    </div>
    </div>
  
  <div class="col-2">
    some other content
    </div>
  </div>

【问题讨论】:

  • CSS 看起来像是在做它被告知要做的事情?
  • 它,也可能是菜单不再是父菜单了?
  • 我更新了 url,我在我的测试用例中忘记了一些 CSS 属性。改变 position:fixed 与 position:static 你会看到宽度是如何变化的。
  • 是的,这可能是因为菜单不再充当父菜单,我认为您可能需要相应调整。
  • @GeorgeKatsanos,我想也许是时候选择一个答案了?

标签: css position css-position


【解决方案1】:

这是一个有趣的挑战。要解决这个问题,我们首先应该了解fixed 的实际作用。

了解固定

absolute 不同,fixed 不会将自己定位于其最近的相对父级。相反,fixed 相对于视口定位自身。视口将始终保持固定,这就是您获得效果的原因。

话虽如此,只要您“继承”任何宽度,它都会与视口相关。因此,当我们尝试将目标元素的宽度设置为其父元素的宽度时,这对我们没有好处。

详细了解position 的不同行为。

快速解决方案

有两种方法可以解决此问题。

纯 CSS

我们可以使用纯CSS来解决这个问题,但是我们需要提前知道宽度。假设它的父元素是300px;

.parent{
    width: 300px;
}

.parent .fixed_child{
    position: fixed;
    width: 300px;
}

JS

现在有了移动设备,我们没有真的拥有拥有设置宽度的奢侈,尤其是任何超过300px。使用百分比也不起作用,因为它是相对于视口而不是父元素。 我们可以使用JS,本例用jQuery来实现。让我们看一个函数,它总是在给定时刻设置父元素的宽度

 function toggleFixed () {
      var parentwidth = $(".parent").width();      
      $(".child").toggleClass("fixed").width(parentwidth);        
  }

css:

.fixed{
    position:fixed;
}

CodePen查看

动态宽度

这很好,很漂亮,但是如果窗口的宽度发生变化,而用户仍在页面上,用这个改变父元素会发生什么?虽然父级可以调整其宽度,但子级将保持函数设置的宽度。 我们可以使用 jQuery's resize() 事件监听器解决此问题。首先,我们需要将我们创建的函数分成两部分:

function toggleFixed() {
   adjustWidth();
   $(".child").toggleClass("fixed");
 }

 function adjustWidth() {
   var parentwidth = $(".parent").width();
   $(".child").width(parentwidth);
 }

现在我们已经分离了每个部分,我们可以单独调用它们,我们将包括我们原始的按钮方法来切换固定和宽度:

$("#fixer").click(
     function() {
       toggleFixed();
     });

现在我们还将调整大小事件监听器添加到窗口:

 $(window).resize(
     function() {
       adjustWidth();
     })

查看CodePen

那里!现在我们有了一个固定元素,当窗口调整大小时,它的大小也会随之调整。

结论

我们通过了解fixed 的位置及其局限性来应对这一挑战。与 Absolute 不同,fixed 仅与视口相关,因此不能继承其父级的宽度。

为了解决这个问题,我们需要使用一些 JS 魔法来实现这一点。

在某些情况下,我们需要一种动态方法,使用不同宽度的缩放设备。再次,我们采用了 JS 方法。

【讨论】:

  • 这是一个出色的答案。您刚刚获得了杰出答题帽!
  • 宽度怎么样:继承; ?
  • > 话虽如此,只要您“继承”任何宽度,它将与视口相关。因此,当我们尝试将目标元素的宽度设置为其父元素的宽度时,这对我们没有好处。
  • 很棒的答案!看到这么多错误的答案...
【解决方案2】:

您可以使用width:inherit。这将使它听父母的。我对其进行了测试,它可以在 Firefox 中运行。

【讨论】:

【解决方案3】:

宽度正在改变,因为静态时对象从其父对象接收其百分比宽度。将对象设置为固定后,它不再处于流动状态并调整大小。

您必须自己设置导航菜单的大小,而不是期望元素从父级获取宽度。

.nav {
    position: fixed;
    width: 20%;
    border: 1px solid green;
    padding: 0px;
    list-style-type:none;
    background:lightblue;
}

http://tinker.io/3458e/5

【讨论】:

  • 我更新了 url,我在我的测试用例中忘记了一些 CSS 属性。改变 position:fixed 与 position:static 你会看到宽度是如何变化的。
【解决方案4】:

您好,您也可以使用 jquery 来保持宽度。例如:

jQuery(function($) {
    function fixDiv() {
        var $cache = $('#your-element');
        var $width = $('#your-element').parent().width();
        if ($(window).scrollTop() > 100) {
            $cache.css({
                'position': 'fixed',
                'top': '10px',
                'width': $width
            });
        } else {
            $cache.css({
                'position': 'relative',
                'top': 'auto'
            });
        }
    }
    $(window).scroll(fixDiv);
    fixDiv();
 });

【讨论】:

  • 希望避免使用 JS。
【解决方案5】:

正如有人已经建议的那样,使用纯 javascript(不带 jquery):

const parentElement = document.querySelector('.parent-element');
const fixedElement = document.querySelector('.fixed-element');

window.addEventListener('load', changeFixedElementWidth);
window.addEventListener('resize', changeFixedElementWidth);

function changeFixedElementWidth() {
  const parentElementWidth = parentElement.getBoundingClientRect().width;
  fixedElement.style.width = parentElementWidth + 'px';
}

【讨论】:

    【解决方案6】:

    这可能是因为&lt;html&gt;&lt;body&gt; 元素上的一些默认边距或填充。当它是静态的时,它的大小基于当时&lt;body&gt; 的宽度,但当它变为position:fixed 时,它的大小是相对于视口的。

    因此,删除默认边距/填充应该可以解决问题(根据我的经验 body { margin:0; } 可以解决问题),就像在解决问题时更改大小一样(例如 width:calc(n% - 5px);)。

    【讨论】:

    • “n”代表什么?
    • @GeorgeKatsanos 无论您希望元素是什么百分比宽度
    【解决方案7】:

    解决方法可能是:导航的 CSS 中的 left:8px; right:0; width:18%;。 虽然不是最好的解决方案。

    【讨论】:

    • 是的,设置任意数字有点麻烦 - 我想唯一的解决方案似乎是使用 javascript 获取父级的宽度..
    【解决方案8】:

    width:auto;添加到带有position:fixed;的元素,使其宽度等于其父元素的宽度。

    【讨论】:

    • 不知道为什么这被否决了——它实际上解决了我的问题。谢谢!
    • 它不起作用。 with position: fixed 元素超出正常流程并且不尊重其父宽度。
    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 2013-03-05
    • 2013-11-19
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    相关资源
    最近更新 更多