{"componentChunkName":"component---src-templates-post-jsx","path":"/blog/4-css-layouts-without-using-media-queries/","result":{"data":{"mdx":{"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nconst _frontmatter = {\n  \"title\": \"4 CSS layouts without using media queries\",\n  \"cover\": \"\",\n  \"date\": \"2020-01-22\",\n  \"type\": [\"tutorial\"]\n};\nconst layoutProps = {\n  _frontmatter\n};\nconst MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  let {\n    components\n  } = _ref,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, `Do you always need media queries to make a website responsive? With flexbox and grid you can make responsive layouts\nwithout having to define fixed breakpoints with media queries. `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://twitter.com/argyleink\"\n  }), `Adam Argyle`), ` recently\nshowed us a tweet-sized example of this in action, where just 13 lines of CSS give you 4 separate layouts.`), mdx(Tweet, {\n    tweetLink: \"argyleink/status/1217213431947747328\",\n    align: \"center\",\n    mdxType: \"Tweet\"\n  }), mdx(\"p\", null, `All four layouts in action in `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://polypane.app\"\n  }), `Polypane`), `:`), mdx(\"video\", {\n    src: \"/blogs/rw-wo-mq/resize.mp4\",\n    autoPlay: true,\n    loop: true,\n    controls: true,\n    className: \"breakout\"\n  }), mdx(\"p\", null, `How does it work? The HTML is surprisingly simple. No wrappers or extra elements:`), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"html\"\n  }, mdx(\"pre\", _extends({\n    parentName: \"div\"\n  }, {\n    \"className\": \"language-html\"\n  }), mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-html\"\n  }), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `<`), `form`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `>`)), `\n  `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `<`), `input`), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `type`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `text`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `placeholder`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `Name`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `/>`)), `\n  `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `<`), `input`), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `type`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `email`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `placeholder`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `Email Address`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `/>`)), `\n  `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `<`), `input`), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `type`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `submit`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-name\"\n  }), `value`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token attr-value\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation attr-equals\"\n  }), `=`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`), `Subscribe`, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `\"`)), ` `, mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `/>`)), `\n`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token tag\"\n  }), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `</`), `form`), mdx(\"span\", _extends({\n    parentName: \"span\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `>`))))), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, `If you want to use this in production, make sure all of these input fields have associated label elements.`)), mdx(\"p\", null, `The CSS that does the heavy lifting is very small too:`), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"css\"\n  }, mdx(\"pre\", _extends({\n    parentName: \"div\"\n  }, {\n    \"className\": \"language-css\"\n  }), mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-css\"\n  }), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token selector\"\n  }), `form`), ` `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `{`), `\n  `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token property\"\n  }), `display`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `:`), ` flex`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `;`), `\n  `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token property\"\n  }), `flex-wrap`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `:`), ` wrap`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `;`), `\n\n  `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token selector\"\n  }), `& > input`), ` `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `{`), `\n    `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token property\"\n  }), `flex`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `:`), ` 1 1 10ch`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `;`), `\n    `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token property\"\n  }), `margin`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `:`), ` 0.5rem`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `;`), `\n\n    `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token selector\"\n  }), `&[type='email']`), ` `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `{`), `\n      `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token property\"\n  }), `flex`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `:`), ` 3 1 30ch`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `;`), `\n    `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `}`), `\n  `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `}`), `\n`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `}`)))), mdx(\"p\", null, `That's 13 rows, blank rows included!`), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"em\", {\n    parentName: \"p\"\n  }, `What's that `, mdx(\"code\", _extends({\n    parentName: \"em\"\n  }, {\n    \"className\": \"language-text\"\n  }), `&`), ` doing there?`), ` `, mdx(\"br\", null), `\nAdam wrote this using `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://preset-env.cssdb.org/\"\n  }), `postcss-preset-env`), `, which is \"Babel for CSS\". It lets you write\nCSS using upcoming specs (like nesting) and compiles it to regular CSS.`)), mdx(\"h2\", {\n    \"id\": \"so-what-does-this-css-do\"\n  }, `So what does this CSS do?`), mdx(\"p\", null, `The styling for the form and input elements work in tandem to create the different layouts, so we'll go through\ntheir CSS properties one by one. Lets start with the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `form`), ` element.`), mdx(\"h3\", {\n    \"id\": \"the-form\"\n  }, `The form`), mdx(\"p\", null, `The form is set to `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `display:flex`), ` so has a flex layout. By default, that's a horizontal flex layout where all items fit a single row.`), mdx(\"p\", null, `By adding `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-wrap: wrap`), `, you specify that the flex layout can wrap to multiple rows if the elements don't fit a single row. Each of those rows will\nbehave as their own flex layout, which this code uses to its advantage.`), mdx(\"h3\", {\n    \"id\": \"the-inputs\"\n  }, `The inputs`), mdx(\"p\", null, `The meat of this technique lies in the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex`), ` property on the inputs. The `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex`), ` property takes three values (e.g. `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `1 1 10ch;`), `) and is shorthand for three CSS properties:`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow`)), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-shrink`)), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-basis`))), mdx(\"p\", null, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow`), ` applies when there is more space in the surrounding element (the form in this case) than the elements\nneed. It take a positive number (or 0). The number indicates what part of the total an element takes.`), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, `The \"part of the total\" is best illustrated with an example. Say there are two elements, both having `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow: 1`), `. They will both be equally wide at 1/2 of the total width. But if the second element has `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow: 2`), `, the total number of parts is 1 + 2 = 3. The first item will then be 1/3rd of the total width, and the second element will be 2/3rd of the total width.`)), mdx(\"p\", null, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-shrink`), ` works much in the same way, except that it is used when there is `, mdx(\"em\", {\n    parentName: \"p\"\n  }, `less`), ` space than the elements would normally take up. Here, a higher number means it ends up being smaller.`), mdx(\"p\", null, `In flexbox terminology, if the elements combined take up more space than available, their `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flexibility`), ` is set to `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `shrink`), `.\nOtherwise it is set to `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `grow`), `. This is not something you set explicitly, but is useful to know when working with flex layouts.`), mdx(\"p\", null, `In our 4-layout example `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-wrap`), ` is set to `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `wrap`), `, which means that the flexibility will never be\nset to shrink. Instead, elements will wrap to the next row if they don't fit.`), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, `At this point, I have to admit that the calculation example I gave for the flex-grow value was a little simplified. It works that way only\nif the last property, `, mdx(\"code\", _extends({\n    parentName: \"em\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-basis`), `, is set to 0. Normally, flex-basis is set to `, mdx(\"code\", _extends({\n    parentName: \"em\"\n  }, {\n    \"className\": \"language-text\"\n  }), `auto`), `, which makes things a little more complicated.`)), mdx(\"p\", null, `When `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-basis`), ` is set to `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `auto`), `, the number set for `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow`), ` and `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-shrink`), ` also take into account the width of the element, either the implicit\nwidth (called the 'content size') or an explicit `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `width`), `. So two elements that both have `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow:1`), ` might not end up being equally wide, if one of\nthem has much more content.`), mdx(\"p\", null, `You can also set `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-basis`), ` to a value. In that situation, the initial size of an element is set to that value. In this layout, the \"name\" field and the button both get a value of `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `10ch`), `, and the \"email\" field is set to `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `30ch`), `.`), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"em\", {\n    parentName: \"p\"\n  }, `What's a `, mdx(\"code\", _extends({\n    parentName: \"em\"\n  }, {\n    \"className\": \"language-text\"\n  }), `ch`), `?`), ` `, mdx(\"br\", null), `\nOne `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `ch`), ` is equivalent to the width of the \"0\" character in a font.`)), mdx(\"p\", null, `The effect of this is that the name input and the button are initially 10ch wide, and the email field is 30ch wide. Because we are in a flex layout, that `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-basis`), ` value is used as the starting point for the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow`), ` or `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-shrink`), ` value. Think of them as multipliers for the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-basis`), ` value.`), mdx(\"p\", null, `In this layout the \"name\" field and the button both have a `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow`), ` of 1, a `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-shrink`), ` of 1 and a `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-basis`), ` of `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `10ch`), `. The e-mail field has a `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow`), ` of 3, a `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-shrink`), ` of 1 and a `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-basis`), ` of 30ch.`), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `In other words`), `, the email field starts out 3 times as wide as the other field, `, mdx(\"em\", {\n    parentName: \"p\"\n  }, `grows`), ` three times as fast but `, mdx(\"em\", {\n    parentName: \"p\"\n  }, `shrinks`), ` at the same rate.`), mdx(\"h2\", {\n    \"id\": \"how-does-that-get-us-to-4-layouts\"\n  }, `How does that get us to 4 layouts?`), mdx(\"p\", null, `That's where the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-wrap`), ` comes into play. When elements do not naturally fit side-by-side, they go to the next row. Let's go layout-by-layout from small to large and see what happens.`), mdx(\"h3\", {\n    \"id\": \"the-smallest-layout\"\n  }, `The smallest layout`), mdx(\"img\", {\n    alt: \"Screenshot of first layout\",\n    src: \"/blogs/rw-wo-mq/i1.png\",\n    className: \"imgshadow\"\n  }), mdx(\"p\", null, `The three elements are stacked vertically. Here's what happens:`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, `There is not enough space to have all three elements side-by-side (their total is 50ch wide, 10 + 30 + 10), so elements will wrap to the next row.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Two of them together (either name and email, or email and button) also don't fit, so the end result is that all of them are on their own row.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `We end up with three rows.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Each row is it's own smaller flex layout, and each element on a single row is smaller than the total width.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `All of them have a positive `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow`), ` value, and don't share their row with other element, so all of them grow to the full width of their own row.`)), mdx(\"h3\", {\n    \"id\": \"the-second-layout\"\n  }, `The second layout`), mdx(\"img\", {\n    alt: \"Screenshot of second layout\",\n    src: \"/blogs/rw-wo-mq/i2.png\",\n    className: \"imgshadow\"\n  }), mdx(\"p\", null, `The name field takes the full width, and the email and subscribe button are on row together. Here's what happens:`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, `There is not enough space to have all three elements side-by-side, so elements will wrap to the next row.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"em\", {\n    parentName: \"li\"\n  }, `Things get sneaky.`), ` Even though the name field and the button have the same flex values, a `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `button`), ` type element has a slightly different content size, so ends up being slightly smaller than a regular input field. `, mdx(\"em\", {\n    parentName: \"li\"\n  }, `Browsers, right?`)), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Name + email don't fit on a single row so email wraps to the next row. Because of the tiny difference, email + button `, mdx(\"em\", {\n    parentName: \"li\"\n  }, `do`), ` fit on a single row.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `We end up with two flex rows.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `The first row has just the name, so that takes full width because of `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `flex-grow`), `.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `The second row is wider than both the email field and button combined, so flex-grow is used to make them fill up the width, the email field at a much bigger ratio compared to the button.`)), mdx(\"p\", null, `If the last element was not a button, this layout wouldn't be possible.`), mdx(\"h3\", {\n    \"id\": \"the-third-layout\"\n  }, `The third layout`), mdx(\"img\", {\n    alt: \"Screenshot of third layout\",\n    src: \"/blogs/rw-wo-mq/i3.png\",\n    className: \"imgshadow breakout\"\n  }), mdx(\"p\", null, `The name field and email field are shown side by side, with the button below it. What happens:`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, `There is not enough space to have all three elements side-by-side so elements can wrap to the next row.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `The name and email fields fit side by side, so it's just the button that wraps to the next row.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Name and email fill out the first row in their flex-grow/flex-basis ratio, and the button fills out the second row completely.`)), mdx(\"h3\", {\n    \"id\": \"the-fourth-layout\"\n  }, `The fourth layout`), mdx(\"img\", {\n    alt: \"Screenshot of fourth layout\",\n    src: \"/blogs/rw-wo-mq/i4.png\",\n    className: \"imgshadow breakout\"\n  }), mdx(\"p\", null, `This is the simplest layout. The total width is wider than all elements, so they're distributed on a single row in their respective ratio.`), mdx(\"p\", null, `But what about that button? You'd expect it to be as wide as the name field, since they have the same flex value. But here's where the sneaky thing from the second layout comes into play again: the content size of the button is less wide and so ends up being smaller.`), mdx(\"h2\", {\n    \"id\": \"responsive-websites-without-media-queries\"\n  }, `Responsive websites without media queries?`), mdx(\"p\", null, `Recreating this layout with media queries is possible but would take you 3 breakpoints at set widths and only works when the form is the full width of the page.`), mdx(\"p\", null, `With this flexbox solution you can place the form element anywhere and it will fit the element it's in, giving you even more flexibility than just media queries would give you.`), mdx(\"p\", null, `Using modern layout algorithm like flexbox and grid give you a lot of extra flexibility when it comes to the way your elements are laid out without needing to explicitly define them. As you can see, they let you do some pretty powerful things!`));\n}\n;\nMDXContent.isMDXComponent = true;","timeToRead":5,"tableOfContents":{"items":[{"url":"#so-what-does-this-css-do","title":"So what does this CSS do?","items":[{"url":"#the-form","title":"The form"},{"url":"#the-inputs","title":"The inputs"}]},{"url":"#how-does-that-get-us-to-4-layouts","title":"How does that get us to 4 layouts?","items":[{"url":"#the-smallest-layout","title":"The smallest layout"},{"url":"#the-second-layout","title":"The second layout"},{"url":"#the-third-layout","title":"The third layout"},{"url":"#the-fourth-layout","title":"The fourth layout"}]},{"url":"#responsive-websites-without-media-queries","title":"Responsive websites without media queries?"}]},"excerpt":"Do you always need media queries to make a website responsive? With flexbox and grid you can make responsive layouts\nwithout having to define fixed breakpoints…","frontmatter":{"title":"4 CSS layouts without using media queries","cover":"","date":"2020-01-22","updated":null},"fields":{"slug":"/blog/4-css-layouts-without-using-media-queries/","date":"2020-01-21T23:00:00.000Z","ogFileName":"4-css-layouts-without-using-media-queries"}}},"pageContext":{"slug":"/blog/4-css-layouts-without-using-media-queries/"}},"staticQueryHashes":["4164364741","425175329"]}