symuluj rozmiar tła: okładka na <video> lub <img>

154

Jak mogę zasymulować funkcjonalność background-size:coverelementu HTML, takiego jak <video>lub <img>?

Chciałbym, żeby to działało

background-size: cover;
background-position: center center;
seron
źródło
1
okej, nigdy nie użyłem background-size: cover; ale spojrzałem na to online, więc co chcesz, to sposób na pełnoekranowy obraz / wideo, który zmienia rozmiar, gdy zmienia się rozmiar okna?
Lennart
Tak, ale są subtelności cover. Zobacz Rozmiar tła 101 pod linkiem .
kazanie
ok, aby uprościć 100% szerokość obrazu / wideo, a jeśli pojawi się przepełnienie, zostanie przecięty? Jeśli tego chcesz, mogę zobaczyć, czy mogę to zakodować, ale w przypadku wideo powinieneś pamiętać, że potrzebujesz niestandardowego odtwarzacza, ponieważ w większości przeglądarek elementy sterujące znajdują się na dole odtwarzacza i zostaną usunięte, jeśli tam są to przepełnienie ...
Lennart
Tak, przelewają się równomiernie po przeciwnych stronach. Jestem świadomy problemu ze sterowaniem wideo.
kazanie
1
Myślę, że jeśli okno jest wyższe niż obraz, pozostawi puste miejsce gdzieś wzdłuż osi pionowej. W takim przypadku obraz powinien zamiast tego przepełniać się po bokach i mieć taką samą wysokość jak okno. I odwrotnie powinno nastąpić, gdy okno jest szersze niż obraz.
kazanie

Odpowiedzi:

142

To jest coś, z czego przez chwilę wyrwałem włosy, ale natknąłem się na świetne rozwiązanie, które nie używa żadnego skryptu i może osiągnąć idealną symulację okładki na wideo z 5 liniami CSS (9, jeśli policzyć selektory i nawiasy ). Ma 0 skrajnych przypadków, w których nie działa idealnie, poza kompatybilnością z CSS3 .

Możesz zobaczyć przykład tutaj

Problem z rozwiązaniem Timothy'ego polega na tym, że nie obsługuje ono poprawnie skalowania. Jeśli otaczający element jest mniejszy niż plik wideo, nie jest zmniejszany. Nawet jeśli nadasz tagowi wideo niewielki rozmiar początkowy, na przykład 16 na 9 pikseli, w autokońcu zmusisz go do minimalnego rozmiaru pliku natywnego. Przy obecnym rozwiązaniu z największą liczbą głosów na tej stronie niemożliwe było zmniejszenie skali pliku wideo, co spowodowało drastyczny efekt powiększenia.

Jeśli jednak znany jest współczynnik proporcji Twojego filmu, na przykład 16: 9, możesz wykonać następujące czynności:

.parent-element-to-video {
    overflow: hidden;
}
video {
    height: 100%;
    width: 177.77777778vh; /* 100 * 16 / 9 */
    min-width: 100%;
    min-height: 56.25vw; /* 100 * 9 / 16 */
}

Jeśli element nadrzędny wideo jest ustawiony tak, aby obejmował całą stronę (na przykład position: fixed; width: 100%; height: 100vh;), wideo również będzie.

Jeśli chcesz, aby film również był wyśrodkowany, możesz zastosować metodę pewnego centrowania:

/* merge with above css */
.parent-element-to-video {
    position: relative; /* or absolute or fixed */
}
video {
    position: absolute;
    left: 50%; /* % of surrounding element */
    top: 50%;
    transform: translate(-50%, -50%); /* % of current element */
}

Oczywiście vw, vhi transformsą CSS3, więc jeśli potrzebujesz kompatybilności z dużo starszymi przeglądarkami , będziesz musiał użyć skryptu.

M-Pixel
źródło
3
To najlepsza odpowiedź. Bez javascript, czystego CSS, skaluje się poprawnie i wyśrodkowany.
mark.monteiro
6
Ach tak stary. Oto odpowiedź na rok 2016. Zignoruj ​​wszystkie inne.
Josh Burson
czy możesz wyjaśnić, dlaczego to działa? Nie mogę objąć go głową. co vhi vwmają do rzeczy?
Commonpike
1
@insidesin: Opublikować skrzypce?
M-Pixel
2
W 2020 roku najlepszym rozwiązaniem jest object-fit: cover, jak opisuje odpowiedź Daniël de Wit
Brett Donald
128

