web-dev-qa-db-ja.com

position:fixedが適用されている場合、親要素の幅を維持することは可能ですか?

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>
48
George Katsanos

これは興味深い挑戦です。これにアプローチするには、まずfixedが実際に行うことを理解する必要があります。

固定を理解する

absoluteとは異なり、fixedは最も近い相対的な位置からそれ自体を配置しません親。代わりに、fixedビューポートを基準にして自身を配置します。ビューポートは常に固定されたままであるため、その効果が得られます。

そうは言っても、幅を「継承」するときは常に、ビューポートに対応します。そのため、ターゲット要素の幅を親の幅に設定しようとしても意味がありません。

position .のさまざまな動作の詳細

クイックソリューション

これを修正する方法は2つあります。

純粋なCSS

pure CSSを使用してこの問題を修正できますが、事前に幅を知る必要があります。親要素が_300px;_であるとします

_.parent{
    width: 300px;
}

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

JS

モバイルデバイスで、しない本当に持っている_ 幅を設定する、特に_300px_を超えるものを持つ贅沢。パーセンテージを使用しても、親要素ではなくビューポートに関連するため、機能しません。 JSを使用できます、この場合はjQueryでこれを実現しますfunctionを見てみましょう。は常に括弧の幅を設定します tは与えられた瞬間に:

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

css:

_.fixed{
    position:fixed;
}
_

CodePenで表示

動的な幅

それはうまくできていますが、ユーザーがまだページにいる間にウィンドウの幅が変更された場合はどうなりますか?親は幅を調整できますが、子は関数が設定した幅にとどまります。 jQuery'sresize()イベントリスナーでこれを修正できます。最初に、作成した関数を2つに分割する必要があります。

_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はビューポートにのみ関連するため、親の幅を継承できません。

これを解決するために、jQueryをあまり使用しなかったJSマジックを使用してこれを実現する必要があります。

場合によっては、さまざまな幅のデバイスをスケーリングする動的なアプローチが必要です。繰り返しになりますが、JSアプローチを採用しました。

32
Philll_t

width:inheritを使用できます。これにより、親のリッスンが行われます。私はそれをテストし、Firefoxで動作します。

12
egon12

静的オブジェクトが親からそのパーセント幅を受け取っているため、幅が変化しています。オブジェクトを固定に設定すると、オブジェクトはフローされなくなり、サイズが変更されます。

ナビゲーションメニューに単独でサイズを設定する必要があり、要素が親から幅を取得することを期待しないでください。

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

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

5
Michael Rader

こんにちは、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();
 });
4
khoekman

これは、デフォルトのマージンまたは<html>または<body>要素のパディングが原因である可能性があります。静的な場合、<body>の幅に基づいてサイズが変更されますが、position:fixedに変更されると、ビューポートに合わせてサイズが変更されます。

そのため、デフォルトのマージン/パディングを削除すると、問題が解決するはずです(私の経験ではbody { margin:0; }が修正)、サイズが修正されたときにサイズを変更する必要があります(width:calc(n% - 5px);など)。

3
Zach Saucier

誰かがすでに示唆しているように、javascriptを使用することが最良の解決策です。

JQueryなし。

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

// get parent-element width when page is fully loaded
// and change fixed-element width accordingly
window.addEventListener('load', changeFixedElementWidth);

// get parent-element width when window is resized
// and change fixed-element width accordingly
window.addEventListener('resize', changeFixedElementWidth);

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

回避策は次のとおりです:left:8px; right:0; width:18%;ナビゲーションのCSSで。しかし、最善の解決策ではありません。

0
Simke Nys