Fitting HTML5 video to parent element size - javascript

I've got a <video> element inside a <div> that gets automatically resized when other elements on the page are dynamically resized / added / deleted.
I would like the video element to also automatically resize so that it always remains contained within its background div; this sort-of-works if I set the video element's CSS height & width to 100%, so it's always the same size as its container. However, if the containing div's dimensions go below the video image's inherent videoWidth or videoHeight, then it starts to behave as though the CSS height/width properties refer to percentages of the video image's inherent dimensions, not the container div! E.g., if the CSS height is 100%, it scales normally except that it has a minimum size of the video's inherent height; if the CSS height is 50%, it scales normally but with a minimum size of 50% of the video's inherent height.
I can fix this, sort of, by using JavaScript to periodically reset the video element's height in pixels to be the computed height of the container, but this is really slow and choppy. Is there any way to fix this in CSS so that the video element will size properly?

I am well aware this is an older question, but I have been struggling with accomplishing a layout with CSS where a video is automatically sized to fit some box, typically within parent element.
Just using width and height with static positioning only works in certain configuration of parent-child topologies, and also depends a lot on how the topology is styled. Even if you get some element to properly calculate its boundaries, once you put a playing video element inside it, it will expand the parents allowed box, even though that is the least sensible behavior you'd expect.
Throw in some fieldset elements, and you're in the rabbit hole of CSS and browser peculiarities.
What I have found out is that it was easiest to just take the video element out of its positioning context, using position: absolute. It doesn't mean that it won't visually well-behave -- using width: 100% and height: 100% effectively makes it properly constrain itself as it otherwise should (but wouldn't). You would then need to add position: relative to appropriate ancestor element of the video element, otherwise the video will be absolutely positioned in relation to document root, which is most likely not what you'd want.
Omitting left and right works because absolute positioning does not reset the position, just switches the calculation method. You could alternatively set both properties to zero, you'd get your video aligned to the offset parent top-left corner then. max-width and max-height are unnecessary -- I just have seen these being thrown in in a lot of cases where people struggle with constraining their video elements -- don't bother.
You can specify background color for either the video element or its offset parent. That way you will get the letter-boxing effect -- say, black bars on the sides of the video.

As your video is inside a div, this can be solved by setting both width and height of the video to 100%. This makes the video occupy 100% of the div element.
Markup example:
<div id="video_container">
<video></video>
</div>
Stylesheet:
#video_container video {
width: 100%;
height: 100%;
}

Related

CSS Grid Container Height Covers Other Content

I'm building a responsive CSS grid with items whose sizes match a desired aspect ratio. I've tried the padding hack among a few other techniques, but nothing has worked nearly as well for me as using JS to determine the pixel value of 1fr for the desired number of columns and the gap size, and then applying that to the row sizing using repeat(auto-fill, minmax(${width}px, 0)).
Unfortunately, this approach comes with a rather nasty side effect: the parent div (display: grid) doesn't know the height of its own content, so it never sizes correctly. As a result, it's never able to show more than one row of the grid. The rest of the grid items display as a line just below that first row.
To fix this, I've tried setting the height of the parent to 100%, but that covers all of the other content on the page. I've tried using containers to fix the sizing, but haven't had any luck there, either. I've also tried overflow: auto, to no effect. If I could calculate and manually set the height of the parent div in my script, that might work, but I've not been able to find a way to do so (and also seems like a messy approach).
Is there any (good) way to do this? Here's a demo of the issue: https://codepen.io/jmindel/pen/GRoMjEw
when you set the overflow: auto it will make a scroll bar in your element to show all of the content in the specified area. then in this case it won't help you. when you set the height of an element to 100% it's height will be the same as it's parent element. I had this problem before. if you want to set the height of an element you should set the height attribute of all the parents of the parents of your element. you can use % as the unit of height and width if you want your code be responsive and don't want to calculate the exact height of elements and if not you can use other units. try to set height with % unit for all of your parents. it helped me and I am sure it will help you too.
Here's what I wound up doing:
I tried wrapping .grid in another div and styling that wrapper such that it has overflow: scroll, which fixes the height not displaying (100% is fine in this environment--it doesn't cover anything, since it's limited to the height of its block-level parent).
I wrote a script that temporarily sets the grid's height to a very large number, finds the lowest element in the grid, and uses its position to determine the grid's height, which gives it a forced pixel height until the next resize.
A few shortcomings of this approach:
The grid must be contained to a scrollable subcontainer, which works well for my use, but might not for others.
The grid's height should size properly, but didn't without a forced pixel height. min-content and max-content did not work.

