Naprawiono pozycję, ale względem kontenera

639

Próbuję to naprawić, divaby zawsze przylegał do górnej części ekranu, używając:

position: fixed;
top: 0px;
right: 0px;

Jest jednak w divśrodku wyśrodkowanego pojemnika. Kiedy position:fixedgo używam , naprawia divwzględne okno przeglądarki, na przykład po prawej stronie przeglądarki. Zamiast tego powinien być ustalony względem kontenera.

Wiem, że position:absolutemożna tego użyć do naprawy elementu względem div, ale kiedy przewijasz stronę, element znika i nie przykleja się do góry, jak w przypadku position:fixed.

Czy istnieje jakiś hack lub obejście tego problemu?

Zach Nicodemous
źródło
„Tether to niskopoziomowa biblioteka interfejsu użytkownika, której można używać do pozycjonowania dowolnego elementu na stronie obok dowolnego innego elementu.” github.com/shipshapecode/tether + Demos / Docs at tether.io
Kai Noack

Odpowiedzi:

408

Krótka odpowiedź: nie. (Jest to teraz możliwe dzięki transformacji CSS. Zobacz edycję poniżej)

Długa odpowiedź: Problem z użyciem „ustalonego” pozycjonowania polega na tym, że usuwa element z przepływu . dlatego nie można go zmienić względem jego rodzica, ponieważ jest tak, jakby go nie miał. Jeśli jednak kontener ma stałą, znaną szerokość, możesz użyć czegoś takiego:

#fixedContainer {
  position: fixed;
  width: 600px;
  height: 200px;
  left: 50%;
  top: 0%;
  margin-left: -300px; /*half the width*/
}

http://jsfiddle.net/HFjU6/1/

Edytuj (03/2015):

To są nieaktualne informacje. Teraz można wyśrodkować zawartość o dynamicznym rozmiarze (poziomo i pionowo) za pomocą magii transformacji CSS3. Ta sama zasada obowiązuje, ale zamiast używać marginesu do przesunięcia kontenera, możesz użyć translateX(-50%). Nie działa to z powyższą sztuczką na marginesie, ponieważ nie wiesz, ile to przesunąć, chyba że szerokość jest stała i nie możesz użyć wartości względnych (jak 50%), ponieważ będzie względna względem elementu nadrzędnego, a nie elementu, który jest dotyczyło. transformzachowuje się inaczej. Jego wartości odnoszą się do elementu, do którego są stosowane. Zatem 50%dla transformśrednich oznacza połowę szerokości elementu, natomiast 50%dla marginesu jest połowa szerokości rodzica. To jest rozwiązanie IE9 +

Korzystając z kodu podobnego do powyższego przykładu, odtworzyłem ten sam scenariusz, używając całkowicie dynamicznej szerokości i wysokości:

.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    left: 50%;
    top: 0%;
    transform: translateX(-50%);
}

Jeśli chcesz, aby był wyśrodkowany, możesz to również zrobić:

.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

Dema:

jsFiddle: Wyśrodkowany tylko poziomo
jsFiddle: Wyśrodkowany zarówno poziomo jak i pionowo
Oryginalne uznanie dla użytkownika aaronk6 za wskazanie mi go w tej odpowiedzi

