Czy można obliczyć szerokość rzutni (vw) bez paska przewijania?

88

Jak wspomniano w tytule, czy można obliczyć vwbez pasków przewijania tylko w CSS?

Na przykład mój ekran ma szerokość 1920px. vwwraca 1920px, świetnie. Ale moja rzeczywista szerokość ciała to tylko coś podobnego 1903px.

Czy istnieje sposób na pobranie 1903pxwartości tylko za pomocą css (nie tylko dla bezpośrednich elementów potomnych body), czy też absolutnie potrzebuję do tego JavaScript?

Marten Zander
źródło
2
ale ... pasek przewijania nie jest uwzględniony w szerokości widoku !?
Danield,
@Danield przepraszam, zaktualizowałem moje pytanie
Marten Zander
Jeśli mówimy o jakiejś sztucznej scroll-bar, który można umieścić tam wtedy być może szukasz czegoś takiego: width: calc(100vw - scrollbarWidth)gdzie „scrollbarWidth” jest jakaś stała wartość jak 15px
Danield
@Danield Właściwie potrzebuję poprawki między przeglądarkami, w której mam zmienną szerokość każdego natywnego scrolera przeglądarki
Marten Zander
2
Obecnie pracuję nad stroną przy użyciu bootstrap 4 w Chrome v64 i% to szerokość wewnętrzna (bez paska przewijania), a vw to szerokość zewnętrzna (szerokość łącznie z paskiem przewijania) - dlatego nie mogę używać vw i podobnie jak OP nie robię nie rozumiem, dlaczego to się dzieje.
Eric_B

Odpowiedzi:

116

Jednym ze sposobów jest użycie funkcji Calc. O ile wiem, 100% to szerokość, w tym paski przewijania. Więc jeśli to zrobisz:

body {
  width: calc(100vw - (100vw - 100%));
}

Otrzymasz 100 vw minus szerokość paska przewijania.

Możesz to zrobić również z wysokością, jeśli chcesz, na przykład, kwadrat stanowiący 50% obszaru roboczego (minus 50% szerokości paska przewijania)