How do websites make an element scale the same on all devices and scale on zoom?

Right now i am making all of my elements with a percent width and height so that they can scale the same regardless of the device. As an example, whether someone is viewing an input element on a 720p or 4k monitor, it should fit the same across the browser.
Now my problem is that i am trying to make my elements scale upon an increase or decrease in zoom(browser zoom:ctrl and +/-) but because i am using a percentage width and height, the element doesn't scale. Well actually i think when i zoom in the input gets smaller, i'm not sure why that is. Other websites when you zoom in their input gets bigger in width and height. When you zoom out the element gets smaller.
What is the proper way to go about doing this? Obviously it can be done since every site i visit, including stackoverflows elements(search input as an example) looks the same size upon viewing and scales in height and width upon zooming.
What i've tried:
Using a fixed min-width and min-height but it's not exactly what i want. If the width/height percentage is higher than the fixed min-width/height then the element wont resize until the zoom % * the fixed min-width/height pixel count is greater. If the fixed min-width/height pixel count is higher than the width/height % set on the element, then the element will be the size of the fixed min-width/height and the element size wont look the same across all monitors.
using a fixed pixel for the width/height will make the element resize upon zooming but it wont look the same across all monitors.
Using a flexbox on the parent div "search" to make the child input "test" grow/shrink upon zooming. Doesn't seem to do anything.
NOTICE: don't try to zoom in without full viewing the code, otherwise it will make the input scale upon zooming as a result of stackoverflow's own code.
html, body {
width: 100%;
height: 100%;
margin:0px;
}
div#maincontainer {
height: 100%;
width:100%;
background-color: orange;
}
div#search {
position: relative;
top: 50%;
margin:auto;
height: 5%;
width: 35%;
}
input#test {
position: relative;
width: 100%;
height: 100%;
}
<div id="maincontainer">
<div id="search">
<input id="test" type="text" placeholder="TESTING" />
</div>
</div>
The browser zooming (using "Ctrl and +/-") actually changes the value that font-size: 100%; (which is equivalent to font-size: 1em;) corresponds to. That is why the text inside your input element is scaled when using this zooming feature. But because the input element size does not change (see explanation below), it looks like the latter gets smaller... whereas in fact it is its inner text that becomes bigger.
As far as I understand, the idea was to give a chance to the visitor to read text (while possibly breaking the page layout), if for some reason they have difficulties with the text size the website designer had chosen.
In the case of the size of your input element, because you define it relatively to the size of its containers (using percentages), up to the body which has 100% of the view port, you are not giving it any chance to be scaled by this feature, but instead you make it dependent on the view port size. So if you do resize your view port (i.e. browser window), you will see your element size changing, but not its inner text. It may sound as what you were looking for at the beginning (rendering with the exact same proportions on different devices, actually on different view port sizes), but what today's websites do is actually a totally different technique.
What they do is called "Responsive Design", i.e. the CSS uses "media queries" that can detect the type of device, screen size (actually view port size), etc. These media queries act as conditional blocks for CSS rules. The typical use case is to render a big menu on a side when the screen is wide enough, but only a menu button when the screen is narrow.
You can also notice that they do not actually render in the exact same proportions depending on the view port size (which was what you wanted to do by using only percentage-based sizes). Most of the time, there is an empty space (on both sides in the case of StackOverflow) that fills the gap, while the content has the same size in pixels, until the view port size changes so much that it triggers a media query, which then applies a different set of CSS rules, possibly changing completely the page layout.
Another good practice is to use as much as possible sizes (but not necessarily positioning) in em units, which refer to the current font size. That way, when the visitor uses the browser zooming feature, these sizes will scale accordingly, not only the text. For your case, you could have defined the height of your input element as 1.5em for example, so that it is always 50% bigger than its inner text.
Finally, I encourage you to use the DOM and Style inspectors of Development Tools featured by most browsers (turn the Development Tools on by hitting F12). They usually also provide element pickers, which allow you to pinpoint an element on the page for which you want to see the exact DOM and applied styling rules. It is a very instructive and ludic way to learn how others design their websites.