Joseph Marikle
źródło
Pracował dla mnie pięknie. Chociaż potrzebowałem mojego z lewej i już wyśrodkowanego, nie naprawionego div, musiałem tylko zmniejszyć lewy margines, aż zostanie wyrównany. Nie pozostaje wyrównany bez względu na szerokość okien. Dzięki. +1
Iain M Norman
9
@Joseph jakiś pomysł, dlaczego position:fixedbez podania toplub left czasem działa? Niektóre przeglądarki wydają się domyślnie ustawiać element w miejscu, w którym normalnie by się znajdował, gdyby miał normalne ustawienie. stackoverflow.com/questions/8712047/…
Flash
2
a co bez stałej wysokości i szerokości? W moim przypadku nie podałem żadnej szerokości sygnału do żadnego kontenera, nawet do znacznika body. Jakie rozwiązanie powiesz mi do zrobienia.
mfq
1
@mfq Niestety ta metoda w ogóle nie zadziała bez znanej wysokości i szerokości. To, co wybierzesz, będzie w dużej mierze zależeć od tego, co próbujesz wyśrodkować. Jeśli jest to obraz, użyj go jako tła kontenera 100% x 100%. Jeśli jest to rzeczywisty element, który jest całkowicie dynamiczny, prawdopodobnie będziesz musiał zbadać za pomocą rozwiązania javascript, aby uzyskać wymiary.
Joseph Marikle
2
Odkryłem, że dodanie left:inheritdo elementu stałej pozycji może zmusić przeglądarkę do przestrzegania przesunięcia elementu nadrzędnego.
Willster
180

W rzeczywistości jest to możliwe, a przyjęta odpowiedź dotyczy tylko centralizacji, co jest dość proste. Poza tym naprawdę nie musisz używać JavaScript.

To pozwoli ci poradzić sobie z każdym scenariuszem:

Ustaw wszystko tak, jak gdybyś chciał ustawić: absolut w pozycji: względny kontener, a następnie utwórz nowy div div stałej pozycji za pomocą position: absolute, ale nie ustawiaj jego górnych i lewych właściwości. Zostanie to naprawione w dowolnym miejscu względem kontenera.

Na przykład:

/* Main site body */
.wrapper {
    width: 940px;
    margin: 0 auto;
    position: relative; /* Ensure absolute positioned child elements are relative to this*/
}

/* Absolute positioned wrapper for the element you want to fix position */
.fixed-wrapper {
    width: 220px;
    position: absolute;
    top: 0;
    left: -240px; /* Move this out to the left of the site body, leaving a 20px gutter */
}

/* The element you want to fix the position of */
.fixed {
    width: 220px;
    position: fixed;
    /* Do not set top / left! */
}
<div class="wrapper">
    <div class="fixed-wrapper">
        <div class="fixed">
            Content in here will be fixed position, but 240px to the left of the site body.
        </div>
    </div>
</div>

Niestety, miałem nadzieję, że ten wątek rozwiąże mój problem z Androidem WebKit wyświetlającym piksele rozmycia pola jako marginesy na elementach o stałej pozycji, ale wygląda na to, że to błąd.
W każdym razie mam nadzieję, że to pomoże!

Graeme Blackwood
źródło
1
Niezupełnie ŻADNY scenariusz, ale to dobry początek. Jeśli pod .wrapper jest dużo miejsca, wtedy twoje .fixed-wrapper skończy się na dole elementu nadrzędnego, ale twój .fixed element będzie nadal wypływał z obu pojemników i do dowolnej zawartości poniżej. Tak jak powiedziałem, to dobry początek, nie idealny, ale nie rozumiem, jak można to osiągnąć bez niektórych js.
o_O,
4
Nie działa to jednak dobrze w przypadku płynnego projektowania.
Zuhaib Ali
3
Próbowałem to zrobić, ale kiedy przewijam w dół, nagłówek, który zastosowałem naprawiony (z absolutem nadrzędnym, do którego rodzic był względny) nie poruszał się podczas przewijania.
Mirage
Działa to dla mnie z prawym górnym divem w Chromium i Firefox, z tym wyjątkiem, że pionowe pozycje stałego diva były różne (na Chromium było na szczycie diva nadrzędnego, na Firefoxie było w środku).
Damien
2
To była dla mnie odpowiedź! Dzięki @Graeme Blackwood
Tabu.Net
136

Tak, zgodnie ze specyfikacją istnieje sposób.

Chociaż zgadzam się, że Graeme Blackwood powinna być przyjętą odpowiedzią, ponieważ praktycznie rozwiązuje problem, należy zauważyć, że element stały może być umieszczony względem swojego pojemnika.

Zauważyłem przypadkowo, że przy składaniu wniosku

-webkit-transform: translateZ(0);