jsFiddle

Używanie okładki tła jest dobre w przypadku obrazów, podobnie jak szerokość 100%. Nie są one optymalne dla <video>, a te odpowiedzi są zbyt skomplikowane. Nie potrzebujesz jQuery ani JavaScript, aby uzyskać tło wideo o pełnej szerokości.

Pamiętaj, że mój kod nie pokryje całkowicie tła filmem, takim jak okładka, ale zamiast tego sprawi, że wideo będzie tak duże, jak to konieczne, aby zachować proporcje i nadal pokrywać całe tło. Nadmiar wideo będzie spadał poza krawędź strony, które strony zależą od miejsca zakotwiczenia wideo.

Odpowiedź jest dość prosta.

Po prostu użyj tego kodu wideo HTML5 lub czegoś podobnego: (przetestuj na całej stronie)

html, body {
  width: 100%; 
  height:100%; 
  overflow:hidden;
}

#vid{
  position: absolute;
  top: 50%; 
  left: 50%;
  -webkit-transform: translateX(-50%) translateY(-50%);
  transform: translateX(-50%) translateY(-50%);
  min-width: 100%; 
  min-height: 100%; 
  width: auto; 
  height: auto;
  z-index: -1000; 
  overflow: hidden;
}
<video id="vid" video autobuffer autoplay>
  <source id="mp4" src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>

Minimalna wysokość i minimalna szerokość pozwolą wideo zachować proporcje wideo, które zwykle są proporcjami każdej normalnej przeglądarki przy normalnej rozdzielczości. Nadmiar wideo znika z boku strony.

Timothy Ryan Carpenter
źródło
2
Jest to znacznie prostsze niż inne odpowiedzi i działa dobrze dla mnie. Po prostu ustawienie min-widthlub min-heightzałatwia sprawę.
Ryan Burney,
31
To rozwiązanie nie wyśrodkowuje wideo, jak robi to okładka.
weotch
1
tylko komentarz, aby uniemożliwić początkującym wyrywanie sobie włosów: #video_background {powinno być #videobackground {.
carrabino

21
W ogóle nie zmniejsza to wideo (nie próbowałem skalować go w górę), co powoduje wiele problemów, jeśli okno przeglądarki jest małe, a wideo jest duże. Zasadniczo zajmuje się tylko częścią spadową rozmiaru tła: okładką, a nie skalą.
Kevin Newman

4
Przy obecnych technologiach powinna to być akceptowana odpowiedź: rozwiązanie CSS jest lepsze niż rozwiązanie JavaScript. Nawet jeśli wymaga to prawidłowego ustawienia parentNode. Do centrowania wideo, użyj tego: position: absolute; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);.
Sjeiti,

101

W przypadku niektórych przeglądarek możesz użyć

object-fit: cover;

http://caniuse.com/object-fit


15
To bardzo mocna deklaracja, która, gdyby przyjęła ją przeglądarki, położyłaby kres wielu problemom związanym ze skalowaniem stron internetowych.
Mike Kormendy

1
To jest dokładnie to, czego szukałem!
Peter_Fretter

3
Jest polyfill dla tych przeglądarek, które go (jeszcze) nie obsługują: github.com/anselmh/object-fit
creimers

7
musiałem również złożyć wniosek height: 100%; width: 100%;. dzięki za tę nowoczesną odpowiedź
Jossef Harush

Na tej podstawie udzieliłem odpowiedzi z przykładami i informacjami . Dziękujemy za wskazanie tej funkcji!
aloisdg przenosi się na codidact.com

43

Oto jak to zrobiłem. Działający przykład znajduje się w tym jsFiddle .

var min_w = 300; // minimum video width allowed
var vid_w_orig;  // original video dimensions
var vid_h_orig;

jQuery(function() { // runs after DOM has loaded

  vid_w_orig = parseInt(jQuery('video').attr('width'));
  vid_h_orig = parseInt(jQuery('video').attr('height'));
  $('#debug').append("<p>DOM loaded</p>");

  jQuery(window).resize(function () { resizeToCover(); });
  jQuery(window).trigger('resize');
});

