El model de Caixes Flexible de CSS3 (Flexible Box en anglès), o flexbox, és un mode de disseny que preveu la disposició dels elements en una pàgina de tal manera que els elements es comporten d'una forma predictible quan el disseny de la pàgina s'ha d'adaptar a diferents mides de pantalla i a diferents dispositius de visualització.
Per moltes aplicacions, el model de caixes flexible proporciona una millora soble el model de blocs perquè no utilitza flotadors (floats) ni els marges del contenidor flexible col·lapsen amb els marges dels seus continguts.
Molts dissenyadors/es troben que el model flexbox és més fàcil d'utilitzar. Els elements fills es poden col·locar en qualsevol direcció i poden tenir dimensions flexibles per tal d'adaptar-se a l'espai que es visualitza. Posicionar els elements fills és molt més fàcil també, i els dissenys complexos es poden realitzar de forma més senzilla i amb un codi més net, ja que l'ordre de presentació dels elements és independent de l'ordre en el codi font. Aquesta independència només afecta la representació visual de forma intencionada, tot deixant l'odre de la lectura i de la navegació al mateix ordre del codi font.
-webkit
; Internet Explorer implementa una versió antiga de l'especificació, prefixada amb -ms- ; Opera 12.10 implementa la darrera versió de l'especificació, sense prefixe. Per estar al dia de l'estat de les compatibilitats veieu la taula de compatiblitats per a cada propietat.
El concepte de les caixes flexibles
Podem definir el disseny de caixa flexible (flex layout) com l'abilitat d'alterar l'amplada i l'alçada, dels elements dintre de la caixa flex, de la millor manera possible, és a dir, s'emplena l' espai disponible en qualsevol dispositiu. Un contenidor flex (flex container) expandeix elements per emplenar l'espai lliure disponible o encongeix els elements per prevenir el sobreeiximent de la caixa.
[TRADUCCIÓ INACABADA]
The flexbox layout algorithm is direction-agnostic as opposed to the block layout, which is vertically-biased, or the inline layout, which is horizontally-biased. While the block layout works well for pages, it lacks sufficient definition to support application components that have to change orientation, resize, stretch, or shrink as the user agent changes, flips from vertical to horizontal, and so forth. Flexbox layout is most appropriate to the components of an application, and small-scale layouts, while the (emerging) Grid layout is intended for larger scale layouts. Both are part of a wider effort of the CSS Working Group to provide for greater interoperability of web applications with different user agents, different writing modes, and other demands on flexibility.
Flexible boxes vocabulary
While a discussion of flexible boxes is liberated from terms like horizontal/inline axis and vertical/block axis, it requires a new terminology to properly describe the model. Consider the following diagram when reviewing the vocabulary items below. It shows a flex container that has a flex-direction
of row
, meaning that the flex items follow each other horizontally across the main axis according to the established writing mode, the direction in which the element's text flows, in this case left-to-right.
- Flex container
- The parent element in which flex items are contained. A flex container is defined using the
flex
orinline-flex
values of thedisplay
property. - Flex item
-
Each child of a flex container becomes a flex item. Text directly contained in a flex container is wrapped in an anonymous flex item.
- Axes
-
Every flexible box layout follows two axes. The main axis is the axis along which the flex items follow each other. The cross axis is the axis perpendicular to the main axis.
- The
flex-direction
property establishes the main axis. - The
justify-content
property defines how flex items are laid out along the main axis on the current line. - The
align-items
property defines the default for how flex items are laid out along the cross axis on the current line. - The
align-self
property defines how a single flex item is aligned on the cross axis, and overrides the default established byalign-items.
- The
- Directions
-
The main start/main end and cross start/cross end sides of the flex container describe the origin and terminus of the flow of flex items. They follow the main axis and cross axis of the flex container in the vector established by the
writing-mode
(left-to-right, right-to-left, etc.).- The
order
property assigns elements to ordinal groups and determines which elements appear first. - The
flex-flow
property shorthands theflex-direction
andflex-wrap
properties to lay out the flex items.
- The
- Lines
-
Flex items can be laid out on either a single line or on several lines according to the
flex-wrap
property, which controls the direction of the cross axis and the direction in which new lines are stacked. - Dimensions
-
The flex items' agnostic equivalents of height and width are main size and cross size, which respectively follow the main axis and cross axis of the flex container.
- The
min-height
andmin-width
properties have a new value,auto
that establishes the minimum size of a flex item. - The
flex
property shorthands theflex-basis
,flex-grow
, andflex-shrink
properties to establish the flexibility of the flex items.
- The
Designating a flexible box
To designate the CSS for elements using this style, set the display property as follows:
display : flex
or
display : inline-flex
Doing so defines the element as a flex container and its children as flex items. The flex
value makes the flex container a block-level element. The inline-flex
value makes the flex container an atomic inline-level element.
display : -webkit-flex
.Flex item considerations
Text that is directly contained inside a flex container is automatically wrapped in an anonymous flex item. However, an anonymous flex item that contains only white space is not rendered, as if it were designated display:none
.
Absolutely positioned children of a flex container are positioned so that their static position is determined in reference to the main start content-box corner of their flex container.
Currently, due to a known issue, specifying visibility:collapse
on a flex item causes it to be treated as if it were display:none
instead of the intended behavior, treating it as if it were visibility:hidden
. The suggested workaround until this issue is resolved is to use visibility:hidden
for flex items that should behave as if they were designated visibility:collapse
.
The margins of adjacent flex items do not collapse. Using auto
margins absorbs extra space in the vertical or horizontal direction and can be used for alignment or to separate adjacent flex items. See Aligning with 'auto' margins in the W3C Flexible Box Layout Model specification for more details.
To ensure a reasonable default minumum size for flex items, use min-width:auto
and/or min-height:auto
. For flex items, the auto
attribute value calculates the minimum width/height of the item to be no less than the width/height of its content, guaranteeing that the item is rendered large enough to hold the content. See min-width
and min-height
for more details.
Flexbox's alignment properties do "true" centering, unlike other centering methods in CSS. This means that the flex items will stay centered, even if they overflow the flex container. This can sometimes be problematic, however, if they overflow past the top edge of the page, or the left edge (in LTR languages like English; the problem occurs on the right edge in RTL languages like Arabic), as you can't scroll to that area, even if there is content there! In future release, the alignment properties will be extended to have a "safe" option as well. For now, if this is a concern, you can instead use margins to achieve centering, as they'll respond in a "safe" way and stop centering if they overflow. Instead of using the align-
properties, just put auto margins on the flex items you wish to center. Instead of the justify-
properties, put auto margins on the outside edges of the first and last flex items in the flex container. The auto margins will "flex" and assume the leftover space, centering the flex items when there is leftover space, and switching to normal alignment when not. However, if you're trying to replace justify-content
with margin-based centering in a multi-line flexbox, you're probably out of luck, as you need to put the margins on the first and last flex item on each line. Unless you can predict ahead of time which items will end up on which line, you can't reliably use margin-based centering in the main axis to replace the justify-content
property.
Recall that while the display order of the elements is independent of their order in the source code, this independence affects only the visual rendering, leaving speech order and navigation based on the source order. Even the order
property does not affect speech or navigation sequence. Thus developers must take care to order elements properly in the source so as not to damage the document's accessibility.
Flexible box properties
Properties not affecting flexible boxes
Because flexible boxes use a different layout algorithm, some properties do not make sense on a flex container.
- column-* properties of the Multicol module have no effect on a flex item.
float
andclear
have no effect on a flex item. Usingfloat
causes thedisplay
property of the element to compute toblock
.vertical-align
has no effect on the alignment of flex items.
Exemples
Exemple bàsic de caixa flex
Aquest exemple mostra com aplicar "flexibilitat" a un element i com els elements germans es comportant en un estat flexible.
<!DOCTYPE html> <html lang="ca"> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="UTF-8"> <style> .flex { /* estíl bàsic */ width: 100%; height: 80vh; /* ocupa el 80% del viewport */ border: 1px solid #555; font: 14px Arial; /* Configuració del flexbox */ display: -webkit-flex; -webkit-flex-direction: row; display: flex; flex-direction: row; } .flex > div { /* La propietat flex té tres paràmetres: flex-grow: ens indica la quantitat de espai lliure que agafarà el element flex-shrink: ens indica la quantitat d'encongiment respecte a la resta d'elements flex-basic: el main size inicial del element, auto és el valor per defecte */ -webkit-flex: 1 1 auto; flex: 1 1 auto; width: 30px; -webkit-transition: width 0.7s ease-out; -moz-transition: width 0.7s ease-out; -o-transition: width 0.7s ease-out; transition: width 0.7s ease-out; } /* colors */ .flex > div:nth-child(1){ background : green; } .flex > div:nth-child(2){ background : blue; } .flex > div:nth-child(3){ background : red; } .flex > div:hover { width: 80%; } </style> </head> <body> <h1>La nova propietat Flex</h1> <div class="flex"> <div>caixa 1</div> <div>caixa 2</div> <div>caixa 3</div> </div> </body> </html>
Holy Grail Layout example
This example demonstrates how flexbox provides the ability to dynamically change the layout for different screen resolutions. The following diagram illustrates the transformation.
Illustrated here is the case where the page layout suited to a browser window must be optimized for a smart phone window. Not only must the elements reduce in size, but the order in which they are presented must change. Flexbox makes this very simple.
<!DOCTYPE html> <html lang="en"> <head> <style> body { font: 24px Helvetica; background: #999999; } #main { min-height: 800px; margin: 0px; padding: 0px; display: -webkit-flex; display: flex; -webkit-flex-flow: row; flex-flow: row; } #main > article { margin: 4px; padding: 5px; border: 1px solid #cccc33; border-radius: 7pt; background: #dddd88; -webkit-flex: 3 1 60%; flex: 3 1 60%; -webkit-order: 2; order: 2; } #main > nav { margin: 4px; padding: 5px; border: 1px solid #8888bb; border-radius: 7pt; background: #ccccff; -webkit-flex: 1 6 20%; flex: 1 6 20%; -webkit-order: 1; order: 1; } #main > aside { margin: 4px; padding: 5px; border: 1px solid #8888bb; border-radius: 7pt; background: #ccccff; -webkit-flex: 1 6 20%; flex: 1 6 20%; -webkit-order: 3; order: 3; } header, footer { display: block; margin: 4px; padding: 5px; min-height: 100px; border: 1px solid #eebb55; border-radius: 7pt; background: #ffeebb; } /* Too narrow to support three columns */ @media all and (max-width: 640px) { #main, #page { -webkit-flex-flow: column; flex-flow: column; } #main > article, #main > nav, #main > aside { /* Return them to document order */ -webkit-order: 0; order: 0; } #main > nav, #main > aside, header, footer { min-height: 50px; max-height: 50px; } } </style> </head> <body> <header>header</header> <div id='main'> <article>article</article> <nav>nav</nav> <aside>aside</aside> </div> <footer>footer</footer> </body> </html>
Playground
There are several flexbox playgrounds available online for experimenting:
Things to keep in mind
The algorithm describing how flex items are laid out can be pretty tricky at times. Here are a few things to consider to avoid bad surprises when designing using flexible boxes.
Flexibles boxes are laid out in conformance of the writing mode. Which means that main start and main end are laid out according to the position of start and end.
cross start and cross end rely on the definition of the start or before position that depends on the value of direction
.
Page breaks are possible in flexible boxes layout as long as break-
property allows it. CSS3 break-after
, break-before
and break-inside
as well as CSS 2.1 page-break-before
, page-break-after
and page-break-inside
properties are accepted on a flex container, flex items and inside flex items.
Browser compatibility
Feature | Firefox (Gecko) | Chrome | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 18.0 (18.0)-moz(Behind a pref) [2] 19.0 (19.0)(Behind a pref) [2] 20.0 (20.0) |
21.0-webkit | Not supported [1] | 12.10 | Not supported [1] |
Feature | Firefox Mobile (Gecko) | Android | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Basic support | 18.0 (18.0)-moz(Behind a pref) [2] 19.0 (19.0)(Behind a pref) [2] 20.0 (20.0) |
? | ? | ? | Not supported |
Notes
[1] Internet Explorer 10 and Safari support an old incompatible draft version of the specification. They have not been updated to support the final version.
[2] Firefox supports only single-line flexbox. To activate flexbox support, for Firefox 18 and 19, the user has to change the about:config preference "layout.css.flexbox.enabled" to true
.