Lab 3: CSS Responsive design

The three key principles to responsive design:

  1. A mobile first approach to design. This means you build the mobile version before you construct the desktop layout.
  2. The @media at-rule. With this rule, you can tailor your styles for viewports of different sizes. This syntax (often called media queries) lets you write styles that only apply under certain conditions.
  3. The use of fluid layouts. This approach allows containers to scale to different sizes based on the width of the viewport.
breakpoint: a particular point at which the page styles change to provide the best possible layout for the screen size.

The viewport meta tag: is an HTML tag that tells mobile devices you've intentionally designed for small screens. Without it, a mobile browser assumes your page is not responsive, and it will attempt to emulate a desktop browser.

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

The meta tag's content attribute indicates two things. First, it tells the browser to use the device width as the assumed width when interpreting the CSS, instead of pretending to be a full size desktop browser. Second, it uses initial-scale to set the zoom level at 100% when the page loads.

I. Media queries

Media queries: allow you to write a set of styles that only apply to the page under certain conditions.

Media queries use the @media at-rule to target devices that match a specified feature.

The @media rule is a conditional check that must be true for any of these styles to be applied to the page.

You can further refine a media query by joining the two clauses with the keyword and (second example). This combined media query only targets devices that meet both criteria.

If you want a media query that targets one of multiple criteria, use a comma (third example). This example targets both viewports 560px and narrower and those 1200px and wider.

CSS

@media (min-width: 560px) { ....}

@media (min-width: 560px) and (max-width: 1200px) { .... }

@media (max-width: 560px), (min-width: 1200px) { .... }

min-width targets devices with a viewport above a certain width, and max-width targets devices below a certain width are each called a media feature.

min-width and max-width are the most common ones you will use by far. But you can also use a number of other types of media features.
Here are some examples:

  • (min-height: 500px): Targets viewports 500px and taller;
  • (max-height: 500px): Targets viewports 500px and shorter
  • (orientation: landscape): Targets viewports that are wider than they are tall;
  • (orientation: portrait): Targets viewports that are taller than they are wide;
  • (min-resolution: 2dppx): Targets devices with a screen resolution of 2 dots per pixel or higher; targets retina displays;
  • (max-resolution: 2dppx): Targets devices with a screen resolution of up to 2 dots per pixel

TIP 1: You can also place a media query in the <link> tag. Adding <link rel="stylesheet" media="(min-width: 500px)" href="large-screen.css" /> to your page will apply the contents of the large-screen.css file to the page only if the min-width media query is true. Note that the stylesheet will always download, regardless of the width of the viewport, so this is merely a tactic for code organization, not network traffic reduction.

TIP 2: The two media types you will generally need to think about are screen and print. Using a print media query lets you control how your page will lay out if the user prints the page, so you can do things like removing background images (to save on ink) and hiding unneeded navigation. When a user prints the page, they typically only want the main page text.

To write print styles that apply only when printing, use the query @media print. To target screen only, use @media screen.

Always be sure each media query comes after the styles it overrides, so the styles within the media query take precedence.

II. Responsive images

The best practice is to create a few copies of an image, each at a different resolution.

Use the srcset attribute (short for “source set”). This attribute is a newer addition to HTML. It allows you to specify multiple image URLs for one <img> tag, specifying the resolution of each. The browser will then figure out which image it needs and download that one.

Most browsers now support srcset, but those that don't will fall back to the specified src, loading whichever URL is specified there. This

HTML

<img alt="Oran-pic"
src="IMAGES/Oran.jpg"
srcset="IMAGES/Oran-small.jpg 560w,
IMAGES/Oran-medium.jpg 800w,
IMAGES/Oran-big.jpg 1280w"
/>

III. Example

In this example, we will create a responsive navigation bar.

The navigation bar will have a logo on the right, and menu items on the left. When the viewport is wide, the menu items will be displayed horizontally.

The menu items will be displayed horizontally when the viewport is large.

When the viewport is narrow, the menu items will be hidden (right: -100%; opacity: 0;) and a burger menu icon will appear instead (.Menu_Icon {display: block;...).

When the user clicks on the burger menu icon, the menu items will appear (.Nav_Bar_Menu {right: 0; opacity: 1;...).

The clicking on the burger menu icon need to be handled by JavaScript. You can find the code here.

HTML

<nav class="Nav_Bar_Items">
<h1 class="Nav_Bar_Logo">سياحة</h1>
<div class="Menu_Icon" id="Menu_Icon_ID">
<i class="fas fa-bars" id="Burger_Icon_ID"> </i>
</div>
<ul class="Nav_Bar_Menu" id="Nav_Bar_Menu_ID">
<li>
<a href="#" class="Nav_Bar_Menu_Item">
<span>إتصل بنا</span>
<i class="fa-solid fa-envelope"> </i>
</a>
</li>
<li>
<a href="#" class="Nav_Bar_Menu_Item">
<span>جميع الخدمات</span>
<i class="fa-solid fa-briefcase"> </i>
</a>
</li>
<li>
<a href="#" class="Nav_Bar_Menu_Item">
<span>من نحن؟</span>
<i class="fa-solid fa-circle-info"> </i>
</a>
</li>
<li>
<a href="#" class="Nav_Bar_Menu_Item">
<span>الرئيسية</span>
<i class="fa-solid fa-house"> </i>
</a>
</li>
</ul>
</nav>

CSS

@media screen and (max-width: 850px) {
Nav_Bar_Menu {
display: flex;
flex-direction: column;
right: -100%;
opacity: 0;
}

.Menu_Icon {
display: block;
cursor: pointer;
}

.Nav_Bar_Menu.active {
right: 0;
opacity: 1;
}

You can find the CSS code of the responsiveness for this example, here.