function resizeToCover() {
  // set the video viewport to the window size
  jQuery('#video-viewport').width(jQuery(window).width());
  jQuery('#video-viewport').height(jQuery(window).height());

  // use largest scale factor of horizontal/vertical
  var scale_h = jQuery(window).width() / vid_w_orig;
  var scale_v = jQuery(window).height() / vid_h_orig;
  var scale = scale_h > scale_v ? scale_h : scale_v;

  // don't allow scaled width < minimum video width
  if (scale * vid_w_orig < min_w) {scale = min_w / vid_w_orig;};

  // now scale the video
  jQuery('video').width(scale * vid_w_orig);
  jQuery('video').height(scale * vid_h_orig);
  // and center it by scrolling the video viewport
  jQuery('#video-viewport').scrollLeft((jQuery('video').width() - jQuery(window).width()) / 2);
  jQuery('#video-viewport').scrollTop((jQuery('video').height() - jQuery(window).height()) / 2);

  // debug output
  jQuery('#debug').html("<p>win_w: " + jQuery(window).width() + "</p>");
  jQuery('#debug').append("<p>win_h: " + jQuery(window).height() + "</p>");
  jQuery('#debug').append("<p>viewport_w: " + jQuery('#video-viewport').width() + "</p>");
  jQuery('#debug').append("<p>viewport_h: " + jQuery('#video-viewport').height() + "</p>");
  jQuery('#debug').append("<p>video_w: " + jQuery('video').width() + "</p>");
  jQuery('#debug').append("<p>video_h: " + jQuery('video').height() + "</p>");
  jQuery('#debug').append("<p>vid_w_orig: " + vid_w_orig + "</p>");
  jQuery('#debug').append("<p>vid_h_orig: " + vid_h_orig + "</p>");
  jQuery('#debug').append("<p>scale: " + scale + "</p>");
};
#video-viewport {
  position: absolute;
  top: 0;
  overflow: hidden;
  z-index: -1; /* for accessing the video by click */
}

#debug {
  position: absolute;
  top: 0;
  z-index: 100;
  color: #fff;
  font-size: 12pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="video-viewport">
  <video autoplay controls preload width="640" height="360">
    <source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"type="video/mp4" />
    <source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.webm"type="video/webm" />
    <source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.ogv"type="video/webm" />
  </video>
</div>

<div id="debug"></div>


Dlaczego odrzucono to rozwiązanie? Wydaje się, że pod każdym względem rozwiązuje problem.
Sty

2
To najlepsze rozwiązanie tego problemu, jakie znalazłem. Dzięki!
Chaser324

1
Działa to świetnie, jeśli wideo jest duże, a okno małe, ale nie zadziała, jeśli okno jest większe niż wideo, a wideo wymaga skalowania w górę. Dodałem min sztuczkę z @ Timothy-Ryan-Carpenter ( odpowiedź tutaj ) do tagu wideo jako: video { min-width: 100%; min-height: 100%; }i działa jak urok.
Alexandre DuBreuil,

Uważam, że to podejście jest również przydatne i zapakowałem je jako prostą wtyczkę jQuery dla wszystkich zainteresowanych: github.com/aMoniker/jquery.videocover
Jim Greenleaf

Pomimo tego, co mówi @AlexandreDuBreuil, to dobrze skaluje filmy (przekonaj się sam: fiddle.jshell.net/GCtMm/show ). To zdecydowanie najlepsze rozwiązanie. Szkoda, że ​​jest tak ciężki JS w porównaniu z inną odpowiedzią tutaj, ale to jest to, czego potrzebujesz, jeśli chcesz background-size: coverwideo.
Chuck Le Butt

14

Pozostałe odpowiedzi były dobre, ale obejmują javascript lub nie wyśrodkowują wideo w poziomie ORAZ w pionie.

Możesz użyć tego pełnego rozwiązania CSS, aby uzyskać wideo, które symuluje właściwość background-size: cover:

  video {
    position: fixed;           // Make it full screen (fixed)
    right: 0;
    bottom: 0;
    z-index: -1;               // Put on background

    min-width: 100%;           // Expand video
    min-height: 100%;
    width: auto;               // Keep aspect ratio
    height: auto;

    top: 50%;                  // Vertical center offset
    left: 50%;                 // Horizontal center offset

    -webkit-transform: translate(-50%,-50%);
    -moz-transform: translate(-50%,-50%);
    -ms-transform: translate(-50%,-50%);
    transform: translate(-50%,-50%);         // Cover effect: compensate the offset

    background: url(bkg.jpg) no-repeat;      // Background placeholder, not always needed
    background-size: cover;
  }