względem ciała, utworzyło względem niego stałe dziecko (zamiast rzutni). Moje stałe elementy lefti topwłaściwości były teraz względne w stosunku do kontenera.

Zrobiłem więc trochę badań i odkryłem, że problem został już omówiony przez Erica Meyera i nawet jeśli wydawało się to „sztuczką”, okazuje się, że jest to część specyfikacji:

W przypadku elementów, których układem rządzi model pudełkowy CSS, każda wartość inna niż żadna dla transformacji powoduje utworzenie zarówno kontekstu stosu, jak i bloku zawierającego. Obiekt działa jako blok zawierający dla ustalonych pozycji potomków.

http://www.w3.org/TR/css3-transforms/

Tak więc, jeśli zastosujesz transformację do elementu nadrzędnego, stanie się on blokiem zawierającym.

Ale...

Problem polega na tym, że implementacja wydaje się błędna / kreatywna, ponieważ elementy również przestają zachowywać się jak ustalone (nawet jeśli ten bit nie wydaje się być częścią specyfikacji).

To samo zachowanie można znaleźć w Safari, Chrome i Firefox, ale nie w IE11 (gdzie stały element nadal pozostanie stały).

Inną interesującą (nieudokumentowaną) rzeczą jest to, że gdy element stały jest zawarty w przekształconym elemencie, a jego właściwości topi leftbędą teraz powiązane z kontenerem, z poszanowaniem box-sizingwłaściwości, kontekst przewijania będzie rozciągał się poza krawędź elementu, jak pole -Rozmiar został ustawiony na border-box. Dla niektórych twórców może to być zabawką :)

TEST