.box {
  width: calc(50vw - ((100vw - 100%)/2))
  height: 0
  padding-bottom: calc(50vw - ((100vw - 100%)/2))
}  
Mattias Ottosson
źródło
42
To niesamowite, ale niestety działa tylko wtedy, gdy wymiarowany element jest bezpośrednim dzieckiem bodylub elementem, który ma taką samą szerokość jak body(w przeciwnym razie 100%będzie odnosić się do niewłaściwej szerokości elementu). W takim przypadku możesz po prostu użyć procentów. Chyba że czegoś mi brakuje?
Nateowami
7
Nie jest OK w przypadkach, gdy uwzględnianie 100vw paska przewijania jest naprawdę problemem - to znaczy, gdy musisz umieścić blok 100vw w kontenerze o stałej szerokości.
pewnościąakey
56
Matematyka: 100vw - (100vw - 100%) = 100vw - 100vw + 100% = 100% czy coś mi brakuje?
Kamil Kiełczewski
4
Niestety nie zadziałałoby to dla elementu pozycjonowanego absolutnie, ponieważ 100% nie jest tam dostępne :(
Hrvoje Golcic
4
@TKoL W każdym przypadku, gdy jego rozwiązanie faktycznie rozwiązałoby problem, szerokość: 50% działałaby równie dobrze. Kamil Kiełczewski ma rację, to rozwiązanie jest bezużyteczne.
Eliezer Berlin
17

Robię to, dodając wiersz JavaScript, aby zdefiniować zmienną CSS po załadowaniu dokumentu:

document.documentElement.style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px");

następnie w CSS możesz użyć var(--scrollbar-width)dowolnych zmian potrzebnych dla różnych przeglądarek z lub bez pasków przewijania o różnych szerokościach. Można zrobić coś podobnego do poziomego paska przewijania, jeśli jest taka potrzeba, zastępując innerWidthz innerHeighti clientWidthz clientHeight.

user11990065
źródło
Dla mnie rozmiar, który ten zwraca, jest dwa razy większy niż potrzeba. Jakieś wskazówki? Daje mi 16 pikseli, ale wystarczyłoby 8 pikseli ...
Fabian Beyerlein
9

Zgodnie ze specyfikacją jednostki względnej długości rzutni nie uwzględniają pasków przewijania (i faktycznie zakładają, że nie istnieją).

Zatem niezależnie od zamierzonego zachowania nie możesz brać pod uwagę pasków przewijania podczas korzystania z tych jednostek.

Duch Madary
źródło
Ponownie, vwzgodnie ze specyfikacją, nie są świadomi istnienia żadnego paska przewijania. Nie możesz więc brać ich pod uwagę.
Madara's Ghost
1
Zgodnie ze specyfikacją, vw zmniejsza szerokość paska przewijania, JEŚLI przepełnienie nie jest ustawione na auto, wtedy działa jak „ukryte” dla wartości vw. Jeśli więc strona musi się przepełniać, ustaw ją na „przewijanie”. Za pomocą overflow-x i overflow-y wybierasz, który pasek przewijania ma być wyświetlany.
Kulvar
1
@Kulvar właśnie wypróbował to w chrome, ustawienie korpusu na overflow-y: scrollvs overflow-y: autonie wydaje się zmieniać obliczonej wartości dla jednostek VW. W szczególności mam coś ustawionego w mojej witrynie na 3.82vw, a szerokość mojego komputera to 1920px. Z przepełnieniem auto, 3,82vw = 73,344px, a potem próbowałem z przewijaniem przepełnienia, który również wyświetla 73,344px, bez zmian, kiedy powinien faktycznie wystawić 72,6946px, jeśli miałeś rację
TKoL
100% bierze pod uwagę paski przewijania, więc jeśli twój przypadek ma 100vw, jeśli możesz, zmień go na 100%
Jairo
3

Przeglądarki Webkit wykluczają paski przewijania, inne uwzględniają je w zwracanej szerokości. Może to oczywiście prowadzić do problemów: na przykład, jeśli masz dynamicznie generowaną treść z ajaxem, która dynamicznie dodaje wysokość, Safari może przełączyć się z układu na inny podczas wizualizacji strony ... Ok, nie zdarza się to często, ale jest coś być świadomym. Na urządzeniach mobilnych mniej problemów, ponieważ paski przewijania zwykle nie są wyświetlane.

To powiedziawszy, jeśli twój problem polega na obliczeniu dokładnie szerokości widocznego obszaru bez pasków przewijania we wszystkich przeglądarkach, o ile wiem, dobrą metodą jest to:

width = $('body').innerWidth();

mając wcześniej ustawione:

body {
    margin:0;
}
holden
źródło
2

vwJednostka nie ponosi overflow-yprzewijania pod uwagę, gdy overflow-yjest ustawiony auto.

Zmień to na, overflow-y: scroll;a vwjednostka będzie rzutnią z paskiem przewijania. Następnie możesz odjąć rozmiar paska przewijania od wartości vw za pomocą funkcji calc (). Możesz także zdefiniować szerokość paska przewijania, aby była niezależna od przeglądarki.

Jedyny minus do wzięcia pod uwagę. Jeśli treść mieści się na ekranie, pasek przewijania jest wyświetlany mimo to. Możliwym rozwiązaniem jest zmiana z autona scrollw javascript.

Ilario Engler
źródło
1
pan miał na myśli overflow-x?
Eliran Malka
2
To nie jest prawda. Jednostka vw zawiera pasek przewijania zoverflow-y: scroll;
NoSkill
0

Jedynym sposobem, w jaki udało mi się to zadziałać bez mieszania kodu z "calc", jest ustawienie rozmiaru elementu kontenera na 100vw; Dodanie owijki wokół kontenera dla overflow-x; Spowoduje to, że kontener będzie miał pełną szerokość, tak jak gdyby pasek przewijania znajdował się nad zawartością.

<!DOCTYPE html>
<html>
<head>
	<style type="text/css">
	html{ overflow-y: scroll; }
	html, body{ padding:0; margin: 0;}
	#wrapper{ overflow-x: hidden; }
	.row{ width: 100vw; }
	.row:after{ clear: both; content: ''; display: block; overflow: hidden; }
	.row-left{ background: blue; float: left; height: 40vh; width: 50vw; }
	.row-right{ background: red; float: right; height: 40vh; width: 50vw; }
	</style>
</head>
<body>

<div id="wrapper">
<div class="row">
	<div class="row-left"></div>
	<div class="row-right"></div>
</div>
</div>


</body>
</html>

SequenceDigitale.com
źródło
0

Gdyby przypadek był podobny do suwaka: Jak napisano w wielu odpowiedziach, szerokość 100% nie uwzględnia paska przewijania, podczas gdy 100vw tak. W przypadku posiadania wielu elementów, które muszą zająć szerokość okna i które są zagnieżdżone w kontenerze o już 100% szerokości okna (lub których naturalna szerokość bloku byłaby taka), możesz użyć:

  • Wyświetl flex na pojemnik
  • Flex: 0 0 100% na elementy potomne
Facundo Videla Peña
źródło
0

100vw = szerokość ekranu z paskiem przewijania 100% = szerokość ekranu bez paska przewijania

Podczas pomiaru szerokości ekranu zawsze lepiej jest używać funkcji calc (100% - 50px). Nawet w przeglądarkach Windows, w których pasek przewijania jest widoczny bezpośrednio, szerokość ekranu jest zwracana inaczej w porównaniu z przeglądarkami macOS.

Vidit Anjaria
źródło
-3

Najłatwiejszym sposobem jest ustawienie html & body na 100vw:

html, body{ width:100vw; overflow-x: hidden; overflow-y: auto; margin: 0; }

Jedynym problemem jest to, że skrajne prawe zostanie trochę przycięte, jeśli zostanie wyświetlony pasek przewijania.

gonnavis
źródło
-3

w moim przypadku mam ustawić div 100wh - 230px i napotkałem ten sam problem z dodatkową szerokością przewijania, co zrobiłem:

width: calc(100vw - (100vw - 100%) - 230px);
Omar Errabaany
źródło
-4

To nie jest moje rozwiązanie, ale pomaga mi tworzyć rozwijane menu o pełnej szerokości z wartością bezwzględną w elemencie względnym bez pełnego zakresu.

Powinniśmy uzyskać scroll z w css var in: root, a następnie go użyć.

:root{
 --scrollbar-width: calc(100vw - 100%);
}


div { margin-right: var(--scrollbar-width); }

https://codepen.io/superkoders/pen/NwWyee

Denis Savenko
źródło
2
Działa to tylko dlatego, że div znajduje się w katalogu głównym. Jeśli element DIV nie znajduje się w katalogu głównym, jest przerywany. Dzieje się tak, ponieważ kalkulator jest rozwiązywany, gdy występuje do niego odwołanie, względem selektora, do którego się odnosi, a nie tam, gdzie jest zdefiniowany. codepen.io/Pedr/pen/YorLPM
Undistraction