To nie zadziałało dla mnie. Film nie został przeskalowany do pełnego ekranu. Czy mogę zobaczyć Twój kod HTML na potrzeby tego przykładu? Czy to tylko tag wideo w treści?
mat.

Naprawdę fajne rozwiązanie. Na początku to nie zadziałało, ale prawdopodobnie było to coś, czego przegapiłem, ponieważ kopiowałem i wklejałem twój CSS, zadziałało! Dzięki;)
rafaelbiten

2
działało świetnie dla mnie. Właśnie zmieniłem pozycję: ustalono na absolutną
Assaf Katz

14

Na podstawie odpowiedzi i komentarzy Daniela de Wita szukałem nieco więcej. Dzięki za rozwiązanie.

Rozwiązaniem jest użycie, object-fit: cover;które ma świetne wsparcie ( obsługuje to każda nowoczesna przeglądarka). Jeśli naprawdę chcesz obsługiwać IE, możesz użyć wypełnienia typu polifill, takiego jak object-fit-images lub object-fit .

Dema:

img {
  float: left;
  width: 100px;
  height: 80px;
  border: 1px solid black;
  margin-right: 1em;
}
.fill {
  object-fit: fill;
}
.contain {
  object-fit: contain;
}
.cover {
  object-fit: cover;
}
.none {
  object-fit: none;
}
.scale-down {
  object-fit: scale-down;
}
<img class="fill" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="contain" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="cover" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="none" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="scale-down" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>

iz rodzicem:

div {
  float: left;
  width: 100px;
  height: 80px;
  border: 1px solid black;
  margin-right: 1em;
}
img {
  width: 100%;
  height: 100%;
}
.fill {
  object-fit: fill;
}
.contain {
  object-fit: contain;
}
.cover {
  object-fit: cover;
}
.none {
  object-fit: none;
}
.scale-down {
  object-fit: scale-down;
}
<div>
<img class="fill" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div><div>
<img class="contain" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div><div>
<img class="cover" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div><div>
<img class="none" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div><div>
<img class="scale-down" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
</div>


1
Najlepsza nowoczesna odpowiedź.
Routhinator

1
To jest odpowiedź dla każdego, kto wybiera nowoczesne przeglądarki. Używając object-fit: coveri widthi heightustawionych na 100%, bez problemu uzyskasz proporcjonalnie skalowane imglub videopowiększane na środku.
phip

13

Rozwiązanie M-Pixel jest świetne, ponieważ rozwiązuje problem skalowania odpowiedzi Timothy'ego (wideo będzie skalowane w górę, ale nie w dół, więc jeśli Twój film jest naprawdę duży, są duże szanse, że zobaczysz tylko niewielką część powiększoną). Jednak rozwiązanie to opiera się na fałszywych założeniach dotyczących rozmiaru kontenera wideo, a mianowicie, że musi to być 100% szerokości i wysokości widocznego obszaru. Znalazłem kilka przypadków, w których to nie zadziałało, więc postanowiłem sam rozwiązać problem i uważam, że znalazłem ostateczne rozwiązanie .

HTML

<div class="parent-container">
    <div class="video-container">
        <video width="1920" height="1080" preload="auto" autoplay loop>
            <source src="video.mp4" type="video/mp4">
        </video>
    </div>
</div>

CSS

.parent-container {
  /* any width or height */
  position: relative;
  overflow: hidden;
}
.video-container {
  width: 100%;
  min-height: 100%;
  position: absolute;
  left: 0px;
  /* center vertically */
  top: 50%;
  -moz-transform: translate(0%, -50%);
  -ms-transform: translate(0%, -50%);
  -webkit-transform: translate(0%, -50%);
  transform: translate(0%, -50%);
}
.video-container::before {
  content: "";
  display: block;
  height: 0px;
  padding-bottom: 56.25%; /* 100% * 9 / 16 */
}
.video-container video {
  width: auto;
  height: 100%;
  position: absolute;
  top: 0px;
  /* center horizontally */
  left: 50%;
  -moz-transform: translate(-50%, 0%);
  -ms-transform: translate(-50%, 0%);
  -webkit-transform: translate(-50%, 0%);
  transform: translate(-50%, 0%);
}

