Элемент положения зафиксирован вертикально, абсолютно горизонтально - PullRequest
67 голосов
/ 21 июля 2010

Вот что я пытаюсь сделать:

Мне нужна кнопка, которая расположена на определенном расстоянии от правой стороны div, и всегда на том же расстоянии от стороны div, независимо от того,размер области просмотра, но будет прокручиваться вместе с окном.

Таким образом, это все время x пикселей с правой стороны от div, но y пикселей от верхней части порта просмотра всегда.

Возможно ли это?

Ответы [ 3 ]

44 голосов
/ 22 июля 2010

Положение фиксированного элемента по горизонтали от другого элемента

( Примечание об отказе от ответственности : Предлагаемое здесь решение не является технически " абсолютно горизонтально "как указано в названии вопроса, но он достиг того, чего первоначально хотел OP, элемент с фиксированной позицией должен быть на расстоянии 'X' от правого края другого, но с фиксированной вертикальной прокруткой.)

Мне нравятся эти типывызовы css.В качестве доказательства концепции, да, вы можете получить то, что вы желаете .Возможно, вам придется настроить некоторые вещи для своих нужд, но вот некоторые примеры HTML и CSS, которые прошли FireFox, IE8 и IE7 (IE6, конечно, не имеет position: fixed).

HTML:

<body>
  <div class="inflow">
    <div class="positioner"><!-- may not be needed: see notes below-->
      <div class="fixed"></div>
    </div>
  </div>
</body>

CSS (границы и все размеры для демонстрации):

div.inflow {
  width: 200px; 
  height: 1000px; 
  border: 1px solid blue; 
  float: right; 
  position: relative; 
  margin-right: 100px;
}
div.positioner {position: absolute; right: 0;} /*may not be needed: see below*/
div.fixed {
  width: 80px; 
  border: 1px solid red; 
  height: 100px; 
  position: fixed; 
  top: 60px; 
  margin-left: 15px;
}

Ключ состоит в том, чтобы вообще не устанавливать left или right длягоризонтальный на div.fixed, но используйте два div обёртки, чтобы установить горизонтальное положение.div.positioner - это , а не , если div.inflow является фиксированной шириной, поскольку для левого поля div.fixed можно указать известную ширину контейнера.Однако, если вы хотите, чтобы контейнер имел процентную ширину, вам понадобится div.positioner, чтобы сначала толкнуть div.fixed к правой стороне div.inflow.

Редактировать: В качестве интересного примечания, когда я установил overflow: hidden (нужно это сделать) на div.inflow, он не имел никакого эффекта на фиксированной позиции div, находящейся за пределами границ другого.По-видимому, фиксированной позиции достаточно, чтобы вывести ее из контекста содержимого div для overflow.

10 голосов
/ 07 августа 2014

После долгих копаний (включая этот пост) я не смог найти решение, которое мне понравилось.Принятый ответ здесь не делает того, что читал заголовок OP, и лучшие решения, которые я мог найти, по общему признанию, привели к нервным элементам.Затем он ударил меня: пусть элемент будет «зафиксирован», обнаружит, когда происходит горизонтальная прокрутка, и переключит его на абсолютное позиционирование.Вот результирующий код:

Просмотреть его как кодовое перо.

HTML

  <div class="blue">
    <div class="red">
    </div>
  </div>

CSS

/* Styling */
.blue, .red {
  border-style: dashed;
  border-width: 2px;
  padding: 2px;
  margin-bottom: 2px;
}

/* This will be out "vertical-fixed" element */
.red {
  border-color: red;
  height: 120px;
  position: fixed;
  width: 500px;
}

/* Container so we can see when we scroll */
.blue {
  border-color: blue;
  width: 50%;
  display: inline-block;
  height: 800px;
}

JavaScript

