I want to fit a YouTube iframe embed in the middle of a page (70% width) so I'm doing this:
.wrapper {
margin: auto;
width: 70%;
}
.wrapper iframe {
left: 0;
top: 0;
width: 100%;
height: 100%;
}
The problem is, I'm getting black bars around the video to fill the available space. If instead I used padding (as in this answer) the iframe would only fit horizontally and might require scrolling in the vertical direction. Any idea what might help? (older browser support is not an issue)
Edit: I know the aspect ratio of the video I want to play.
You can try to use flex css for this issue. you can use the static height width to the iframe as per your requirement
.wrapper {
display: flex;
align-items: center;
justify-content: center;
}
.wrapper iframe{
width: 100px;
height: 100px;
}
Black bars appear when the height/width ratio of the iframe is too high (over .5, approximately).
Use this CSS to maintain a fixed height/width ratio, even when the wrapper is resized:
.wrapper {
width: 70%;
padding-top: 35%; // 35/70 = 0.5, the ratio can be changed here
margin: auto;
position: relative;
}
.wrapper iframe {
width: 100%;
position: absolute;
height: 100%;
transform: translate(0, -100%);
}
Related
Let's say I have a video with a known aspect ratio. I need to make it act like a fixed background-cover for a full-screen section (100vw / 100vh).
But also I need to attach some floating absolute-positioned elements, relative to the content of the video. For example, 60% left / 40% top point relative to the content of the video .
So If I use object-fit: cover on the video, and position: absolute for the floating elements, I can no longer just provide left / top percentage offset, because those percents no longer match the content of the video.
I tried to overcome this problem by using some math formulas like:
--video-aspect-ratio: 1680 / 944;
--video-height: max(100vh, 100vh / var(--video-aspect-ratio));
--video-width: max(100vw, 100vw * var(--video-aspect-ratio));
--vertical-video-offset: min(0%, (100vh - var(--video-height)) / 2);
--horizontal-video-offset: min(0%, (100vw - var(--video-width)) / 2);
position: absolute;
inset: var(--vertical-video-offset) var(--horizontal-video-offset);
But it just doesn't seems to work for some reason.
Need some help in figuring out how to achieve this layout, preferably in plain CSS.
Any ideas? Thanks!
So, looks like I found 2 possible solutions for this:
Using 2 wrappers and flex:
<div class='bg-frame'>
<div class='video-container'>
<video />
...Floating elements
</div>
</div>
.bg-frame {
position: absolute;
inset: 0;
display: flex;
place-content: center;
> .video-container {
aspect-ratio: var(--video-aspect-ratio);
flex: 0 0 auto;
min-height: 100%;
min-width: 100%;
width: max(100vw, 100vh * var(--video-aspect-ratio));
> video {
object-fit: cover;
height: 100%;
width: 100%;
}
}
}
Using 1 wrapper and position absolute:
<div class='video-container'>
<video />
...Floating elements
</div>
.video-container {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
aspect-ratio: var(--aspect-ratio);
min-height: 100%;
min-width: 100%;
width: max(100vw, 100vh * var(--aspect-ratio));
> video {
object-fit: cover;
height: 100%;
width: 100%;
}
}
I don't really like the transform: translate(-50%, -50%) part of the second solution, but it seems to work fine in the cases I tested.
I tried to get the right formula for positioning the texts when using cover for the video.
For reasons I have been unable to explain this worked when the video height was fixed to the viewport height but not when the width was fixed.
So this snippet uses another sizing and positioning method by setting the position of the video relative to a container depending on whether the viewport aspect ratio is greater or less than the video's aspect ratio.
The text positions are set as % within the video (so you can measure these on the original video) and therefore their positions relative to the overall video do not change. Of course, texts near an edge of the video may disappear or be seen only partially if the viewport gets too narrow or too wide.
* {
margin: 0;
}
body {
overflow: hidden;
}
.container {
height: 100vh;
width: 100vw;
overflow: hidden;
position: absolute;
}
.inner {
position: absolute;
width: fit-content;
height: fit-content;
overflow: hidden;
}
video {
position: relative;
/* here put the aspect ratio of your video */
aspect-ratio: 1920 / 1080;
overflow: hidden;
}
.overlay {
position: absolute;
top: var(--t);
left: var(--l);
transform: translate(-50%, -50%);
background: white;
padding: 10px;
}
/* here put the aspect ratio of your video */
#media (min-aspect-ratio: 1920 / 1080) {
.inner {
position: relative;
top: 50%;
transform: translateY(-50%);
width: 100vw;
}
video {
width: 100vw;
height: auto;
}
}
/* here put the aspect ratio of your video */
#media (max-aspect-ratio: 1920 / 1080) {
.inner {
position: relative;
left: 50%;
transform: translateX(-50%);
height: 100vh;
}
video {
height: 100vh;
width: auto;
}
}
<div class="container">
<div class="inner">
<video src="https://ahweb.org.uk/easter-card.mp4" autoplay muted></video>
<!-- --t and --l are the % top and left positions of the center of the overlaid text element -->
<div class="overlay" style="--t: 20%; --l: 20%;">a tree</div>
<div class="overlay" style="--t:45%; --l: 50%;">another tree</div>
<div class="overlay" style="--t:80%; --l: 90%;">yet another tree</div>
<div class="overlay" style="--t: 20%; --l: 80%;">the church</div>
</div>
</div>
Unfortunately it is not possible to build in the dimensions (or aspect ratio) of the video as the media queries do not allow CSS variables to be used so there are several places where you need to put the ratio in by hand.
I know there are a lot of questions out there regarding this topic, however I couldn't find a proper solution.
I have a #banner element on top of my site that is 710px high.
In this #banner I have my video that should always scale like "background-size:cover". It doesn't matter if the video is cut at the top or bottom, it should just always fill the #banner element.
#banner {
position:relative;
opacity:0;
height:710px;
width:100%;
overflow:hidden;
}
#banner .video {
position: absolute;
bottom: 50%;
right: 50%;
transform: translateX(-50%) translateY(-50%);
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
overflow: hidden;
}
I found this code right here but it doesn't properly work for me. The video does not resize when scaling the browser-window. For me this does not work.
Also I tried to use the covervid plugin that seems to work perfect for full-background sizes but not to fit it inside a banner with fixed height.
If I use this plugin and resize the window it jumps from width to height fitting, always setting the width or either height to auto.
Any idea how to do this via css or js?
Just remove the opacity from the banner and add max-height:100% to make sure that there's no vertical scroll
DEMO
html,
body {
margin: 0;
height: 100%;
}
#banner {
position: relative;
height: 710px;
border: 5px solid tomato;
overflow: hidden;
max-height: 100%;
box-sizing: border-box;
}
#banner .video {
min-width: 100%;
min-height: 100%;
}
<div id="banner">
<video class="video" autoplay>
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" type="video/mp4" />
</video>
</div>
My goal is to vertically and horizontally center an image inside its container and that the image takes as much space as possible without ever changing the original aspect ratio.
Using { background-size: contain; background-position: center; background-repeat: norepeat; } is not an option since I need to attach an overlay div to the corner of the image. Using a background would mean that the containing div would not follow the image size precisely.
Here's an attempt to do this using flexbox. Unfortunately it does not work in Firefox (on linux at least). Firefox stretches images when the width of the container is larger than the image's width for the given height. Flexbox attempt
Here's another attempt, this time using absolute positioning w/ left: 50%; in order to center a first div and transform: translate(-50%, -50%) in order to center the image. The result is not acceptable because the image-wrapper div (with green "olivedrab" borders) is not right around the image on Firefox (same in chrome when resizing the window vertically). This means that no overlay can be attached directly on the image (and follow as it is resized). Left 50% + Translate attempt
Note: No Javascript should be needed.
<style>
div {
width: 400px;
height: 400px;
line-height: 400px;
background-color: #cccccc;
vertical-align: middle;
position: relative;
border: 1px solid black;
}
img {
position: absolute;
display: block;
max-width: 100%;
max-height: 100%;
margin: auto;
vertical-align: middle;
width: auto;
height: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
Tested in IE9 and FF.
This works:
div {
width: 30em;
height: 30em;
display: flex;
align-items: center;
justify-content: center;
/* Just to illustrate the example better */
background-color: lightgray;
margin-bottom: 1em;
}
img {
max-width: 100%;
max-height: 100%;
}
<div><img src="http://static.tumblr.com/9dc5afd0db110ad78cb81e0b1dd84ebc/7dmyfag/NGfmkucxa/tumblr_static_tyrion-lannister.jpg" /></div>
<div><img src="http://upload.wikimedia.org/wikipedia/en/5/50/Tyrion_Lannister-Peter_Dinklage.jpg" /></div>
Hey guys I am working on this responsive horizontal gallery, but now I have a dilemma.
I am trying to get 4 list items on a single shot (viewport).
The images are somehow not stretched to the full height.
Have a look and please tell me if my image size is not fine or something like that.
I need at least 4 images on a single shot.
Thanks
FIDDLE
li {
display: inline-block;
max-height: 100%;
width: 25%;
}
li img {
max-width: 100%;
}
Code looks something like this. Please check fiddle. thanks.
Something like this Link
Here's my answer:
http://jsfiddle.net/SKEL2/14/
I set all the widths to be 100% of the window (INCLUDING html and body), this might be a problem if you have other scrollable elements inside the page.
after that I just positioned the images inside the with position absolute, and gave them a height of 100% (this will stretch them to the bottom of the container, keeping the aspect ratio constant).
To keep it centered I used the
top: 50%;
transform: translateX(-50%);
trick, that will keep an absolutely positioned element in the center of the container (as long as the container has position: relative)
I hardcoded a
min-width 420px;
to avoid the white borders around the images when the window became too small.
Hope this helps
Check this fiddle: http://jsfiddle.net/SKEL2/15/
*{
height:100%;
}
body {
width:100%;
margin: 0;
padding: 0;
}
slides {
width: 100%;
overflow: auto;
margin: 0;
padding: 0;
}
ul {
width:100%;
display: inline-block;
white-space: nowrap;
margin: 0;
padding: 0;
}
li {
display: inline-block;
max-height: 100%;
width: 25%;
background-image:url('http://beautifulsoftwares.com/scroll/img/2.jpg');
background-size:cover;
background-position:50% 50%;
}
li img {
max-width: 100%;
}
background-image:url(''); - Sets an image to the element
background-size:cover; - Property to cover the entire width and height with image
background-position:50% 50% - Centers the image
I have found this vertical centring method which seems pretty common..
#container {
width: 960px;
height: 740px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -480px;
margin-top: -370px;
}
What I'm trying to center here is the entire site, and this code goes perfectly as expected when the screen preview is larger than the div height (larger than 740px). However, Once the browser window is minimized less than div's vertical size (740px) parts of the header disappear above the top of the page.
I can sort of understand why this is happening seeing that 50% becomes less than half the div's size which will be equalized with margin-top.
What I'm looking for is a fix for this issue? Or even a completely different method, I just need to center the site both vertically and horizontally.
try this:
#container {
height: 740px;
width: 960px;
position: absolute;
margin: auto;
top: 0; right: 0; bottom: 0; left: 0;
}
By the way, Smashing Magazine recently published a nice article about this.
You need to add a media query:
#media screen and (min-height:740px) {
#container {
top:0;
margin-top:0;
}
}
This will only apply the formatting where the screen is at least 740px tall. If you want to learn more about media queries, check http://www.w3.org/TR/css3-mediaqueries/
Absolute Centering like Lino Rosa mentioned is the best approach here for easy horizontal and vertical centering while allowing you to add some responsive touches, like fixing your height issue.
Ideally, you should be using percentages for the width and height declarations so that your content will vary with the viewport. Of course, sometimes you just need pixels :-)
Here's what I've done:
.Absolute-Center {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
margin: auto;
}
#container {
width: 960px;
max-width: 90%;
height: 740px;
max-height: 90%;
overflow: auto;
}
By setting a max-height and max-width, the box will never be more than 90% of the container (in this case, the browser viewport) even if it's less than 960px wide or 740px tall, so even small screens see a nice centered box. overflow: auto ensures that if the content is longer than the box, the user can scroll in the box to see the rest.
View the demo
If you must have the box exactly 960px by 740px no matter the screen size (forcing the user to scroll around to see all of the content on a small window), then only apply the Absolute Centering styles to #container using a media query, like so:
#container {
width: 960px;
height: 740px;
overflow: auto;
margin: auto;
}
#media screen and (min-height:740px) and (min-width: 960px) {
#container {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
}
View the demo
I encountered the same issue. As the height of my element is dynamically changed, I can't give it a fixed height.
Here is a demo below, hope it helps.
.wrapper {
display: table;
height: 100vh;
width: 100%;
}
#container {
display: table-cell;
vertical-align: middle;
background-color: lightblue;
}
.content {
width: 30%;
height: 30%;
background-color: red;
}
<html>
</html>
<body>
<div class="wrapper">
<div id="container">
<div class="content">
</div>
</div>
</div>
</body>