Francesco Frapporti
źródło
4
Umożliwiło mi to utworzenie tabeli ze stałymi nagłówkami wewnątrz kontenera
Zach Saucier,
Fajnie, to działa dla mnie w Chrome. Wszelkie pomysły na osiągnięcie tego samego w IE? Próbowałem użyć translateZ, ale nie w żadnej wersji IE.
Anish Patel
To samo .. czy ktoś wie jak to zrobić w IE? to rodzaj bólu w wykrywaniu przeglądarki, a następnie systematycznie pokazywać lub nie pokazywać left:(biorąc pod uwagę, że to popsuło)
Tallboy
Po prostu spełniam przeciwny warunek, który muszę naprawić we względnym kontenerze, ale zmieniony przez właściwość transformacji. Twoja odpowiedź jest bardzo pomocna, dziękuję!
mitarcher
8
@Francesco Frapporti wydaje się, że to już nie działa ... w najnowszej wersji Chrome (wersja 42.0.2311.90) :(
jjenzz
60

Odpowiedź brzmi tak, o ile nie ustawisz left: 0lub right: 0po ustawieniu pozycji div na stałą.

http://jsfiddle.net/T2PL5/85/

Sprawdź div paska bocznego. Jest ustalony, ale związany z elementem nadrzędnym, a nie z punktem widoku okna.

body { background: #ccc; }

.wrapper {
    margin: 0 auto;
    height: 1400px;
    width: 650px;
    background: green;
}

.sidebar {
    background-color: #ddd;
    float: left;
    width: 300px;
    height: 100px;
    position: fixed;
}

.main {
    float: right;
    background-color: yellow;
    width: 300px;
    height: 1400px;
}

<div class="wrapper">wrapper
    <div class="sidebar">sidebar</div>
    <div class="main">main</div>
</div>
Shadow_boi
źródło
12
Czy jest jakiś powód, dla którego nie ma więcej głosów pozytywnych? Wydaje mi się to najbardziej oczywistym rozwiązaniem.
Śledzenie
Co z kompatybilnością między przeglądarkami. Czy ktoś z was to sprawdził?
Alexandre Bourlier,
3
Jest to poprawne, ale tylko w przypadku „pozycjonowania” stałego elementu. Nie będzie szanować szerokości pojemnika ani w żaden sposób zmieniać jego rozmiaru. Na przykład, jeśli masz owijarkę płynów o maksymalnej szerokości: 1000 pikseli; margines: auto; to nie zadziała. Jeśli wszystko może mieć stałą szerokość, to tak, rozwiąże to twój problem.
Rhys
3
@AlexandreBourlier Tak, to działało dobrze dla mnie przynajmniej dla stałego elementu w Chrome, Firefox i IE11.
Jason Frank,
Działał idealnie. Musiałem dodać margines lewy: X%, aby przenieść element na prawo od kontenera
Anand
45

position: stickyto nowy sposób pozycjonowania elementów, który jest koncepcyjnie podobny do position: fixed. Różnica polega na tym, że element z position: stickyzachowuje się jak position: relativew swoim obiekcie nadrzędnym, dopóki dany próg przesunięcia nie zostanie spełniony w rzutni.

W Chrome 56 (obecnie beta w grudniu 2016 r., Stabilny w styczniu 2017 r.) Pozycja: sticky jest teraz z powrotem.

https://developers.google.com/web/updates/2016/12/position-sticky

Więcej szczegółów znajdziesz w Trzymaj swoje lądowania! pozycja: lepkie ziemie w WebKit .

PoseLab
źródło
To sprawia, że ​​życie jest o wiele łatwiejsze, jedynym problemem jest to, że lepki nie jest obsługiwany w Internet Explorerze lub Edge 15 i wcześniejszych wersjach.
ricks
1
position:stickyjest super. Obsługiwane przez wszystkie przeglądarki oprócz IE caniuse.com/#feat=css-sticky
Yarin
lol, tak stary interfejs API, a ty oszczędzasz mi dzień ... używam go do stałych kolumn do elastycznych tabel.
Vladislav Gritsenko
1
„w obrębie rodzica” - czy można pozostać lepkim elementem na górze, jeśli przewijanie w górę rodzica stanie się niewidoczne?
Fikret
28

ROZWIĄZANIE 2019: Możesz korzystać z position: stickynieruchomości.

Oto przykład CODEPEN pokazujący użycie, a także, czym się różniposition: fixed .

Jak to działa wyjaśniono poniżej:

  1. Element o lepkiej pozycji jest pozycjonowany na podstawie pozycji przewijania użytkownika. Zasadniczo działa tak, position: relativedopóki element nie zostanie przewinięty poza określone przesunięcie, w którym to przypadku zmieni się w pozycję: naprawiono. Po przewinięciu do tyłu powraca do poprzedniej (względnej) pozycji.

  2. Wpływa na przepływ innych elementów na stronie, tj. Zajmuje określoną przestrzeń na stronie (podobnie jak position: relative).

  3. Jeśli jest zdefiniowany w jakimś kontenerze, jest pozycjonowany względem tego kontenera. Jeśli pojemnik ma przepełnienie (przewijanie), w zależności od przesunięcia przewijania zmienia się w pozycję: naprawiono.

Więc jeśli chcesz osiągnąć ustaloną funkcjonalność, ale wewnątrz kontenera, użyj lepkiej.

Pransh Tiwari
źródło
Niezłe rozwiązanie. Jeszcze nie wiedziałem position: sticky. Bardzo pomogłem, dzięki!
dave0688
Właśnie miałem to opublikować. Dobra odpowiedź! lepka jest droga.
dkellner
18

Po prostu wyjmij górny i lewy styl ze stałej pozycji div. Oto przykład

<div id='body' style='height:200%; position: absolute; width: 100%; '>
    <div id='parent' style='display: block; margin: 0px auto; width: 200px;'>
        <div id='content' style='position: fixed;'>content</div>
    </div>
</div> 

#Content div będzie siedział wszędzie tam, gdzie siedzi div div, ale zostanie tam naprawiony.

Hobberwickey
źródło
3
Dlaczego minus? Działa to doskonale do mocowania elementu w dowolnym miejscu w przepływie DOM. deadlykitten.com/tests/fixedPositionTest.php
hobberwickey
18

Stworzyłem tę wtyczkę jQuery, aby rozwiązać podobny problem, w którym miałem wyśrodkowany kontener (dane tabelaryczne), i chciałem, aby nagłówek był przymocowany do góry strony podczas przewijania listy, ale chciałem, żeby była zakotwiczona dane tabelaryczne, tak aby znajdowały się w dowolnym miejscu, w którym umieszczam kontener (wyśrodkowany, lewy, prawy), a także pozwalają mu przesuwać się w lewo i prawo ze stroną podczas przewijania w poziomie.

Oto link do tej wtyczki jQuery, która może rozwiązać ten problem:

https://github.com/bigspotteddog/ScrollToFixed

Opis tej wtyczki jest następujący:

Ta wtyczka służy do mocowania elementów na górze strony, jeśli element przewinąłby się poza widok w pionie; pozwala jednak elementowi nadal przesuwać się w lewo lub w prawo za pomocą przewijania w poziomie.

Biorąc pod uwagę opcję marginTop, element przestanie się poruszać pionowo w górę, gdy pionowy zwój osiągnie pozycję docelową; ale element nadal będzie się przesuwał w poziomie, gdy strona będzie przewijana w lewo lub w prawo. Po przewinięciu strony w dół minęła pozycję docelową, element zostanie przywrócony do pierwotnej pozycji na stronie.

Ta wtyczka została przetestowana w Firefoksie 3/4, Google Chrome 10/11, Safari 5 i Internet Explorer 8/9.

Zastosowanie w konkretnym przypadku:

<script src="scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery-scrolltofixed-min.js" type="text/javascript"></script>

$(document).ready(function() {
    $('#mydiv').scrollToFixed();
});
Bigspotteddog
źródło
12

Musiałem to zrobić z reklamą, którą mój klient chciał usiąść poza obszarem zawartości. Po prostu zrobiłem następujące i działało to jak urok!

<div id="content" style="position:relative; width:750px; margin:0 auto;">
  <div id="leftOutsideAd" style="position:absolute; top:0; left:-150px;">
    <a href="#" style="position:fixed;"><img src="###" /></a>
  </div>
</div>
Eric K.
źródło
Moja reklama miała 140 pikseli szerokości, więc przesunąłem ją o 150 pikseli w lewo, aby uzyskać trochę prawego marginesu względem krawędzi ramki witryny.
Eric K
7

Dwa elementy HTML i czysty CSS (nowoczesne przeglądarki)

Zobacz ten przykład jsFiddle. Zmień rozmiar i zobacz, w jaki sposób elementy stałe poruszają się nawet z elementami pływającymi, w których się znajdują. Użyj paska przewijania znajdującego się najbardziej na środku, aby zobaczyć, jak przewijanie działa w witrynie (elementy stałe pozostają nieruchome).

Aż tu stwierdziły, jeden klucz nie wyznacza żadnych ustawień pozycyjnych na fixedelemencie (no top, right, bottomlub leftwartości).

Zamiast tego umieszczamy wszystkie stałe elementy (zwróć uwagę, jak ostatnie pudełko ma ich cztery) na początku w polu, z którego mają zostać ustawione, tak jak poniżej:

<div class="reference">
  <div class="fixed">Test</div>
  Some other content in.
</div>

Następnie używamy margin-topi margin-left„przenosimy” je w stosunku do kontenera, podobnie jak ten CSS:

.fixed {
    position: fixed;
    margin-top: 200px; /* Push/pull it up/down */
    margin-left: 200px; /* Push/pull it right/left */
}

Zauważ, że ponieważ fixedelementy ignorują wszystkie inne elementy układu, końcowy pojemnik w naszym skrzypcach może mieć wiele fixedelementów i nadal mieć wszystkie te elementy związane z lewym górnym rogiem. Jest to jednak prawdą tylko wtedy, gdy wszystkie zostaną umieszczone najpierw w kontenerze, ponieważ to skrzypce porównawcze pokazuje, że po rozproszeniu w zawartości kontenera pozycjonowanie staje się niewiarygodne .

Bez względu na to , czy opakowanie jest ustawione statycznie , względnie czy bezwzględnie , nie ma to znaczenia.

ScottS
źródło
3

Możesz wypróbować moją wtyczkę jQuery, FixTo .

Stosowanie:

$('#mydiv').fixTo('#centeredContainer');
Burak
źródło
2

Innym dziwnym rozwiązaniem, które pozwala osiągnąć względną stałą pozycję, jest przekształcenie kontenera w ramkę iframe, w ten sposób ustalony element można przymocować do rzutni kontenera, a nie całej strony.

Beto Aveiga
źródło
2

W czystym CSS nie da się tego zrobić; przynajmniej nie mam. Jednak możesz to zrobić w jQuery bardzo prosto. Wyjaśnię mój problem i przy niewielkiej zmianie możesz go użyć.

Na początek chciałem, aby mój element miał stałą górę (od góry okna) i lewy komponent, który odziedziczył po elemencie nadrzędnym (ponieważ element nadrzędny jest wyśrodkowany). Aby ustawić lewy komponent, wystarczy umieścić element w elemencie nadrzędnym i ustawić position:relativeelement nadrzędny.

Następnie musisz wiedzieć, ile wynosi od góry twój element, gdy pasek przewijania znajduje się na górze (przewijane zero); znów są dwie opcje. Po pierwsze, jest statyczny (pewna liczba) lub musisz go odczytać z elementu nadrzędnego.

W moim przypadku jest to 150 pikseli od góry. Więc kiedy zobaczysz 150, to ile wynosi element od góry, gdy nie przewinęliśmy.

CSS

#parent-element{position:relative;}
#promo{position:absolute;}

jQuery

$(document).ready(function() { //This check window scroll bar location on start
    wtop=parseInt($(window).scrollTop());
    $("#promo").css('top',150+wtop+'px');

});
$(window).scroll(function () { //This is when the window is scrolling
    wtop=parseInt($(window).scrollTop());
    $("#promo").css('top',150+wtop+'px');
});
Pan Br
źródło
Problem polega na tym, że dany div miga podczas przewijania.
vvohra87
Prawdopodobnie dlatego, że przewijanie jest zbyt duże lub zbyt szybkie. Nie miałem tego problemu tbh, ale mogę zasugerować, abyś spróbował użyć globalnego „blokera”, który byłby odświeżany na przykład co 10 ms lub jakiś czas i ustawiany na wartość blokowania za każdym razem, gdy wprowadzasz jakąś zmianę wysokości. Oczywiście musisz dodać warunek do zdarzenia .scroll sprawdzającego, czy w tym okresie (10ms) przewinąłeś już div. Powtarzam, że nie próbowałem, ale wierzę, że to może zadziałać :) W ten sposób możesz powstrzymać div przed zbyt dużą zmianą jego pozycji, aby komputer nie mógł właściwie podążać, i wystarczająco, aby ludzkie oko to zobaczyło.
Pan Br
Dałem już odpowiedź +1 kolega;) Ból związany z dołączeniem globalnej metody zapętlenia to naprawdę wydajność. Uzyskiwanie czegoś takiego ładnie działającego na starszych komputerach i tabletach jest bolesne. Wielokrotnie młodszy programista w pracy pisał „var x” w takiej metodzie, co powoduje niepotrzebne wycieki pamięci, jeśli strona pozostanie otwarta zbyt długo: P Ale tak, twoja sugestia wydaje się jedyną realną opcją.
vvohra87
Masz punkt w globalnych pętlach; nie jest dobre, zgadzam się. Po prostu lubię myśleć o tego rodzaju problemach, dlatego napisałem kolejną sugestię :) Tbh, teraz wyglądając trochę lepiej, unikałbym tego xD Mam teraz inne rozwiązanie. Co powiesz na temat ustawiania setTimeout () dla zdarzenia przewijania, które wywołuje func. co powoduje ruch div. używasz również globalnego blokera, który jest ustawiony na wartość true podczas oczekiwania na limit czasu, a po wywołaniu limitu czasu zwraca bloker na false, co umożliwia kolejne wywołanie po pewnym czasie ... w ten sposób nie użyjesz pętli globalnej ale nadal mają kontrolę nad częstotliwością ruchu div.
Pan Br
Jest bardziej elegancki, ale trudno mi go zaakceptować. Tego właśnie oczekuję od html i css specyfikacji tbh. Nienawidzę faktu, że js jest zaangażowany w pierwszej kolejności!
vvohra87
1