Jest również oparty na współczynniku wideo, więc jeśli Twój film ma współczynnik inny niż 16/9, będziesz chciał zmienić dolny procent wypełnienia. Poza tym działa po wyjęciu z pudełka. Przetestowano w IE9 +, Safari 9.0.1, Chrome 46 i Firefox 41.

EDYCJA (17 marca 2016 r.)

Od czasu, kiedy pisał tę odpowiedź Pisałem mały moduł do symulacji zarówno CSS background-size: coveri background-size: containna <video>elementach: http://codepen.io/benface/pen/NNdBMj

Obsługuje różne wyrównania wideo (podobnie jak background-position). Należy również pamiętać, że containimplementacja nie jest doskonała. W przeciwieństwie do background-size: containtego, nie przeskaluje wideo powyżej jego rzeczywistego rozmiaru, jeśli szerokość i wysokość kontenera są większe, ale myślę, że w niektórych przypadkach może być przydatne. Dodałem również specjalne fill-widthi fill-heightklasy, z których możesz korzystać razem, containaby uzyskać specjalną mieszankę containi cover... wypróbuj ją i nie krępuj się ją ulepszyć!


Nie powoduje to skalowania wideo powyżej normalnej rozdzielczości, aby pasowało do 100% szerokości / wysokości bez względu na wszystko. Dlatego nie powiela funkcji „okładki”.
jetlej

@jetlej Robi tutaj. W jakiej przeglądarce testujesz? Czy spojrzałeś na mój kod?
benface

1
W moim przypadku działało to przyjemnie jako rozwiązanie awaryjne w Edge. Pozdrawiam
MrThunder,

@MrThunder, czego używasz jako głównego rozwiązania, jeśli używasz tego jako rozwiązania zastępczego?
benface

1
@ benoitr007 Użyłem object-fit: coverdo FF i chrome oraz twojego rozwiązania z Modernizr dla IE
MrThunder


4

CSS i little js mogą sprawić, że wideo zakryje tło i zostanie wyśrodkowane w poziomie.

CSS:

video#bgvid {
    position: absolute;
    bottom: 0px; 
    left: 50%; 
    min-width: 100%; 
    min-height: 100%; 
    width: auto; 
    height: auto; 
    z-index: -1; 
    overflow: hidden;
}

JS: (powiąż to ze zmianą rozmiaru okna i wywołaj raz osobno)

$('#bgvid').css({
    marginLeft : '-' + ($('#bgvid').width()/2) + 'px'
})

3

Zaraz po naszej długiej sekcji komentarzy myślę, że właśnie tego szukasz, jest oparty na jQuery:

HTML:

<img width="100%" id="img" src="http://uploads8.wikipaintings.org/images/william-adolphe-bouguereau/self-portrait-presented-to-m-sage-1886.jpg">

JS:

<script type="text/javascript">
window.onload = function(){
       var img = document.getElementById('img')
       if(img.clientHeight<$(window).height()){
            img.style.height=$(window).height()+"px";
       }
       if(img.clientWidth<$(window).width()){
            img.style.width=$(window).width()+"px";
       } 
}
​</script>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

CSS:

body{
    overflow: hidden;
}

Powyższy kod korzysta z szerokości i wysokości przeglądarki, jeśli robisz to w ramach elementu div, musisz zmienić to na coś takiego:

Dla Div:

HTML:

<div style="width:100px; max-height: 100px;" id="div">
     <img width="100%" id="img" src="http://uploads8.wikipaintings.org/images/william-adolphe-bouguereau/self-portrait-presented-to-m-sage-1886.jpg">
</div>

JS:

<script type="text/javascript">
window.onload = function(){
       var img = document.getElementById('img')
       if(img.clientHeight<$('#div').height()){
            img.style.height=$('#div').height()+"px";
       }
       if(img.clientWidth<$('#div').width()){
            img.style.width=$('#div').width()+"px";
       } 
}
​</script>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

CSS:

div{
   overflow: hidden;
}

Powinienem również stwierdzić, że przetestowałem tylko, że to Google Chrome ... tutaj jest jsfiddle: http://jsfiddle.net/ADCKk/


Wydaje się, że jsfiddle nic nie robi, gdy zmieniam rozmiar ramki wyników lub rozmiar przeglądarki. Próbowałem tego w Chrome.
kazanie

Zaktualizowałem go, ale nadal mam niewielki problem, że jeśli zmniejszysz szerokość do bardzo, nagle skacze ... jsfiddle.net/ADCKk/1
Lennart

