CSS: keep image aspect ratio as viewport width decreases - css

At this page, there are 3 "doorway" graphics:
<div class="textwidget">
<div class="one-third first">
<div id="doorway1" class="doorway">
<h3>The Best Core Exercise Ever</h3>
<div class="doorway-action">
<img src="http://vmpersonal.com/wp-content/themes/vmpersonal/images/doorway-action.png" alt="Watch Video Now" title="Watch Video Now" /> Watch Video Now
</div>
</div>
</div>
<div class="one-third">
<div id="doorway2" class="doorway">
<h3>Core Strength Level 1 Program</h3>
<div class="doorway-action">
<img src="http://vmpersonal.com/wp-content/themes/vmpersonal/images/doorway-action.png" alt="Watch Video Now" title="Watch Video Now" /> Watch Video Now
</div>
</div>
</div>
<div class="one-third">
<div id="doorway3" class="doorway">
<h3>Cardio Program</h3>
<div class="doorway-action">
<img src="http://vmpersonal.com/wp-content/themes/vmpersonal/images/doorway-action.png" alt="Watch Video Now" title="Watch Video Now" /> Watch Video Now
</div>
</div>
</div>
</div>
I'd like to make the graphics and the divs that contain them responsive.
They are contained in div.one-third containers.
The images are 409px x 292px, meaning the height is 71.39364303% of the width.
I thought if I used CSS:
#doorway1 {background-image: url('images/doorway1.png'); height: 71.39364303%;}
#doorway2 {background-image: url('images/doorway2.png'); height: 71.39364303%;}
#doorway3 {background-image: url('images/doorway3.png'); height: 71.39364303%;}
they would scale down with the div.one-third as the viewport decreased in width, but they don't, the images are cut off.
How can I keep the images aspect ration consistent as the viewport width decreases?
Help appreciated.
Update: AJ Funk has helped me make the background images scale down, but how do I make the divs that contain them scale down proportionally too?

You should combine the background-size: contain with a padding-bottom CSS trick to maintain aspect ratio. This could work as follows. Note that the main ideas are the background-size: contain and padding-bottom: 71.39364303% on .doorway elements, in combination with height: 0. The rest is minimal styling to illustrate the point.
It should be straightforward to apply this on your linked test page.
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.textwidget {
width: 100%:
font-size: 0; /* to prevent space between inline-block doorways */
}
.one-third {
display: inline-block;
vertical-align: top;
box-sizing: border-box;
width: 30%;
padding: 20px;
}
.doorway {
box-sizing: border-box;
width: 100%;
height: 0;
padding-bottom: 71.39364303%;
background-image: url('https://placehold.it/409x292');
background-size: contain;
border: 1px solid #000;
font-size: 1rem; /* reset font-size */
}
<div class="textwidget">
<div class="one-third">
<div id="doorway1" class="doorway">
<h3>The Best Core Exercise Ever</h3>
<div class="doorway-action">
Watch Video Now
</div>
</div>
</div>
<div class="one-third">
<div id="doorway2" class="doorway">
<h3>Core Strength Level 1 Program</h3>
<div class="doorway-action">
Watch Video Now
</div>
</div>
</div>
<div class="one-third">
<div id="doorway3" class="doorway">
<h3>Cardio Program</h3>
<div class="doorway-action">
Watch Video Now
</div>
</div>
</div>
</div>

You need to set the background-size to contain
#doorway1,
#doorway2,
#doorway3 {
background-size: contain;
}

I believe that you can use img {max-width:100%} to make the images scale down responsively. Then as for scaling down the divs, I cannot see why it would be necessary. div tags don't serve a purpose on their own, and are only important because of the content you put inside of it. The links will remain the size of the image, no matter what size the image is. This is because the link is represented by the image.
But, if you displayed the content you need to manipulate, h3, etc. as block elements, which should allow you to set the dimensions using
.doorway h3{ //h3 is a child element of the class doorway
display: block;//Or "inline-block", if you are using inline currently
//Then you should be able to set the max-width or max-height whatever the case may be
max-height: xx%;
}
The reason that using the percentage value you wer using is because saying height: 71% does not mean height: 71% of width It actually means height: 71% of the viewport or the size of the device screen / window (depending on the way you set the viewport) so you could calculate what the amount of viewport you want the content to take up is, 3 images so roughly 33.33% for all 3 to take up all of the screen or you can use different units like pixels, which works less kindly with RWD (Responsive Web Design) but it can work if you use 'max' and 'min' for the width, as well as make some other accommodations, such as using percentages everywhere where it can be used.
I truly hope this helped or at least points you toward the answers you are looking for.