Jest to łatwe (zgodnie z HTML poniżej)

Sztuką jest NIE używać góry lub lewej strony elementu (div) z „position: fixed;”. Jeśli nie zostaną one określone, element „stała treść” pojawi się WZGLĘDNY dla elementu otaczającego (div z „position: relative;”) ZAMIAST względem okna przeglądarki !!!

<div id="divTermsOfUse" style="width:870px; z-index: 20; overflow:auto;">
    <div id="divCloser" style="position:relative; left: 852px;">
        <div style="position:fixed; z-index:22;">
            <a href="javascript:hideDiv('divTermsOfUse');">
                <span style="font-size:18pt; font-weight:bold;">X</span>
            </a>
        </div>
    </div>
    <div>  <!-- container for... -->
         lots of Text To Be Scrolled vertically...
         bhah! blah! blah!
    </div>
</div>

Powyżej pozwoliło mi zlokalizować zamykający przycisk „X” u góry dużej części tekstu w div z pionowym przewijaniem. „X” siedzi na swoim miejscu (nie porusza się z przewijanym tekstem, a mimo to przesuwa się w lewo lub w prawo z otaczającym kontenerem div, gdy użytkownik zmienia rozmiar okna przeglądarki! W ten sposób jest „ustalony” w pionie, ale ustawiony względem element zamykający poziomo!

Zanim zacząłem działać, „X” przewijał się w górę i poza zasięgiem wzroku, gdy przewijałem treść tekstu w dół.

Przepraszamy za niedostarczenie funkcji javascript hideDiv (), ale niepotrzebnie wydłużyłaby ten post. Zdecydowałem się na jak najkrótsze.

Bruce Allen
źródło
Solidne rozwiązanie dla wielu przeglądarek, działa w IE8 jak urok.
dmi3y
1

Stworzyłem jsfiddle, aby pokazać, jak to działa przy użyciu transformacji.

HTML

<div class="left">
    Content
</div>
<div class="right">
<div class="fixedContainer">
    X
</div>
    Side bar
</div>

CSS

body {
  margin: 0;
}
.left {
  width: 77%;
  background: teal;
  height: 2000px;
}
.right {
  width: 23%;
  background: yellow;
  height: 100vh;
  position: fixed;
  right: 0;
  top: 0;
}
.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    //right: 0;
    top: 0%;
    transform: translateX(-100px);
}

