Using CSS Media Queries
Tags: css, webdev, beginners
Published: 2019-11-07 20:39:48

In this post I will be diving into the important topic of Media Queries in CSS, providing examples of  elements from my own project that needed mobile optimization and how I approached them. In my [previous post](https://dev.to/milandhar/responsive-react-components-w-semantic-ui-10cn) I covered how to make React components responsive, which allowed me to create a unique user experience for mobile devices. This week's post zooms in to the individual HTML elements within each component that need mobile optimization. I view this process as analogous to responsiveness in React, except it is more manual whereas Semantic UI React has [special props and components](https://react.semantic-ui.com/addons/responsive/) that do much of the work for us.

![Media Query Image](https://www.w3schools.com/css/mqcap.JPG)

##What is a Media Query?
In CSS, a [media query](https://www.w3schools.com/css/css_rwd_mediaqueries.asp) uses the `@media` rule to include certain CSS properties only if a condition is true. Media queries can check several things, like the width or height of a device, the screen's orientation (landscape or portrait), the screen's resolution, and more. 

The syntax for a media query is the following: 
```css
@media not|only mediatype and (mediafeature and|or|not mediafeature) {
  CSS-Code;
}
```
You can find all of the different media types and media features at this [W3Schools page](https://www.w3schools.com/cssref/css3_pr_mediaquery.asp). I most frequently use the "screen" media type and "max-width" media feature for my responsive web development media queries. 

An example of a type of media query I often use is below: 

```css 
@media screen and (max-width: 500px) {
  .container {
    display: block;
  }
}
```
This would change the `display` property to `block` of the element with class of "container" for screen sizes less than or equal to 500px. 

##Adding Media Queries to My Project
A note on the media feature I used - for most of the media queries, I used a `max-width: 767px` feature. I found that setting the breakpoint at 767px max-width allowed me to capture most mobile device sizes (portrait and landscape) for which I needed to adjust CSS properties. I used Chrome DevTools to [simulate different mobile devices](https://developers.google.com/web/tools/chrome-devtools/device-mode) on my website. I highly recommend using the device mode with DevTools for mobile responsiveness media queries.  

In my css file, I grouped most of the media queries I wrote for mobile responsiveness in the following block:

```css
@media only screen and (max-width: 767px) {
  ...
}
```
However, in the examples below I have repeated the query each time for clarity. 

Now let's dive into some real examples of how I used media queries to make elements in [EffectiveDonate](https://mighty-beach-46515.herokuapp.com/) responsive. 
 
###Stacking Elements Using Flexbox Layout
In the "Projects" page of EffectiveDonate, there are dropdowns for countries and themes, allowing the user to filter the types of projects they want to learn about. On desktop screens, it works to have these dropdowns positioned next to each other. However, once the width of the screen shrinks to mobile sizes, the dropdowns become too small to contain all of the content, and they look awkward: 

![Project Dropdowns](https://i.imgur.com/0nqgwVn.png)

To solve this on mobile, I wrote a media query that changes the `display` to "flex" and also associated properties `justify-content` and `align-items` to "center". This style of container is called the "Flexbox Layout". You can learn all about Flexbox in this excellent [CSS-Tricks Guide](https://css-tricks.com/snippets/css/a-guide-to-flexbox/), which walks you through all of the awesomeness of Flexbox. I enjoy using Flexbox when I can, since it is inherently more responsive than other layouts, and just feels more spatially intuitive to me. 

I also increased the width of both of the dropdowns so that the longer countries and themes could be easily readable: 

```css
@media only screen and (max-width: 415px) {
  .ui.grid .project-dropdown-row {
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }

  .project-dropdown-row .country-drop {
    min-width: 70% !important;
  }

  .project-dropdown-row .themes-drop {
      min-width: 70% !important;
  }
}
```

Now the dropdowns are cleanly stacked and easy to read! 
![Project Dropdowns Fixed](https://i.imgur.com/Xp4gzMY.png)


###Make Table Text Wrap

Another component that needed some responsive media queries was my `Profile` section. I have a responsive [Semantic UI Table](https://react.semantic-ui.com/collections/table/) for the user's starred projects that collapses on smaller screens. However, the table's text data would not wrap to the next line, so it cut off key project data on mobile: 
![No-wrap table](https://i.imgur.com/2RVFCJ6.png)

To fix this, I changed the `white-space` and `word-wrap` properties in my media query. `white-space` was previously set to "nowrap", which forced all text in the table to render on one line. [Setting it](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) to "normal" allows text to be broken into multiple lines. Setting `word-wrap: break-word` is self explanatory: it [allows words to be broken up](https://www.w3schools.com/cssref/css3_pr_word-wrap.asp). 

I also wanted the red "X" and green "$" buttons to be easier to click on mobile, so I flipped their `display` to flex and used `justify-content: space-evenly` to spread the buttons out along the container. 

Here are both of the blocks I wrote to solve these issues: 

```css
@media only screen and (max-width: 415px) {
 .ui.table[class*="single line"]  {
    white-space: normal !important;
    word-wrap: break-word;
  }

  #remove-donate-div {
    display: flex !important;
    justify-content: space-evenly;
  }
}
```

Now the entire table content can actually be viewed and the buttons are spread out enough to be clickable on mobile! 

![Wrapped table](https://i.imgur.com/8n1z8UN.png)

###Centering Content
The final example of media queries I will discuss here is a common one that is frustrating if you don't know a quick trick. The way to center text within a container is fairly straightforward (`text-align:center`). But actually horizontally centering an entire container of content is less intuitive. The best way I've learned is to make the `margin-left` and `margin-right` equal to "auto". This effectively equalizes the space to the left and right of the container, ensuring that it is always centered. This is also very responsive design friendly, since the content will be centered as the viewport shrinks.

In my Create User Form, I have a checklist of themes the user can choose as their top three favorites. However, each list item was awkwardly positioned left of center: 

![Uncentered Content](https://i.imgur.com/MM84eGM.png)

To horizontally center each theme `div`, I used the margin trick: 
```css
@media only screen and (max-width: 415px) {
  #fields-div .field {
    margin-left: auto;
    margin-right: auto;
    width: 100% !important;
   }
}
```
I also set the `width` to 100% to ensure the theme text would not wrap. Now the theme checklist is centered and good to go! 

![Centered Content](https://i.imgur.com/WhSFHuU.png)


##Conclusion
While the examples I included in this post represent many common use cases for media queries, there are limitless possibilities. I recommend skimming the list of [Media Features](https://www.w3schools.com/cssref/css3_pr_mediaquery.asp) available just to see the different ways media queries can be used. 

However, now that I've implemented these responsive queries, I feel ready to share [EffectiveDonate](https://mighty-beach-46515.herokuapp.com/). Feel free to check it out and let me know if you have any feedback or see any bugs. Thanks for reading!