You have two choices :
This working for responsive (You keep the full image, no crop) :
img {
max-width: 100%;
height: auto;
}
This working for backgroud image (The image will crop) :
div { background-size: contain; }
Else you can have a look to some jquery plugins that auto resize an html element depending the window height/width.

Related

Display image original size, if possible, else shrink

There are lots of questions on this general subject, but none that do what I need.
I need to present multiple images, each in a div of its own, but I have no prior knowledge of whether they're portrait, landscape, or low resolution. What I want to do is show them original size (and centered) if they will fit (i.e. I don't want to stretch a low-resolution image), but if they're larger than the div then shrink them appropriately according to their aspect ratio.
This sounds simple but I gave up with the img element, and solutions suggesting width:100%;height:auto; were neglecting the fact that this presumes a landscape image.
I started using background properties and had much more success. If I could make this work then it would have the added benefit that it worked with IE11 too. For instance:
background-image: url("http://example.jpg");
background-position:center center;
background-size: auto;
background-repeat: no-repeat;
works fine if the image is smaller than the div, but crops the image if the original size is too large.
Is there a way to scale the size appropriately in this case (as with background-size:contain), but display original size when possible?
I think you can achieve what you want with a combination of the two properties: max-width: 100% and max-height: 100%:
.container {
display: flex;
}
.item {
margin: 1rem;
width: 200px;
height: 200px;
border: 1px solid;
display: flex;
}
img {
max-width: 100%;
max-height: 100%;
margin: auto;
}
<div class="container">
<div class="item">
<img src="https://via.placeholder.com/150x150" />
</div>
<div class="item">
<img src="https://via.placeholder.com/300x200" />
</div>
<div class="item">
<img src="https://via.placeholder.com/200x300" />
</div>
</div>
1st item: image is smaller, keeps its original size.
2nd item: image is landscape, shrinked to fit.
3rd item: image is portrait, shrinked to fit.
Is this what you needed?

How to reposition div on decrease in screen size with css?

I have been trying to build a website having a 3 column layout. All of the body is given a margin:0 auto to keep it at the centre, and has a minimum width of 1218px.
Now, what I want to do is reposition the right column in such a way the it goes below the left column without affecting the centre column. A live example would be twitter home page, where at the left I can see my profile and trends, the centre column features the tweets and the right column shows suggestions on a 1366x768 screen, now if I change the screen size to 1024x768, the column of suggestions at right goes down below the left column but the central timeline is unaffected.
The definition would be:
<div class="containter" style="margin:0px auto;">
<div class="left-col" style="width:290px; float:left;">Left Stuff goes here </div>
<div class="center-col" style="width:590px; float:right;"> Center body </div>
<div class="right-col" style="width:290px; float:right;">right Stuff goes here </div>
</div>
Now note that the central column has a right float, copied from twitter.
I can't use media queries for that since the website is going to deal with a lot of old browsers and also I would like to avoid JavaScript if possible.
Any help?
You can't do that with "min-width" of the main container. You must use "max-width" since you want to make sure something happens when the screen width gets more narrow. And the main column (in the center) has to be left-floated, not right. Here's a possible solution. However the whole questions seems weird to me since you want to make a responsive layout in an old browser that doesn't support responsive CSS.
<style>
.container {
max-width: 1218px;
}
.leftColumn {
float: left;
width: 300px;
height: 500px;
background-color: brown;
}
.mainColumn {
float: left;
width: 700px;
height: 500px;
background-color: darkgreen;
}
.suggestions {
float: left;
width: 218px;
height: 500px;
background-color: darkorange;
}
.cleaner {
clear: both;
}
</style>
<div class="container">
<div class="leftColumn">
LEFT
</div>
<div class="mainColumn">
MAIN
</div>
<div class="suggestions">
SUGGESTIONS
</div>
<div class="cleaner"></div>
</div>

Relative Sizing with a Fixed Position

The best example I can find of what I'm trying to achieve with my current website project is the amazon homepage.
I want the width of a banner on my page to be 100% of the browser width, but I don't need it to resize when the window is resized. In addition, I would like the entire page to not resize and instead cut off/have scroll bars.
The banner is located at the top of the page, has a hi-res image as the background, and contains my nav bar as well as some text.
What would be the best method to set the size of my percentage based divs relative to screen resolution? Is there a way to set the size of my images without using percentages for size? (div width = screen width).
I'm having issues with divs containing text not resizing correctly, the text gets jumbled when the browser is resized. I'm using html5 and css with dreamweaver cs6.
I think this is what you want.
The header re-sizes but the content stays at a fixed size when page resizes:
https://jsfiddle.net/DIRTY_SMITH/zopnqxry/4/
<div class="header">
</div>
<div class="body">
<div class="left">
</div>
<div class="right">
</div>
</div>
CSS
body{margin: 0; overflow: scroll}
.header{width: 100%; height: 50px; background-color: lightblue;}
.body{width: 400px; height: 600px; background-color: lightgreen; margin-left: auto; margin-right: auto;}
.left, .right{width: 50%; height: 200px; float: left;}
.left{background-color: blue;}
.right{background-color: red;}