ok, przepraszam, ale nie mam pojęcia, próbowałem tylu rzeczy, myślę, że się pomyliłem, nie jestem pewien, czy to możliwe ... Powyższy skrypt działa tylko po odświeżeniu strony, aby działał kiedy zmieniasz rozmiar okna, musisz użyć zdarzenia window.resize w js, ale nie mogę sprawić, żeby działało, może możesz z tą informacją :) i tak powodzenia
Lennart

3

Najlepsza odpowiedź nie zmniejsza rozmiaru wideo, gdy szerokość przeglądarki jest mniejsza niż szerokość filmu. Spróbuj użyć tego kodu CSS (z #bgvid to identyfikator Twojego filmu wideo):

#bgvid {
     position: fixed;
     top: 50%;
     left: 50%;
     min-width: 100%;
     min-height: 100%;
     width: auto;
     height: auto;
     transform: translateX(-50%) translateY(-50%);
     -webkit-transform: translateX(-50%) translateY(-50%);
}

Dlaczego to, co negatywne, jest z-indexkonieczne?
aleclarson

To nie jest - po prostu pomocne przy projektowaniu z elementami wielowarstwowymi. Usunąłem to.
Ramzi Dreessen

1

Jestem gunna i publikuję to rozwiązanie, ponieważ miałem ten problem, ale inne rozwiązania nie działały w mojej sytuacji ...

Myślę, że aby poprawnie zasymulować background-size:cover;właściwość css na elemencie zamiast właściwości background-image elementów, musiałbyś porównać proporcje obrazu z obecnym współczynnikiem kształtu okna, więc bez względu na rozmiar (a także w przypadku, gdy obraz jest wyższy niż szerszy) okno to element, który wypełnia okno (i również go wyśrodkowuje, chociaż nie wiem, czy to był wymóg) ....

używając obrazu, tylko dla uproszczenia, jestem pewien, że element wideo też będzie działał.

najpierw pobierz proporcje elementów (po załadowaniu), następnie dołącz moduł obsługi zmiany rozmiaru okna, uruchom go raz do początkowego rozmiaru:

var img = document.getElementById( "background-picture" ),
    imgAspectRatio;

img.onload = function() {
    // get images aspect ratio
    imgAspectRatio = this.height / this.width;
    // attach resize event and fire it once
    window.onresize = resizeBackground;
    window.onresize();
}

następnie w programie obsługi zmiany rozmiaru należy najpierw określić, czy szerokość lub wysokość wypełnienia ma być wypełniona, porównując bieżące proporcje okna z oryginalnymi proporcjami obrazu.

function resizeBackground( evt ) {

// get window size and aspect ratio
var windowWidth = window.innerWidth,
    windowHeight = window.innerHeight;
    windowAspectRatio = windowHeight / windowWidth;

//compare window ratio to image ratio so you know which way the image should fill
if ( windowAspectRatio < imgAspectRatio ) {
    // we are fill width
    img.style.width = windowWidth + "px";
    // and applying the correct aspect to the height now
    img.style.height = (windowWidth * imgAspectRatio) + "px";
    // this can be margin if your element is not positioned relatively, absolutely or fixed
    // make sure image is always centered
    img.style.left = "0px";
    img.style.top = (windowHeight - (windowWidth * imgAspectRatio)) / 2 + "px";
} else { // same thing as above but filling height instead
    img.style.height = windowHeight + "px";
    img.style.width = (windowHeight / imgAspectRatio) + "px";
    img.style.left = (windowWidth - (windowHeight / imgAspectRatio)) / 2 + "px";
    img.style.top = "0px";
}

}

