css

responsive-design

viewport

I've created a few responsive sites but am rather new to responsive site development. In my CSS 99% of my values are in ems or percentages. I am using media queries (both max-width and max-device-width) to make layout changes. I have not included a viewport meta tag and it works perfectly on iOS, a number of Android phones and tablets that I tested on, and all desktop browsers.

Adding a meta tag breaks my site. Am I doing something wrong, or doing something right so that I don't need to include it? I'm confused as to why it seems to be a best practice, as it's breaking my stuff.

Am I missing something?

Solution 1

On desktop operating systems, browser viewports are a fixed number of pixels wide, and web page content is rendered into them as-is.

Starting with Safari on iOS (or whatever we were supposed to be calling iOS back then), mobile browser viewports have been "virtual". Although the viewport may only take up (for example) 320 physical pixels-worth of space in the interface, the browser creates a "virtual" viewport that's larger (980 pixels wide by default on iOS, I think) and renders content in there, then zooms that virtual viewport out until it fits into the actual physical pixels available on the devices screen.

The viewport meta tag allows you to tell the mobile browser what size this virtual viewport should be. This is often useful if you're not actually changing your site's design for mobile, and it renders better with a larger or smaller virtual viewport. (I believe 980 pixels was chosen as the default because it did a good job of rendering lots of high-profile sites in 2007; for any given site, a different value might be better.)

Personally, I always use <meta name="viewport" content="width=device-width, initial-scale=1"> so that the virtual viewport matches the device dimensions. (Note that initial-scale=1 seems to be necessary to make the virtual viewport adapt to landscape mode on iOS.) That makes mobile browsers behave like desktop browsers always have, which is what I'm used to.

Without a viewport meta tag, your site will be rendered into the device's default virtual viewport. I don't think that's necessarily a problem, especially if all your units are ems or percentages as you say. But it might be a bit confusing if you need to think in pixels at any point, especially as different browsers could have differently-sized default virtual viewports. It also might be confusing for subsequent maintainers if they don't understand the approach.

I imagine you set your base font size quite large, so that it's legible? Could you link to one of the websites you've created like this, so we can see an example?

Solution 2

Without viewport your device uses a virtual viewport which by default is effectively a zoomed out version of your website, this is around 980 px on iPhone and 800px on andriod. As soon as you set the viewport and disable this zooming out, the device treats the website as it should and measures out at around 480px wide or 320px depending on device and orientation etc.

Full resource here below, my advice is that whenever your working with responsive & mobile, always set the viewport first. It is the best way to normalise device zoom and ensure your site is shown using an actual device width as opposed to any virtual widths.

http://www.javascriptkit.com/dhtmltutors/cssmediaqueries3.shtml

Solution 3

So to answer my own question. It is not necessary.

You can use min and max width media queries to style the desktop version at specific breakpoints.

You then update primarily font-size and other properties specifically for tablets and phones. Like I said this is primarily increasing font-size for readability.

This method though has a major maintainability issue.

The viewport meta tag allows you to simply use max and min-width that span from desktop to mobile devices.

Solution 4

You should definitely use viewport tags, as they have the ability to make a web developers life infinitely simpler. They allow you to easily control the exact render dimensions and/or zoom levels of ANY screen (even on desktop if you want). That makes building a website for any device a piece of cake. But know that with great power comes great responsibility. Use this power wisely (and do not DISABLE zooming).

Solution 5

Not for all devices, but yes for Mobiles. Mobile browsers render pages in a virtual "window", the viewport which is usually wider than the screen so they don't need to squeeze every page layout into a tiny window (hence it breaks some non-mobile-optimized sites & users have to zoom). Mobile Safari introduced the "viewport meta tag" to let web developers control the viewport's size and scale. Now all mobile browsers support this tag even though it is not part of any web standard. A typical mobile-optimized site should contain the following tag:

<meta name="viewport" content="width=device-width, initial-scale=1">

The width property controls the size of the viewport. Width of the screen in CSS pixels at a scale of 100%,The initial-scale property controls the zoom level when the page is first loaded. The maximum-scale, minimum-scale, and user-scalable properties control how users are allowed to zoom the page in or out.

https://developer.apple.com/library/prerelease/ios/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html#//apple_ref/doc/uid/TP40006509-SW19

Solution 6

You can still use the viewport metatag to optimize the resolution to the device view and able the user to Zooming:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0
">

