css 是否可以在定位时保持父元素的宽度:是否应用固定?

rlcwz9us  于 2023-02-06  发布在  其他
关注(0)|答案(9)|浏览(308)

当我们将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>
4szc88ey

4szc88ey1#

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

了解已修复

absolute不同的是,fixed不会从最近的相关父对象开始定位,而是相对于视口**定位。视口将始终保持固定,这就是为什么您会得到这样的效果。
也就是说,无论何时你"继承"任何宽度,它都是相对于视口的宽度,所以当我们试图将目标元素的宽度设置为其父元素的宽度时,它对我们没有任何好处。

快速解决方案

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

纯CSS

我们可以使用pure CSS来解决这个问题,但是我们需要提前知道宽度

.parent{
    width: 300px;
}

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

JS

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

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

CSS:

.fixed{
    position:fixed;
}

动态宽度

这很好,但是如果窗口的宽度改变了,当用户还在页面上的时候,用这个改变了父元素,会发生什么?当父元素可以调整它的宽度时,子元素将保持函数设置的宽度。我们可以用jQuery'sresize()**事件监听器来修复这个问题。首先,我们需要将我们创建的函数一分为二:

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

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

现在我们已经分离了每个部分,我们可以单独调用它们了,我们将包括我们最初的button方法,该方法用于切换fixed和width:

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

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

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

好了!现在我们有了一个固定的元素,它的大小会随着窗口大小的改变而改变。

结论

我们通过理解fixed的位置和它的局限性来解决这个问题。与Absolute不同,fixed只与视口相关,因此不能继承其父视口的宽度。
为了解决这个问题,我们需要使用一些JS魔法,这在jQuery中并不需要太多。
在某些情况下,我们需要一个动态的方法来缩放不同宽度的设备。

3wabscal

3wabscal2#

你可以使用width:inherit。这将使它听父母。我测试了它,它在火狐浏览器中工作。

jxct1oxe

jxct1oxe3#

宽度正在更改,因为对象在静态时从其父对象接收其百分比宽度。一旦将对象设置为固定,它将不再处于流动状态并调整大小。
你必须自己设置导航菜单的大小,而不是期望元素从父元素获得宽度。

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

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

t5fffqht

t5fffqht4#

你也可以使用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();
 });
r9f1avp5

r9f1avp55#

正如有人已经建议的那样,使用普通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';
}
fnatzsnv

fnatzsnv6#

这可能是因为<html><body>元素上的一些默认边距或填充。当它是静态的时,它根据<body>当时的宽度来调整大小,但当它更改为position:fixed时,它根据viewport来调整大小。
因此,删除默认的边距/填充应该可以解决这个问题(根据我的经验,body { margin:0; }可以解决这个问题),在解决这个问题时也应该改变大小(如width:calc(n% - 5px);)。

7z5jn7bk

7z5jn7bk7#

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

mjqavswn

mjqavswn8#

在我的例子中,我想要一个响应式的用户界面,但我也想要一个固定的侧边栏。我所做的是找到最大屏幕上的最大宽度,以像素为单位(在我的例子中是250px)。然后我使用:

<script>
.parent {
  maxWidth: '1500px';
  margin: 'auto auto';
}
.left {
  flex: 1;
}
.center {
  flex: 4;
}
.right {
  flex: 1;
}
.fixedTop {
  position: 'fixed';
  maxWidth: '250px';
}
</script>

<div className="parent">
  <div className="left">left side</div>
  <div className="center">center</div>
  <div className="right"> 
    <div className="fixedTop">
      <label>I am responsively sized horizontally up to my max width.</label>
    </div>
  </div>
</div>

这不允许您按照请求继承宽度,但是如果您尝试执行我所做的操作,它可能有助于避免这种需要。

vu8f3i0k

vu8f3i0k9#

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

相关问题