bawwb
1
Dzięki za odpowiedź @turbopipp, chociaż obawiam się, że źle zrozumiałeś powód mojej nagrody. Podniosłem go, aby móc przyznać go istniejącej odpowiedzi, po prostu nie pozwoli mi na to, dopóki nagroda nie będzie aktywna przez 24 godziny. Mimo to +1 za swoje wysiłki, sztuczka procentowego wypełnienia jest użytecznym sposobem na zapewnienie, że element zachowa prawidłowy współczynnik proporcji.
Hidden Hobbes
Aha, cóż, naprawdę nie było to kłopotliwe i naprawdę miło z twojej strony, że dajesz nagrodę za już istniejące odpowiedzi. Chyba powinienem poczytać o systemie nagród. :) Dzięki
turbopipp
To fajny pomysł iw niektórych przypadkach warto spróbować. Jedynym minusem jest to, że * .gif jest (w moim przypadku) większy w rozmiarze pliku. Przekonwertowałem 2,5 MB * .mpeg na 16 MB * .gif.
Henning Fischer,
Zgadzam się, i często .gifjest znacznie większy, a jednocześnie bardziej rozmyty. Mój pogląd zmienił się, odkąd napisałem tę odpowiedź. Szkoda, że ​​nie możesz połączyć tego, co najlepsze z obu.
D-Marc
Skończyło się na (skróconym) * .gif na urządzenia mobilne i * .mp4 na komputer.
Henning Fischer
1

To podejście wykorzystuje tylko css i html. W rzeczywistości możesz łatwo układać elementy DIV pod wideo. Jest zakryta, ale nie jest wyśrodkowana podczas zmiany rozmiaru.

HTML:

<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css"> 
</script>
</head>
<body>
<div id = "contain">
<div id="vid">
    <video autoplay>
        <source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" type="video/mp4" />
    </video>
</div>
</div>
</body>
</html>

CCS:

/*
filename:style.css
*/
body {
    margin:0;
}

#vid video{
position: absolute; 
right: 0; 
top: 0;
min-width: 100%; 
min-height: 100%;
width: auto; 
height: auto; 
}

#contain {
width:100%;
height:100%;
zoom:1%;/*Without this the video will be stretched and skewed*/ 
}
killsarkazm
źródło
1

@Hidden Hobbes

To pytanie ma otwartą nagrodę wartą +100 reputacji od Hidden Hobbes, kończącą się za 6 dni. Pomysłowe wykorzystanie jednostek widoku w celu uzyskania elastycznego rozwiązania opartego tylko na CSS.

Otworzyłeś nagrodę za to pytanie za rozwiązanie tylko dla CSS, więc spróbuję. Moim rozwiązaniem takiego problemu jest użycie stałego współczynnika do określenia wysokości i szerokości wideo. Zwykle używam Bootstrap, ale wyodrębniłem stamtąd niezbędny CSS, aby działał bez. Jest to kod, którego użyłem wcześniej, aby między innymi wyśrodkować osadzone wideo z odpowiednim współczynnikiem. Powinien działać dla elementów <video>i <img>też. Najważniejszy jest tutaj istotny, ale podałem ci również pozostałe dwa, ponieważ już je miałem. Powodzenia! :)

przykład pełnoekranowy jsfiddle

.embeddedContent.centeredContent {
    margin: 0px auto;
}
.embeddedContent.rightAlignedContent {
    margin: auto 0px auto auto;
}
.embeddedContent > .embeddedInnerWrapper {
    position:relative;
    display: block;
    padding: 0;
    padding-top: 42.8571%; /* 21:9 ratio */
}
.embeddedContent > .embeddedInnerWrapper > iframe {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    height: 100%;
    width: 100%;
    border: 0;
}
.embeddedContent {
    max-width: 300px;
}
.box1text {
    background-color: red;
}
/* snippet from Bootstrap */
.container {
    margin-right: auto;
    margin-left: auto;
}
.col-md-12 {
    width: 100%;
}
<div class="container">
    <div class="row">
        <div class="col-md-12">
            Testing ratio AND left/right/center align:<br />
            <div class="box1text">
                <div class="embeddedContent centeredContent">
                    <div class="embeddedInnerWrapper">
                        <iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&amp;jqoemcache=eE9xf" width="425"></iframe>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            Testing ratio AND left/right/center align:<br />
            <div class="box1text">
                <div class="embeddedContent rightAlignedContent">
                    <div class="embeddedInnerWrapper">
                        <iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&amp;jqoemcache=eE9xf" width="425"></iframe>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            Testing ratio AND left/right/center align:<br />
            <div class="box1text">
                <div class="embeddedContent">
                    <div class="embeddedInnerWrapper">
                        <iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&amp;jqoemcache=eE9xf" width="425"></iframe>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