$(function () {
  var $document = $(document),
      left = 0,
      scrollTimer = 0;

  // Detect horizontal scroll start and stop.
  $document.on("scroll", function () {
    var docLeft = $document.scrollLeft();
    if(left !== docLeft) {
      var self = this, args = arguments;
      if(!scrollTimer) {
        // We've not yet (re)started the timer: It's the beginning of scrolling.
        startHScroll.apply(self, args);
      }
      window.clearTimeout(scrollTimer);
      scrollTimer = window.setTimeout(function () {
        scrollTimer = 0;
        // Our timer was never stopped: We've finished scrolling.
        stopHScroll.apply(self, args);
      }, 100);
      left = docLeft;
    }
  });

  // Horizontal scroll started - Make div's absolutely positioned.
  function startHScroll () {
    console.log("Scroll Start");
    $(".red")
    // Clear out any left-positioning set by stopHScroll.
    .css("left","")
    .each(function () {
      var $this = $(this),
          pos = $this.offset();
      // Preserve our current vertical position...
      $this.css("top", pos.top)
    })
    // ...before making it absolutely positioned.
    .css("position", "absolute");
  }

  // Horizontal scroll stopped - Make div's float again.
  function stopHScroll () {
    var leftScroll = $(window).scrollLeft();
    console.log("Scroll Stop");
    $(".red")
    // Clear out any top-positioning set by startHScroll.
    .css("top","")
    .each(function () {
      var $this = $(this), 
        pos = $this.position();
      // Preserve our current horizontal position, munus the scroll position...
      $this.css("left", pos.left-leftScroll);
    })
    // ...before making it fixed positioned.
    .css("position", "fixed");
  }
});
7 голосов
/ 27 июня 2012

Я прибыл сюда в поисках решения аналогичной проблемы, которая заключалась в том, чтобы иметь нижний колонтитул, который охватывает ширину окна и находится ниже содержимого (переменной высоты и ширины).Другими словами, создайте впечатление, что нижний колонтитул «зафиксирован» относительно его горизонтального положения, но сохраняет свое обычное положение в потоке документов относительно его вертикального положения.В моем случае текст нижнего колонтитула был выровнен по правому краю, поэтому мне удалось динамически настроить ширину нижнего колонтитула.Вот что я придумал:

HTML

<div id="footer-outer">
<div id="footer">
    Footer text.
</div><!-- end footer -->
</div><!-- end footer-outer -->

CSS

#footer-outer
{
    width: 100%;
}
#footer
{
    text-align: right;
    background-color: blue;
    /* various style attributes, not important for the example */
}

CoffeeScript / JavaScript

(с использованием prototype.js).

class Footer
document.observe 'dom:loaded', ->
    Footer.width = $('footer-outer').getDimensions().width
Event.observe window, 'scroll', ->
    x = document.viewport.getScrollOffsets().left
    $('footer-outer').setStyle( {'width': (Footer.width + x) + "px"} )

, который компилируется в:

Footer = (function() {

  function Footer() {}

  return Footer;

})();

document.observe('dom:loaded', function() {
  return Footer.width = $('footer-outer').getDimensions().width;
});

Event.observe(window, 'scroll', function() {
  var x;
  x = document.viewport.getScrollOffsets().left;
  return $('footer-outer').setStyle({
    'width': (Footer.width + x) + "px"
  });
});

Это хорошо работает в FireFox и довольно хорошо в Chrome (немного нервно);Я не пробовал другие браузеры.

Я также хотел, чтобы любое свободное пространство под нижним колонтитулом было другого цвета, поэтому я добавил это footer-stretch div:

HTML

...
</div><!-- end footer -->
<div id="footer-stretch"></div>
</div><!-- end footer-outer -->

CSS

#footer-outer
{
    height: 100%;
}
#footer-stretch
{
    height: 100%;
    background-color: #2A2A2A;
}

Обратите внимание, что для работы div # footer-stretch все родительские элементы вплоть до элемента body (и, возможно, элемент html - не уверен) должны иметь фиксированную высоту(в этом случае высота = 100%).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...