1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
|
..
This file is part of m.css.
Copyright © 2017, 2018, 2019, 2020, 2021, 2022, 2023
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
Grid system
###########
:breadcrumb: {filename}/css.rst CSS
:footer:
.. note-dim::
:class: m-text-center
`CSS <{filename}/css.rst>`_ | `Typography » <{filename}/css/typography.rst>`_
.. role:: css(code)
:language: css
.. role:: html(code)
:language: html
Inspired by `Bootstrap <https://getbootstrap.com>`_, the grid system is the
heart of a responsive website layout. The `m-grid.css <{filename}/css.rst>`_
file contains all the setup you need for it, it's completely standalone.
Besides that, in order to have devices recognize your website properly as
responsive and not zoom it out all the way to an unreadable mess, don't forget
to add this to your :html:`<head>`:
.. code:: html
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
.. contents::
:class: m-block m-default
`Overview`_
===========
If you have never heard of it, it all boils down to a few breakpoints that
define how the website is wide on various screen sizes. For every one of them
you can define how your page and content layout will look like. In every case
you have 12 columns and it's completely up to you how you use them. Let's start
with an example.
.. code:: html
<div class="m-container">
<div class="m-row">
<div class="m-col-t-6">.m-col-t-6</div>
<div class="m-col-t-6">.m-col-t-6</div>
</div>
<div class="m-row">
<div class="m-col-s-4 m-col-m-6">.m-col-s-4 .m-col-m-6</div>
<div class="m-col-s-4 m-col-m-3">.m-col-s-4 .m-col-m-3</div>
<div class="m-col-s-4 m-col-m-3">.m-col-s-4 .m-col-m-3</div>
</div>
<div class="m-row">
<div class="m-col-l-7"><div class="m-frame m-center">.m-col-l-7</div></div>
<div class="m-col-l-5"><div class="m-frame m-center">.m-col-l-5</div></div>
</div>
</div>
.. raw:: html
<div class="m-row">
<div class="m-col-t-6 m-nopad"><div class="m-frame m-text-center">.m-col-t-6</div></div>
<div class="m-col-t-6 m-nopad"><div class="m-frame m-text-center">.m-col-t-6</div></div>
</div>
<div class="m-row">
<div class="m-col-s-4 m-col-m-6 m-nopad"><div class="m-frame m-text-center">.m-col-s-4 .m-col-m-6</div></div>
<div class="m-col-s-4 m-col-m-3 m-nopad"><div class="m-frame m-text-center">.m-col-s-4 .m-col-m-3</div></div>
<div class="m-col-s-4 m-col-m-3 m-nopad"><div class="m-frame m-text-center">.m-col-s-4 .m-col-m-3</div></div>
</div>
<div class="m-row">
<div class="m-col-l-7 m-nopady m-nopadx"><div class="m-frame m-text-center">.m-col-l-7</div></div>
<div class="m-col-l-5 m-nopadt m-nopadx"><div class="m-frame m-text-center">.m-col-l-5</div></div>
</div>
.. note-info::
To see the effect, try to resize your browser window (or rotate the screen
of your mobile device). Please note that the live examples here are not
*exactly* matching the code --- I added a bunch of HTML elements and CSS
classes to improve clarity.
In the above code, the outer :html:`<div class="m-container">` is taking care
of limiting the website layout width. On very narrow devices, the whole screen
width is used, on wider screens fixed sizes are used in order to make the
content layouting manageable. The :css:`.m-container` usually has :css:`.m-row`
items directly inside, but that's not a requirement --- you can put anything
there, if you just want to have some predictable width limitation to your
content.
The :html:`<div class="m-row">` denotes a row. The row is little more than
a delimiter for columns --- it just makes sure that two neighboring rows don't
interact with each other in a bad way.
The actual magic is done by the row elements denoted by :css:`.m-col-B-N`. The
``B`` is one of four breakpoints --- ``t`` for tiny, ``s`` for small, ``m`` for
medium and ``l`` for large --- based on screen width. The ``N`` is number of
columns that given element will span. So, looking at the code above,
:css:`.m-col-m-3` will span three columns out of twelve on medium-sized screen.
This setting is inherited upwards --- if you specify a column span for a
smaller screen width, it will get applied on larger width as well, unless you
override it with a setting for larger screen width. On the other hand, if given
screen width has no column width specified, the element will span the whole
row. So, again from above, the :css:`.m-col-s-4 .m-col-m-6` element will span
the whole row on tiny screen sizes, four columns on small screen sizes and six
columns on medium and large screen sizes.
`Detailed grid properties`_
===========================
.. class:: m-table
+-------------------+-----------------------+---------------------------+-------------------------------+
| Breakpoint | Screen width range | ``.m-container`` width | Classes applied, ordered by |
| | (inclusive) | | priority |
+===================+=======================+===========================+===============================+
| ``t``, "tiny", | less than 576px | full screen width | ``.m-col-t-*`` |
| portrait phones | | | |
+-------------------+-----------------------+---------------------------+-------------------------------+
| ``s``, "small", | 576px - 767px | 560px | ``.m-col-s-*``, |
| landscape phones | | | ``.m-col-t-*`` |
+-------------------+-----------------------+---------------------------+-------------------------------+
| ``m``, "medium", | 768px - 991px | 750px | ``.m-col-m-*``, |
| tablets, small | | | ``.m-col-s-*``, |
| desktops | | | ``.m-col-t-*`` |
+-------------------+-----------------------+---------------------------+-------------------------------+
| ``l``, "large", | 992px and up | 960px | ``.m-col-l-*``, |
| desktops, very | | | ``.m-col-m-*``, |
| large tablets | | | ``.m-col-s-*``, |
| | | | ``.m-col-t-*`` |
+-------------------+-----------------------+---------------------------+-------------------------------+
`Wrapping around`_
==================
Besides the above "all or nothing" scenario, where all the elements either form
a single row or are laid out one after another in separate rows, it's possible
to wrap the items around so they for example take four columns in a large
screen width and two rows of two columns in a small screen width. In such case
it's important to account for elements with different heights using a
:css:`.m-clearfix-*` for given breakpoint:
.. code:: html
<div class="m-container">
<div class="m-row">
<div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...<br/>...</div>
<div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3</div>
<div class="m-clearfix-s"></div>
<div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...</div>
<div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...</div>
</div>
</div>
.. raw:: html
<div class="m-row">
<div class="m-col-s-6 m-col-m-3 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-6 .m-col-m-3<br/>...<br/>...</div></div>
<div class="m-col-s-6 m-col-m-3 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-6 .m-col-m-3</div></div>
<div class="m-clearfix-s"></div>
<div class="m-col-s-6 m-col-m-3 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-6 .m-col-m-3<br/>...</div></div>
<div class="m-col-s-6 m-col-m-3 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-6 .m-col-m-3<br/>...</div></div>
</div>
.. note-success::
Shrink your browser window and then try to remove the
:html:`<div class="m-clearfix-s">` element to see what it does in the above
markup.
`Pushing and pulling`_
======================
It's possible to push and pull the elements around using :css:`.m-push-*` and
:css:`.m-pull-*` and even use this functionality to horizontally reorder
content based on screen width. Learn by example:
.. code:: html
<div class="m-container">
<div class="m-row">
<div class="m-col-l-6 m-push-l-3">.m-col-l-6 .m-push-l-3</div>
</div>
<div class="m-row">
<div class="m-col-s-8 m-push-s-4">.m-col-s-8 .m-push-s-4<br/>first</div>
<div class="m-col-s-4 m-pull-s-8">.m-col-s-4 .m-pull-s-8<br/>second</div>
</div>
</div>
.. raw:: html
<div class="m-row">
<div class="m-col-l-6 m-push-l-3 m-nopad"><div class="m-frame m-text-center">.m-col-l-6 .m-push-l-3</div></div>
</div>
<div class="m-row">
<div class="m-col-s-8 m-push-s-4 m-nopad"><div class="m-frame m-text-center">.m-col-s-8 .m-push-s-4<br/>first</div></div>
<div class="m-col-s-4 m-pull-s-8 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-4 .m-pull-s-8<br/>second</div></div>
</div>
.. note-warning::
There may be some corner cases related to column span inheritance and
pushing/pulling. If the output is not desired, try specifying the
:css:`.m-push-*` and :css:`.m-pull-*` explicitly for all breakpoints.
`Floating around`_
==================
It's also possible to responsively float or align the elements around using
:css:`.m-left-*`, :css:`.m-right-*` and :css:`.m-center-*` if you put the
:css:`.m-col-*` elements directly into text flow without wrapping them in a
:css:`.m-row` element. The following example will float the contents to the
right on medium-size screens, center them on small and put them full-width
on tiny screens.
Perhaps even more important than in the `wrapping case mentioned above <#wrapping-around>`_
is adding a :css:`.m-clearfix-*` element after, to avoid the floating element
cutting into unrelated content that follows.
.. code:: html
<div class="m-col-s-6 m-center-s m-col-m-4 m-right-m">
.m-col-s-6 .m-center-s .m-col-m-4 .m-right-m
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
<div class="m-clearfix-m"></div>
.. raw:: html
<div class="m-col-s-6 m-center-s m-col-m-4 m-right-m">
<div class="m-frame m-text-center">.m-col-s-6 .m-center-s .m-col-m-4 .m-right-m</div>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
<div class="m-clearfix-m"></div>
Left-aligned floating blocks additionally have :css:`1rem` padding on the right
and right-aligned blocks on the left. All of them have implicitly padding on bottom, except if the element is a last child. Add a :css:`.m-nopadb` class to
them to disable bottom padding, if you want to preserve it even for a last
child, add an empty :html:`<div></div>` element after.
.. note-info::
The floating works on any element, not just those that are :css:`.m-col-*`.
Moreover, if you'll float `components <{filename}/css/components.rst>`_
such as images or figures without using :css:`.m-col-*`, they will occupy
exactly the width of their contents without being shrunk or scaled.
`Grid padding`_
===============
The :css:`.m-container` element pads its contents from left and right by
:css:`1rem`; the :css:`.m-row` adds a negative :css:`-1rem` margin on left and
right to reset it. Finally, the :css:`.m-col-*` elements have :css:`1rem`
padding on all sides to separate the contents. It's possible to override this
on the :css:`.m-container` and/or on :css:`.m-col-*` elements using
:css:`.m-nopad`, :css:`.m-nopadx`, :css:`m-nopady`, :css:`.m-nopadt`,
:css:`.m-nopadb`, :css:`.m-nopadl`, :css:`.m-nopadr` which remove all, just
horizontal or vertical padding, or padding on the top/bottom/left/right,
respectively.
`Grid nesting`_
===============
It's possible to nest the grid. Just place a :css:`.m-row` element inside an
:css:`.m-col-*` (it *doesn't* need to be a direct child) and put your
:css:`.m-col-*` elements inside. The inner grid will also have 12 columns, but
smaller ones.
.. note-info::
Because the :css:`.m-container` element specifies a fixed width, it's not
desirable to wrap the nested grid with it again.
`Removing the grid on larger screen sizes`_
===========================================
The usual behavior is to *add* the grid for larger screen sizes, but sometimes
you might want to do the opposite. It's possible to do that just by specifying
:css:`.m-col-*-12` for given breakpoint, but sometimes the CSS :css:`float`
property might cause problems. The :css:`.m-col-*-none` classes completely
remove all grid-related CSS styling for given screen size and up so the element
behaves like in its initial state.
.. code:: html
<div class="m-container">
<div class="m-row">
<div class="m-col-s-8 m-col-l-none">.m-col-s-8 .m-col-l-none</div>
<div class="m-col-s-4 m-col-l-none">.m-col-s-4 .m-col-l-none</div>
</div>
</div>
.. raw:: html
<div class="m-row">
<div class="m-col-s-8 m-col-l-none m-nopad"><div class="m-frame m-text-center">.m-col-s-8 .m-col-l-none</div></div>
<div class="m-col-s-4 m-col-l-none m-nopad"><div class="m-frame m-text-center">.m-col-s-4 .m-col-l-none</div></div>
</div>
`Hiding elements based on screen size`_
=======================================
The :css:`.m-show-*` and :css:`.m-hide-*` classes hide or show the element on
given screen size and up. Useful for example to show a different kind of
navigation on different devices.
.. code:: html
<div class="m-show-m">.m-show-m<br/>shown on M and up</div>
<div class="m-hide-l">.m-hide-l<br/>hidden on L and up</div>
.. raw:: html
<div class="m-row">
<div class="m-col-m-6 m-col-l-12 m-show-m m-nopad"><div class="m-frame m-text-center">.m-show-m<br/>shown on M and up</div></div>
<div class="m-col-m-6 m-col-l-12 m-hide-l m-nopad"><div class="m-frame m-text-center">.m-hide-l<br/>hidden on L and up</div></div>
</div>
`Inflatable nested grid`_
=========================
It's usual that the content area of the page doesn't span the full 12-column
width in order to avoid long unreadable lines. But sometimes one might want to
use the full available width --- for example to show big pictures or to fit
many things next to each other.
If you have a ten-column content area with one column space on each side, mark
your :css:`.m-container` element with :css:`.m-container-inflatable` and then
put your nested content in elements marked with :css:`.m-container-inflate`.
.. code:: html
<div class="m-container m-container-inflatable">
<div class="m-row">
<div class="m-col-l-10 m-push-l-1">
<div class="m-container-inflate">.m-container-inflate</div>
</div>
</div>
</div>
.. raw:: html
<div class="m-container-inflate">
<div class="m-frame m-text-center">.m-container-inflate</div>
</div>
The :css:`.m-container-inflate` block has implicitly a :css:`1rem` padding
after (but not on other sides and also not if it's the last child). Add a
:css:`.m-nopadb` class to it to disable that, if you want to preserve the
padding even for a last child, add an empty :html:`<div></div>` element after.
It's also possible to tuck floating content out of the page flow by combining
:css:`.m-left-*` with :css:`.m-container-inflate`:
.. code:: html
<div class="m-container m-container-inflatable">
<div class="m-row">
<div class="m-col-l-10 m-push-l-1">
<div class="m-container-inflate m-col-l-6 m-right-l">
.m-container-inflate .m-col-l-6 .m-right-l
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id
elit posuere, consectetur magna congue, sagittis est. Pellentesque
est neque, aliquet nec consectetur in, mattis ac diam.</p>
</div>
</div>
</div>
.. raw:: html
<div class="m-container-inflate m-col-l-6 m-right-l">
<div class="m-frame m-text-center">.m-container-inflate .m-col-l-6 m-right-l</div>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id
elit posuere, consectetur magna congue, sagittis est. Pellentesque
est neque, aliquet nec consectetur in, mattis ac diam.</p>
.. note-warning::
Similarly to `pushing and pulling`_, there may be corner cases where
inflating of floating elements may not work. To fix that, try specifying
all applicable :css:`.m-col-*-10` breakpoints for the inflatable column and
:css:`.m-right-*` / :css:`.m-left-*` for the floating element explicitly.
`Debug CSS`_
============
It's sometimes hard to see why the layout isn't working as expected. Including
the `m-debug.css <{filename}/css.rst>`_ file will highlight the most usual
mistakes --- such as :css:`.m-row` not directly containing :css:`.m-col-*` or
two :css:`.m-container`\ s nested together --- with bright red background for
you to spot the problems better:
.. code:: html
<link rel="stylesheet" href="m-dark.css" />
Other than highlighting problems, this file doesn't alter your website
appearance in any way. To save unnecessary requests and bandwidth, I recommend
that you remove the reference again when publishing the website.
|