66

当我们应用于position:fixed一个元素时,它会脱离文档的正常流程,因此它不尊重它的父元素宽度。如果将其声明为百分比,有没有办法让它继承它的父宽度?(下面的工作用例)

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>

4

8 回答 8

51

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

了解固定

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

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

详细了解职位的不同行为。

快速解决方案

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

纯 CSS

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

.parent{
    width: 300px;
}

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

JS

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

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

CSS:

.fixed{
    position:fixed;
}

CodePen中查看

动态宽度

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

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

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

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

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

现在我们还将 resize 事件监听器添加到窗口:

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

CodePen中查看

那里!现在我们有一个固定元素,当窗口调整大小时,它的大小将被调整。

结论

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

为了解决这个问题,我们需要使用一些 JS 魔法来实现这一点,这在 jQuery 中并不需要太多。

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

于 2017-03-19T08:52:25.663 回答
12

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

于 2013-06-02T19:44:11.287 回答
6

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

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

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

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

于 2013-04-15T15:12:14.203 回答
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();
 });
于 2015-07-09T10:12:23.307 回答
4

正如有人已经建议的那样,使用普通的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';
}
于 2018-02-26T02:07:52.720 回答
2

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

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

于 2015-05-03T01:58:03.587 回答
0

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

于 2013-04-15T15:26:47.503 回答
-3

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

于 2016-01-15T10:59:51.830 回答