Responsively Scaled Image in CSS

I'm creating a slideshow with jQuery Cycle, and I need to be able to resize the images in the slideshow responsively with css. So far, cycle has been so controlling of the width and height of the images that I haven't been able to do it. I have been able to achieve the images resizing according to window width when I refresh the page, but the images won't dynamically resize when resizing the window. I'm trying to work out a solution in Javascript, but I'd really like to be able to get away with pure css.
jQuery Cycle is setting widths inline on the <img> tags. That's the first problem. I would try removing that, it looks like the options for Cycle has this value slideResize, try setting that to false or 0.
The next step would be setting a max-width on the container, and width: 100% on the imgs.
Just a suggestion - but you'll probably want to use something like JavaScript (or an AJAX service or something) to handle this because if you were to handle resizing the images within the browser that is going to put an incredible amount of strain on the browser to handle all of the resizing and scaling.
You may want to target specific resolutions and serve the images based on the "closest" viewport size accordingly.
you can set the width or height of the image related to a container
.container{width:200px}.container img {width:100%}
Hope this helps!
Set the img elements width to 100% and height to auto to take aspect ratio into account. If you don't want the image to be 100% of the browser, add a container element.
Your best bet to make a image responsive, this is without it being inside a container btw.
img {
width: 100%;
height: auto;
}
Now, it will stretch to the width of the page, but if its contained it will stretch to the width of the container, the thing to try is, making the container grow and shrink as well.

Absolute positioned elements inside a float

I have a stack of imgs overlaying one-another which are shown/hidden as needed. For these images to overlap I am forced to use position:absolute(I am fading between them so I need at least two images on-top of one-another at a time). Their container div is floated, but the images' height varies so I cannot set a fixed height on this parent container. I need their container to accurately reflect their height as there is another floated div that clears the container which needs to sit below the image, whatever height it is.
Is there any way of achieving this without using javascript to adjust the height of the container appropriately for each image?
Here is a link to the page as it is at the moment. I am using images with identical heights but I would like to be able to vary the height of the images.
http://www.unwalked.com/
What if you don't make all the child images absolutely positioned, instead only temporarily set position: absolute; to the image that's being faded away? That way the container would naturally resize to fit active image.

Get image height in IE of display:none image?

I have images who are set to display:none. I am using javascript (document.getElementById('elem').height) to get the height/width of these images.
This works in other browsers, but IE reports the height to be 0 (presumably due to the fact that its display is set to none - because when I remove the display:none, the height is reported correctly). I tried wrapping the images in a div and setting the div's display to none instead of the images - but this didn't work either.
What is the typical work around for this?
If you are interested in the size of the image itself, apart from any styles or attributes set in the html, you can measure a new Image with the same src.
It doesn't add anything to the document's html or stylesheets, or even to document.images.length if you are only testing included images.
var im=new Image();
im.src=element.src;
return [im.src, im.width, im.height];
you could use visibility: hidden;, maybe in combination with position:absolute too prevent "flickering" which you will remove after reading out the height.
Try this:
Position it offscreen
set it to display:block
get its height
set it back to display:none
re-position it back where it was
display:none; elements are defined as not having any display properties, so height and width shouldn't be used while it's in this state.
You could try setting it to visibility:hidden;, which would retain height and width. The downside of this is that visibility doesn't affect it's position in the page flow, so it will also retain the space it takes up in the layout. You could counter-act that by setting the position to either absolute or fixed to take it out of the context flow. You may also want to set the z-index to a negative value to ensure it gets hidden behind the rest of the page elements, otherwise it might block other elements from being clicked, etc, even though it would be invisible.

Categories