jQuery

$('.fixedContainer').on('click', function() {
    $('.right').animate({'width': '0px'});
  $('.left').animate({'width': '100%'});
});

https://jsfiddle.net/bx6ktwnn/1/

Wen
źródło
1

Mam ten sam problem, jeden z członków naszego zespołu daje mi rozwiązanie. Aby umożliwić pozycję div div fix i w stosunku do innych div, naszym rozwiązaniem jest użycie kontenera ojca owijającego div div i przewijania div.

<div class="container">
  <div class="scroll"></div>
  <div class="fix"></div>
</div>

css

.container {
  position: relative;
  flex:1;
  display:flex;
}

.fix {
  prosition:absolute;
}
Jay0Lu
źródło
1
/* html */

/* this div exists purely for the purpose of positioning the fixed div it contains */
<div class="fix-my-fixed-div-to-its-parent-not-the-body">

     <div class="im-fixed-within-my-container-div-zone">
          my fixed content
     </div>

</div>



/* css */

/* wraps fixed div to get desired fixed outcome */
.fix-my-fixed-div-to-its-parent-not-the-body 
{
    float: right;
}

.im-fixed-within-my-container-div-zone
{
    position: fixed;
    transform: translate(-100%);
}
Carol McKay
źródło
1

Tak, jest to możliwe, o ile nie ustawisz pozycji ( toplub leftitp.) Swojego fixedelementu (nadal możesz jednak użyć margindo ustawienia pozycji względnej). Simon Bos napisał o tym jakiś czas temu .

