Подтвердить что ты не робот

Позиционный элемент фиксирован вертикально, абсолютный по горизонтали

Вот что я пытаюсь выполнить:

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

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

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

4b9b3361

Ответ 1

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

( Отказ от ответственности: Предлагаемое здесь решение технически не " абсолютное горизонтальное значение", как указано в названии вопроса, но достигло того, что первоначально требовалось 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.positioner требуется не, если div.inflow является фиксированной шириной, так как левое поле div.fixed может быть установлено на известную ширину контейнера. Однако, если вы хотите, чтобы контейнер имел процентную ширину, вам понадобится div.positioner, чтобы сначала нажать div.fixed на правую сторону div.inflow.

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

Ответ 2

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

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;
}

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

Ответ 3

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

Просмотрите его как Pen Pen.

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 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 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 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");
  }
});