With a maximum-scale defined you can have control how the user Zoom it. I thing we should have this option enable because even with a responsive website I wish to Zoom, it learn that already, it's so intuitive that becomes expectation.

Solution 7

Yes it is a necessary tag for developing responsive sites.However using the tag alone won't help you to do so,but they definitely do make it easier to develop responsive sites by allowing you to control the size of the visible content of your webpage.

Solution 8

For whomever is in doubt, the easiest way is to test without it. I did so and came to a swift resolution - if I had to keep just one meta tag, this would be it (above 'description' and whatever). Actually if I had to choose between just this one and all others, I'd give and all away. Just test it!

Solution 9

Yes, it is required. When people started browsing on desktop browsers (in the 1990s), everyone had a low screen resolution, like 640×480 or 800×600.
But then, in 2007, the iPhone was released. It had a screen resolution of 320×480, which was less than most desktop screens at the time. So consider the following HTML code:

<!DOCTYPE html>
<html>
<img src="/reallylargeimg.jpeg" style="width:640; height:480;" />
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ex, sagittis id erat nec, imperdiet posuere erat. Mauris pharetra neque quis venenatis sagittis.</p>
</html>

Then, because the image is really large, the Web page was larger than the iPhone. Additionally, it uses static width and height.

So they scaled down the page. It looks really bad without the viewport tag, like above.

Apple also released the viewport tag. Here, you can set a custom device width: <meta name="viewport" content="width=200px" />

This sets the screen width to 200 pixels. A more widely used solution is:

<meta name="viewport" content="width=device-width" />

which sets the width to the screen width.

But we also want to control the scale. Here's how: add the "initial-scale" property. We have something like this:
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
Without this tag, websites look really small, forcing the user to zoom in. But with that tag, everything is solved.

So yes, the meta viewport tag should be used on all websites and is mandatory if you want a good user experience. You may also need to use media queries to change CSS for different screen widths, like collapsing a menubar into a hamburger menu. The meta viewport tag won't do this for you, but you should.

@media only screen and (max-width: 600px) {
  #hamburgermenu {
    display:block;
  }
  #menubar {
    display:none;
  }
}
@media only screen and (min-width: 600px) {
  #hamburgermenu {
    display:none;
  }
  #menubar {
    display:block;
  }
}

So the finished page should look something like this. It's a crude example of a Web site, but it should work as expected: showing a menu at 600px and showing a menubar above 600px.

var coll = document.getElementsByClassName("collapsible");
var i;

for (i = 0; i < coll.length; i++) {
  coll[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var content = this.nextElementSibling;
    if (content.style.display === "block") {
      console.log('closed!');
      content.style.display = "none";
    } else {
      content.style.display = "block";
      console.log('opened!');
    }
  });
}
@media only screen and (max-width: 600px) {
  #hamburgermenu {
    display: block;
  }
  #menubar {
    display: none;
  }
}

#hamburgermenu {
  position: fixed;
  top: 0;
  width: 100%;
  background-color: aqua;
  border: 1px solid black;
}

@media only screen and (min-width: 600px) {
  #hamburgermenu {
    display: none;
  }
  #menubar {
    display: block;
  }
}

li {
  list-style: none;
  cursor:pointer;
}

li::before {
  content: "  ";
  user-select: text;
  -o-user-select: text;
  -ms-user-select: text;
  -moz-user-select: text;
  -webkit-user-select: text;
}

::selection {
  background-color: #b3d4fc;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<head>
  <!--over here-->
  <meta name="viewport" content="width=device-width,initial-scale=1.0" />
  <title>demo</title>
</head>

<body>
  <div id="hamburgermenu">
    <button class="collapsible">Open Menu</button>
    <ul style="display:none;">
      <li onclick="console.log('option 1!'); alert('1');">Option 1</li>
      <li onclick="console.log('option 2!'); alert('2');">Option 2</li>
      <li onclick="console.log('option 3!'); alert('3');">Option 3</li>
    </ul>
  </div>
  <div id="menubar">
    <button onclick="console.log('option 1!'); alert('1');">Option 1</button>
    <button onclick="console.log('option 2!'); alert('2');">Option 2</button>
    <button onclick="console.log('option 3!'); alert('3');">Option 3</button>
  </div>
  <br>
  <p>Resize the window to see the media query effect.
  </p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ex, sagittis id erat nec, imperdiet posuere erat. Mauris pharetra neque quis venenatis sagittis.</p>
</body>

</html>