Resize Row Heights Depending on Background Image Details in Zurb's Foundation

This is a hard one to explain, so I'll do my best.
As it stands now, I have a wrapper div that has the iceberg image as it's background. It's styled in that the background image sizes to fit the user's screen. Within that wrapper div, I have two .rows, each containing a column.
Now the tricky part: I want one row to just span the top of the water, with the other spanning the bottom of the water. Here's a rough concept.
Right now these rows are given a min-height to match that horizon, however when the user resizes their screen or has a different browser width than my dev environment, of course it doesn't work the same.
Now, how can I go about getting these rows to match heights with the background image? I had considered slicing the image into two, but I imagine there's got to be a much more resourceful way. Here's the CodePen I'm working with: http://codepen.io/jwindeknecht/pen/qOqwPp
If you can offer any advice or if I can clear anything up, let me know! Thanks.
<div class="hero">
<div class="row over">
<div class="large-6 large-offset-6 columns">
<div class="inside">
<h1>Hello World</h1>
</div>
</div>
</div>
<div class="row under">
<div class="large-6 large-offset-6 columns">
<div class="inside">
<h1>Hello World</h1>
</div>
</div>
</div>
</div>
.hero {
background: url(http://i.imgur.com/fdRuNIF.jpg) center top no-repeat;
background-size: cover;
min-width: 100%;
div {
display: table;
.inside {
display: table-cell;
vertical-align: middle;
}
}
}
.over div { min-height: 275px; }
.under div { min-height: 275px; }
Okay! I figured this out. I know the dimensions of the image, so I had the min-height of the row set to a certain percentage of the the width of the image.
e.g. The image is 1500px wide. The row that covers just the horizon is 300px high. Therefor the min-height of the row is set to 20vw.
So regardless of the background image width, the height of the row matches up due to using the vw. Here's a pen example: http://codepen.io/jwindeknecht/pen/RWyBGW
And the new code is simple:
.over div { min-height: 275px; }
to
.over div { min-height: 20vh; }

css text on the image

I have an image which has to take full width. And I need to put a text and a button on top of it in a specific place. I looked over many topics but can not figure out how to make it fully responsive.
<div class"wrapper">
<div class="image-box">
<img src="x">
</div>
<div class="content-box">
<h1>text goes there</h1>
<a>anchor tag goes there</a>
</div>
</div>
so this is the layout but it can be changed if it gets me to the point I need.
If I understand correctly the parent div called wrapper should be set to position: relative and all the child divs to position: absolute, after that you just position all these child elements with top, left, right, bottom. So after testing this this is what I get. Since the image is always 100% of the viewport it gets smaller and smaller by height and width because of its aspect ratio. The text and button on the image just stays at a fixed place and after some point it goes out of the image.
Whats my mistake?
P.S found a lot of topics but still, I am messing something up. Thank you for your insights and help.
The image tag is used to create a separate element on the page. This is not really what you want... you want the content-box to have a background, right? Rather than using the image tag, use CSS to apply a background image.
here is a jsfiddle
.content-box {
/* set width and height to match your image */
/* if these are omitted, it will only be as big as your content, */
/* and only show that much of your image */
width: 200px;
height: 300px;
/* obviously, replace this with your image */
background:url('http://placecage.com/200/300');
}
<div class"wrapper">
<div class="content-box">
<h1>text goes there</h1>
<a>anchor tag goes there</a>
</div>
</div>
I think this is what you want. Also, this is a good occasion to use those HTML5 tags figure
and figcaption, but basically all you need is this kind of structure:
<div class="wrapper">
<img />
<div class="content-box">
<!-- Your content here -->
</div>
</div>
So what is happening here is that your wrapper's dimensions are fixed by the image, and then you position absolutely your content-box or the elements within. If you do not want to position them at the very top or bottom of your image, just use percentage values when positionning:
top: 10%;
figure {
position: relative;
}
figure img {
width: 100%;
height: auto;
}
figure figcaption {
position: absolute;
top: 0;
left: 0;
right: 0;
margin: 0;
background: rgba(255,255,255,.7);
padding: 10px;
}
<figure>
<img src="http://www.jpl.nasa.gov/spaceimages/images/mediumsize/PIA17011_ip.jpg" />
<figcaption>
<h1>The image title</h1>
<p>This is the image caption</p>
</figcaption>
</figure>

Resources