Nie oczekuj jednak, że ustalony element będzie przewijał się wraz z nie ustalonymi krewnymi.

Zobacz demo tutaj .

Javarome
źródło
0

Zrobiłem coś takiego jakiś czas temu. Byłem całkiem nowy w JavaScript, więc jestem pewien, że możesz zrobić lepiej, ale oto punkt wyjścia:

function fixxedtext() {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        if (document.body.offsetWidth > 960) {
            var width = document.body.offsetWidth - 960;
            width = width / 2;
            document.getElementById("side").style.marginRight = width + "px";
        }
        if (document.body.offsetWidth < 960) {
            var width = 960 - document.body.offsetWidth;
            document.getElementById("side").style.marginRight = "-" + width + "px";
        }
    }
    else {
        if (window.innerWidth > 960) {
            var width = window.innerWidth - 960;
            width = width / 2;
            document.getElementById("side").style.marginRight = width + "px";
        }
        if (window.innerWidth < 960) {
            var width = 960 - window.innerWidth;
            document.getElementById("side").style.marginRight = "-" + width + "px";
        }
    }
    window.setTimeout("fixxedtext()", 2500)
}

Musisz ustawić szerokość, a następnie pobiera szerokość okna i zmienia margines co kilka sekund. Wiem, że jest ciężki, ale działa.