turbopipp
źródło
1
Dzięki za odpowiedź @turbopipp, chociaż obawiam się, że źle zrozumiałeś powód mojej nagrody. Podniosłem go, aby móc przyznać go istniejącej odpowiedzi, po prostu nie pozwoli mi na to, dopóki nagroda nie będzie aktywna przez 24 godziny. Mimo to +1 za swoje wysiłki, sztuczka procentowego wypełnienia jest użytecznym sposobem na zapewnienie, że element zachowa prawidłowy współczynnik proporcji.
Hidden Hobbes
Aha, cóż, naprawdę nie było to kłopotliwe i naprawdę miło z twojej strony, że dajesz nagrodę za już istniejące odpowiedzi. Chyba powinienem poczytać o systemie nagród. :) Dzięki
turbopipp
0

Aby odpowiedzieć na komentarz Weotch, że odpowiedź Timothy'ego Ryana Carpentera nie uwzględnia coverwyśrodkowania tła, oferuję tę szybką poprawkę CSS:

CSS:

margin-left: 50%;
transform: translateX(-50%);

Dodanie tych dwóch linii spowoduje wyśrodkowanie dowolnego elementu. Co więcej, wszystkie przeglądarki obsługujące wideo HTML5 obsługują również transformacje CSS3, więc to zawsze będzie działać.

Kompletny CSS wygląda tak.

#video-background { 
    position: absolute;
    bottom: 0px; 
    right: 0px; 
    min-width: 100%; 
    min-height: 100%; 
    width: auto; 
    height: auto; 
    z-index: -1000; 
    overflow: hidden;
    margin-left: 50%;
    transform: translateX(-50%);
}

Skomentowałbym bezpośrednio odpowiedź Timothy'ego, ale nie mam wystarczającej reputacji, aby to zrobić.

Jake Z
źródło
0

Chłopaki mam lepsze rozwiązanie jest krótkie i na mnie działa idealnie. Użyłem go do wideo. I doskonale emuluje opcję okładki w css.

Javascript

    $(window).resize(function(){
            //use the aspect ration of your video or image instead 16/9
            if($(window).width()/$(window).height()>16/9){
                $("video").css("width","100%");
                $("video").css("height","auto");
            }
            else{
                $("video").css("width","auto");
                $("video").css("height","100%");
            }
    });

Jeśli odwrócisz if, w przeciwnym razie otrzymasz zawartość.

A oto css. (Nie musisz go używać, jeśli nie chcesz pozycjonować na środku, nadrzędny element DIV musi mieć wartość „ position: względna ”)

CSS

video {
position: absolute;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
top: 50%;
left: 50%;}
user2925729
źródło
0

Właśnie to rozwiązałem i chciałem się podzielić. Działa z Bootstrap 4. Działa z, imgale nie testowałem tego z video. Oto HAML i SCSS

HAML
.container
  .detail-img.d-flex.align-items-center
    %img{src: 'http://placehold.it/1000x700'}
SCSS
.detail-img { // simulate background: center/cover
  max-height: 400px;
  overflow: hidden;

  img {
    width: 100%;
  }
}

/* simulate background: center/cover */
.center-cover { 
  max-height: 400px;
  overflow: hidden;
  
}

.center-cover img {
    width: 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
  <div class="center-cover d-flex align-items-center">
    <img src="http://placehold.it/1000x700">
  </div>
</div>

Chloe
źródło
0

Stare pytanie, ale na wypadek, gdyby ktoś to zobaczył, najlepszą odpowiedzią moim zdaniem jest przekonwertowanie wideo na animowany GIF. Daje to znacznie większą kontrolę i możesz po prostu traktować to jak obraz. To także jedyny sposób, aby działał na telefonie komórkowym, ponieważ nie można automatycznie odtwarzać filmów. Wiem, że chodzi o zrobienie tego w <img>tagu, ale tak naprawdę nie widzę wad używania a <div>i doingbackground-size: cover

D-Marc
źródło
To fajny pomysł iw niektórych przypadkach warto spróbować. Jedynym minusem jest to, że * .gif jest (w moim przypadku) większy w rozmiarze pliku. Przekonwertowałem 2,5 MB * .mpeg na 16 MB * .gif.
Henning Fischer,
Zgadzam się, i często .gifjest znacznie większy, a jednocześnie bardziej rozmyty. Mój pogląd zmienił się, odkąd napisałem tę odpowiedź. Szkoda, że ​​nie możesz połączyć tego, co najlepsze z obu.
D-Marc
Skończyło się na (skróconym) * .gif na urządzenia mobilne i * .mp4 na komputer.
Henning Fischer