Cosinux Cosinux - 9 months ago 40
CSS Question

Responsive image size and position in CSS

I'm designing a simple website in HTML and CSS but got stuck. I'd like my website to have an image at the top. Any content that comes after that image should appear underneath the image, not on top of it (like it does with a background image). The image should be 0.6 (or some other fraction) the height of the viewport and centered. Any overflowing part should be cropped. However, in case the image is too narrow, it should be resized to fill the whole width of the viewport. It should never change its apect ratio. I'd also like to keep my site script-free and would like to have no absolute values (like

px
) in my source files.

Here are some doodles I made to explain my idea:

Image height is set to 0.6vh. It is centered. The overflowing areas are cropped. Text starts at the bottom.
case 1

Image height would be set to 0.6vh but it wouldn't cover the whole viewport's width. Instead, set the image width to match the viewport width (equal to the width of the page), ignoring the 0.6vh rule. Text still starts at the bottom.
case 2

I've been searching the internet for two days already but I couldn't really find quite what I need.

Additionaly, I am trying to solve this problem: currently, I am using
vh
to set the height of the image, but it gets weird when viewing on a mobile browser, because the value of
vh
changes when the address bar collapses.

[EDIT]

Rule:


  1. The minimum width of the image should be the width of the viewport.

  2. Then, if it's possible, it's height should match 0.6
    vh
    .



[EDIT 2]

I noticed that the answers work great by centering an image and keeping it's aspect ratio. But the image shouldn't be cropped vertically.

Another doodle:

I hope this doodle makes it easier to see what I am trying to achieve. Red line indicates the "0.6vh rule" while blue line represents the "mininimal width equals viewport width" rule. Green rectangle shows where the image should be.
case 3

[EDIT 4]

I added an image and some comments to the previous image:
case 4

Answer Source

Rather than using an image tag, try setting its properties in CSS. It's easier to maintain aspect ratio and centering this way. You may also want to specify a minimum and maximum height property to ensure things look nice.

    body{
      margin: 0; /* Stripping out margin and padding so .bg can be full width*/
      padding: 0;
    }
    .bg {
      box-sizing: border-box; 
      display: block; 
      width: 100%;  
      height: 60vh; /* 60vh = 60% of the viewport height*/
      padding: 0; /* No padding */
      margin: 0; /* No margins */
      background-image: url('http://www.naturheilpraxis-kaelin.ch/bilder/fruehling-01.jpg'); 
      background-repeat: no-repeat;
      background-position: center center;  
      background-size: cover; /* Cover all available space. */ 
      /* If you want the whole image visible try 'contain'*/
    }
    .main{
      padding: 0 1em; /* L/R padding to look nice */
    }
  <body>
  <div class="bg"></div>
  <article class="main">
  <h1>Your rad site</h1>
  <p>Notice how the image is centered and it keeps its aspect ratio.</p>
  </article>
  </body>


[EDIT]

Okay! So here's the best I can do.
This doesn't crop anything vertically and there's no JS or hard values BUT you do have to use an aspect ratio media query that you need to figure out based on your image.

This is the formula for the aspect ratio media query Where H = image height, W = image width and D = percent of the viewport used (expressed as a decimal).

H / (W / (D))

For example, the image I used is 1000px x 300px. We're using 60% of the viewport so D = .6.
So 1000 / (300 / (.6)) >> 1000 / 500 >> 2/1 ratio.

body,html,.container{
  margin: 0;
  padding: 0;
}
.container {
  position: relative;
  overflow: hidden;
  height: 60vh;
}

img {
  position: absolute;
  /* Position the image in the middle of its container. */
  /* Hack*/
  top: -9999px;
  right: -9999px;
  bottom: -9999px;
  left: -9999px;
  margin: auto;
  min-height: 100%;
  height: 100%;
}

@media only screen and (min-aspect-ratio:
2/1) { 
/*  Aspect ratio determined like so -- H / (W * (10/6)) */ 
  .container img{
    position: relative; /*Undoing the hack basically*/
    right: auto;
    top: auto;
    left: auto;
    bottom: auto;
    width: 100%; /*rather than the width get cropped, it's full. height is auto*/
}
  .container {height: auto; /* the image height determines the height */}
}
<div class="container">
    <img src="http://placehold.it/1000x300" alt="" />
</div>

Make it full page and resize the browser to see how the image adapts. I really hope that helps!