webLacky3rdClass
źródło
Jednym z problemów, które widzę w tym podejściu, jest to, że opiera się on na zegarze (2,5 sekundy) i w tym czasie, jeśli użytkownik zmieni rozmiar okna, jego poprawienie zajmie ten czas. To nie jest najlepsza rzecz, jeśli chodzi o wrażenia użytkownika. Ponadto, jeśli można temu zaradzić, spróbuj użyć detektorów zdarzeń zamiast timerów.
Joseph Marikle
Jak powiedziałem, jest to stary skrypt, jeden z moich pierwszych i nie musiałem go naprawiać. To nie jest najlepszy, ale może być dobrym punktem wyjścia.
webLacky3rdClass
0

Jest to możliwe, jeśli używasz JavaScript. W takim przypadku wtyczka jQuery Sticky-Kit :

Paz Aricha
źródło
0

Mój projekt to .NET ASP Core 2 MVC Angular 4 szablon z Bootstrap 4. Dodanie „lepkiego” do głównego komponentu HTML (tj. App.component.html) w pierwszym rzędzie działało w następujący sposób:

<div class='row sticky-top'>
    <div class='col-sm-12'>
        <nav-menu-top></nav-menu-top>
    </div>
</div>
<div class="row">
    <div class='col-sm-3'>
        <nav-menu></nav-menu>
    </div>
    <div class='col-sm-9 body-content'>
        <router-outlet></router-outlet>
    </div>
</div>

Czy to konwencja, czy też uprościłem to?

Adam Cox
źródło
0

Kiedy używasz position:fixedreguły CSS i próbujesz zastosować top/ left/ right/ bottomustaw element względem okna.

Obejściem tego problemu jest użycie marginwłaściwości zamiast top/ left/ right/bottom

Sunil Garg
źródło
-1

Sprawdź to:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body style="width: 1000px !important;margin-left: auto;margin-right: auto">
        <div style="width: 100px; height: 100px; background-color: #ccc; position:fixed;">
        </div>
        <div id="1" style="width: 100%; height: 600px; background-color: #800000">
        </div>
        <div id="2" style="width: 100%; height: 600px; background-color: #100000">
        </div>
        <div id="3" style="width: 100%; height: 600px; background-color: #400000">
        </div>
    </body>
</html>
Kunal
źródło
5
Nie sądzę, że osiąga to całkiem to, o co poprosił PO.
JasonWyatt,