Designing Imaginative Layouts (workshop)

433acaea1012b25d97ae66da9b998dad?s=47 Andy Clarke
October 26, 2016

Designing Imaginative Layouts (workshop)

With more and more websites following the same tired layout patterns, it’s time be bring imagination back to our digital products and websites. This workshop will teach you how to design inspired layouts, without compromising accessibility, responsiveness or user experience.

433acaea1012b25d97ae66da9b998dad?s=128

Andy Clarke

October 26, 2016
Tweet

Transcript

  1. None
  2. Designing and developing imaginative layouts, Australia 2016 Designing imaginative layouts

    With Andy Clarke @malarkey
  3. None
  4. None
  5. Speakerdeck https://speakerdeck.com/malarkey/ #inspireddesign

  6. Designing and developing imaginative layouts, Australia 2016

  7. Morning Designing imaginative layouts Systems Anatomy Types Ratios Compound Practical

  8. Developing imaginative layouts Columns Shapes Practical Afternoon Flexible boxes Grid

  9. Designing and developing imaginative layouts, Australia 2016 Inspiration

  10. Alexey Brodovitch

  11. Harpers Bazaar magazine 1934–1958

  12. None
  13. None
  14. None
  15. None
  16. Designing and developing imaginative layouts, Australia 2016 Grid systems

  17. None
  18. None
  19. None
  20. None
  21. None
  22. None
  23. None
  24. None
  25. None
  26. None
  27. None
  28. None
  29. None
  30. None
  31. None
  32. None
  33. None
  34. None
  35. None
  36. Create units in multiples of three or four, with twelve

    as an ideal, because it is a multiple of three and four. ” Khoi Vinh in ‘Ordering Disorder,’ New Riders 2010
  37. Designing and developing imaginative layouts, Australia 2016 Grid anatomy

  38. None
  39. None
  40. None
  41. None
  42. None
  43. None
  44. None
  45. None
  46. None
  47. Designing and developing imaginative layouts, Australia 2016 Grid types

  48. None
  49. None
  50. None
  51. None
  52. None
  53. None
  54. None
  55. None
  56. None
  57. None
  58. Designing and developing imaginative layouts, Australia 2016 Ratios

  59. None
  60. Grids are fundamentally about proportions, the relationship between content and

    viewport. #inspireddesign
  61. None
  62. None
  63. None
  64. None
  65. None
  66. None
  67. None
  68. None
  69. None
  70. None
  71. None
  72. None
  73. None
  74. None
  75. None
  76. None
  77. None
  78. None
  79. None
  80. To be ‘rational,’ ratios must include whole numbers. Irrational ratios

    include fractions. #inspireddesign
  81. Designing and developing imaginative layouts, Australia 2016 Gridset

  82. None
  83. None
  84. None
  85. None
  86. None
  87. None
  88. None
  89. None
  90. None
  91. None
  92. None
  93. None
  94. None
  95. None
  96. None
  97. None
  98. None
  99. Designing and developing imaginative layouts, Australia 2016 Inspiration

  100. None
  101. None
  102. None
  103. None
  104. None
  105. None
  106. Grids help to bring order, but suprise and delight are

    key to maintaining interest. #inspireddesign
  107. Designing and developing imaginative layouts, Australia 2016 Get creative

  108. None
  109. None
  110. Example content https://goo.gl/PfyCQC

  111. Designing and developing imaginative layouts, Australia 2016 Take a break

  112. Designing and developing imaginative layouts, Australia 2016 Welcome back

  113. None
  114. Designing and developing imaginative layouts, Australia 2016 Symmetry

  115. None
  116. None
  117. None
  118. None
  119. None
  120. None
  121. None
  122. None
  123. None
  124. None
  125. None
  126. Designing and developing imaginative layouts, Australia 2016 Inspiration

  127. None
  128. None
  129. None
  130. None
  131. Designing and developing imaginative layouts, Australia 2016 Compound grid

  132. Pros Distinctive Flexible Compound grid Mathematics Cons

  133. None
  134. None
  135. None
  136. None
  137. None
  138. None
  139. None
  140. None
  141. Designing and developing imaginative layouts, Australia 2016 Inspiration

  142. None
  143. Designing and developing imaginative layouts, Australia 2016 Modular grid

  144. None
  145. None
  146. None
  147. None
  148. None
  149. None
  150. None
  151. None
  152. None
  153. You don’t need to fill every grid module with content

    #inspireddesign
  154. None
  155. None
  156. None
  157. None
  158. Designing and developing imaginative layouts, Australia 2016 Inspiration

  159. None
  160. None
  161. None
  162. Designing and developing imaginative layouts, Australia 2016 Get creative

  163. Reading list

  164. Designing and developing imaginative layouts, Australia 2016 Anything we missed?

  165. None
  166. Designing and developing imaginative layouts, Australia 2016 Developing imaginative layouts

    With Andy Clarke @malarkey
  167. Designing and developing imaginative layouts, Australia 2016 Welcome

  168. Developing imaginative layouts Columns Shapes Practical Afternoon Flexible boxes Grid

  169. Speakerdeck https://speakerdeck.com/malarkey/ #inspireddesign

  170. Today’s browsers Chrome Canary Firefox Nightly Safari Technology Preview https://goo.gl/hEOhjB

    https://goo.gl/MqX7eh https://goo.gl/SAeD4H
  171. None
  172. None
  173. None
  174. Drawbacks Complicated maths Vertical centering Float drops Float clearing Same

    height columns Shrink-to-fit containers Source order dependence
  175. Vertical centring solved

  176. Float drop & clearing solved

  177. Equal height columns solved

  178. Source order dependence helped

  179. Designing and developing imaginative layouts, Australia 2016 Multiple columns

  180. None
  181. None
  182. None
  183. None
  184. None
  185. Advantages Improves readability
 Manages the measure
 Reduces purely presentational markup

  186. None
  187. None
  188. None
  189. Presentational HTML <div class="col"> <p>Johannes Gensfleisch zur Laden zum Gutenberg

    was a German blacksmith, goldsmith, printer, and publisher who introduced printing to Europe.</p> </div> <div class="col"> <p>His introduction of mechanical movable type printing to Europe started the Printing Revolution and is widely regarded as the most important invention of the second millennium.</p> </div>
  190. Properties Column count Column width Column span Break after Column

    gap Column rule Break before
  191. Markup <section> <p>Johannes Gensfleisch zur Laden zum Gutenberg was a

    German blacksmith, goldsmith, printer, and publisher who introduced printing to Europe.</p> <p>His introduction of mechanical movable type printing to Europe started the Printing Revolution and is widely regarded as the most important invention of the second millennium.</p> </section>
  192. section { column-width : 32em; } Column width -moz- and

    -webkit- prefixes may also be required
  193. section { column-count : 2; } Column count -moz- and

    -webkit- prefixes may also be required
  194. @media (min-width: 48rem) { section {
 column-count : 2; }


    } @media (min-width: 64rem) { section {
 column-count : 3; }
 } Column count -moz- and -webkit- prefixes may also be required
  195. section { columns : 2 24em; } Columns -moz- and

    -webkit- prefixes may also be required
  196. section { column-gap : 2vw; } Column gap -moz- and

    -webkit- prefixes may also be required
  197. section { column-rule-width : 2px; column-rule-style : solid; 
 column-rule-color

    : #000; } Column rule -moz- and -webkit- prefixes may also be required
  198. None
  199. @media (min-width : 37.5em) { .sidebar ul { column-count :

    2; column-gap : 4vw; } } @media (min-width : 48em) { .sidebar ul { column-count : 1; } } Columnised lists -moz- and -webkit- prefixes may also be required
  200. @media (min-width : 37.5em) { .cols-figure figcaption { column-count :

    2; column-gap : 4vw; } } Columnised captions -moz- and -webkit- prefixes may also be required
  201. None
  202. None
  203. <section> <p>…</p> <figure class="column__span" >…</figure> <p>…</p> <h2 class="column__span">…</h2> … </section>

    Spanning columns
  204. .cols__span { column-span : all; } Spanning columns Column-span is

    not supported in Firefox
  205. None
  206. None
  207. None
  208. h2 { break-before : column; break-after : avoid-column; 
 }

    Breaks -moz- and -webkit- prefixes may also be required
  209. Support 1 Supported with -webkit- prefix 2 Supported with -moz-

    prefix 13 (IE 10) 52 (2 2 ) 51 (4 1 ) 37 (15 1 ) 9 (3.1 1 ) 2.1 1 9.2 (3.2 1 ) 53
  210. Designing and developing imaginative layouts, Australia 2016 Inspiration

  211. None
  212. None
  213. None
  214. Feature query @supports (column-span:all) { section {
 column-count : 2;

    }
 }
  215. Feature query @supports (column-span:all) { section {
 column-count : 2;

    }
 } @supports not (column-span:all) { section {
 padding : 0 4vw; }
 }
  216. Feature query @supports (column-count:2) or (-webkit-column-count:2) { section {
 column-count

    : 2; }
 }
  217. Feature query @supports (column-count:2) and (column-span:all { section {
 column-count

    : 2; } }
  218. Designing and developing imaginative layouts, Australia 2016 Shapes

  219. None
  220. None
  221. None
  222. None
  223. .shapes__circle { shape-outside : circle ( ); // Content will

    wrap around a shape } Shapes
  224. circle () ellipse () box-values inset () polygon () Shapes

    Each shape is defined by a set of points.
  225. Floated left or right 
 A shapes element must be

    floated to enable content to wrap around it. 
 Intrinsic size
 Intrinsic size (height and width dimensions) needed to establish a coordinate system on the element; the system will be used to position the shape functions’ points on the element. The intrinsic size doesn’t have to be set using absolute values (e.g pixels), you can use percentages, which means that the shaped element can be fully responsive. Conditions
  226. img { float : left; shape-outside : circle (); }

    Circle
  227. img { float : left; shape-outside : circle ();
 shape-margin

    : 22px; } Shape margin
  228. img { float : left; shape-outside : ellipse ();
 }

    Ellipse
  229. img { float : left; shape-outside : inset ();
 }

    Inset
  230. img { float : left;
 background : url(gutenberg-press.png) 100% 100%;

    clip-path : polygon(…);
 shape-outside : polygon(…); } Polygon
  231. None
  232. None
  233. None
  234. None
  235. None
  236. None
  237. None
  238. None
  239. Support 1 Supported with -webkit- prefix 37 24 7.1 1

    52 8 1 53 4
  240. Designing and developing imaginative layouts, Australia 2016 Get technical

  241. Example content https://goo.gl/PfyCQC

  242. Designing and developing imaginative layouts, Australia 2016 Break

  243. Designing and developing imaginative layouts, Australia 2016 Welcome back

  244. Designing and developing imaginative layouts, Australia 2016 Flexible boxes

  245. Advantages More flexible layouts Visual content reordering Column height matching

  246. Main & cross axis main axis cross axis

  247. Applying flex .container { display : flex; } Turns container

    into a flex-container and doesn’t remove its block attributes
  248. None
  249. Applying flex .container { display : inline-flex; } Container will

    not fill available horizontal space
  250. Applying flex <div class="item">
 <div class="item__img"> <img src="gutenberg.svg" alt="">
 </div>

    <div class="item__description">…</div> </div>
  251. Flex direction .item { flex-direction : row; /* default */

    } // row, row-reverse, column, column-reverse
  252. Unless we’ve set the dir attribute to rtl, for right-to-left

    languages, 
 this flex starts on the left and ends on the right.
  253. Reverse .item { flex-direction : row-reverse; }

  254. Reversing the flex-direction changes this horizontal layout without altering the

    markup.
  255. Column <figure class="figure--classic">
 <img src="gutenberg.svg" alt="">
 <figcaption>…</figcaption> </figure>

  256. Column .figure--classic { flex-direction : column; }

  257. None
  258. Column <figure class="figure--reverse">
 <img src="gutenberg.svg" alt="">
 <figcaption>…</figcaption> </figure>

  259. Column-reverse .figure--reverse { flex-direction : column-reverse; }

  260. None
  261. Figcaption .figure--reverse figcaption { max-width : 50%; 
 }

  262. None
  263. .container { flex-wrap : nowrap; /* default */ } Wrapping

    flex items
  264. .container { flex-wrap : wrap; } Wrapping flex items

  265. None
  266. .container { flex-wrap : wrap-reverse; } Wrap-reverse

  267. None
  268. Flex-flow .container { flex-flow : row nowrap; }

  269. None
  270. Flex-grow // Boxes have equal width .box { flex-grow :

    1; 
 }
  271. The ability for a flex item to grow if necessary

    and dictates the amount 
 of available space an item should take.
  272. The ability for a flex item to grow if necessary

    and dictates the amount 
 of available space an item should take.
  273. Flex-grow .box--one { flex-grow : 1; 
 } .box--two {

    flex-grow : 2; // Twice available space as siblings
 } .box--three { flex-grow : 1;
 }
  274. The ability for a flex item to grow if necessary

    and dictates the amount 
 of available space an item should take.
  275. Flex <figure class="figure--horizontal">
 <img src="gutenberg.svg" alt="">
 <figcaption>…</figcaption> </figure>

  276. Flex @media (min-width: 48rem) { .figure--horizontal { display : flex;

    } .figure--horizontal img { 
 flex : 4; } .figure--horizontal figcaption { 
 flex : 1; }
 
 }
  277. None
  278. Flex @media (min-width: 48rem) { .figure--horizontal-reverse { display : flex;


    flex-direction : row-reverse; } }
  279. None
  280. Flex-basis <section>
 <article>…</article> 
 <article>…</article> </section>

  281. Flex-basis article { 
 flex-basis : 400px; 
 }

  282. None
  283. Flex-basis article:first-of-type { 
 flex-grow : 1; 
 }

  284. None
  285. Order Controls the order in which items appear visually in

    a flex container. <section>
 <article>…</article> 
 <article>…</article> <article>…</article> </section>
  286. Order section { 
 display : flex; 
 flex-direction :

    column; }
  287. None
  288. Order article:last-of-type { 
 order : -1; 
 }

  289. None
  290. Order .item:nth-of-type(1) { 
 order : 3; } .item:nth-of-type(2) {

    
 order : 4; } .item:nth-of-type(3) { 
 order : 1; } .item:nth-of-type(4) { 
 order : 2; }
  291. None
  292. Align-items flex-start: Items placed on the cross axis start line

    .content {
 align-items : flex-start; 
 }
  293. None
  294. Align-items flex-end: Items placed on the cross axis end line

    .content {
 align-items : flex-end; 
 }
  295. None
  296. Align-items center: items centered in the cross axis .content {


    align-items : center; 
 }
  297. None
  298. Align-items stretch (default): items stretch to fill container height .content

    {
 align-items : stretch; /* default */
 }
  299. None
  300. Align-items baseline: items aligned so that their baselines match .content

    {
 align-items : baseline;
 }
  301. None
  302. Align-items <figure>
 <img src="gutenberg.svg" alt="">
 <figcaption>…</figcaption> </figure>

  303. Align-items @media (orientation:landscape) { figure {
 display : flex;
 align-items

    : flex-end; } img {
 flex : 2 0 360px; } figcaption {
 flex : 1; }
 }
  304. None
  305. Justify-content flex-start: Items placed on the main axis start line

    .content {
 justify-content : flex-start;
 }
  306. None
  307. Justify-content flex-end: Items placed on the main axis end line

    .content {
 justify-content : flex-end;
 }
  308. None
  309. Justify-content center: Items centered in the main axis .content {


    justify-content : center;
 }
  310. None
  311. Justify-content space-between: Items distributed in the line; first item on

    the start line, last on the end .content {
 justify-content : space-between;
 }
  312. None
  313. Justify-content space-around: Items distributed in the line with equal space

    around them .content {
 justify-content : space-around;
 }
  314. None
  315. Align-content flex-start: lines placed at the start of the container

    .content {
 align-content : flex-start;
 }
  316. None
  317. Align-content flex-end: lines placed at the end of the container

    .content {
 align-content : flex-end;
 }
  318. None
  319. Align-content center: lines placed at the center of the container

    .content {
 align-content : center;
 }
  320. None
  321. Align-content stretch (default): lines stretch to fill container height .content

    {
 align-content : stretch; /* default */
 }
  322. None
  323. Align-content space-between: Lines distributed in the container; first item on

    the start line, last on the end .content {
 align-content : space-between; 
 }
  324. None
  325. Align-content space-around: Lines distributed in the container with equal space

    around them .content {
 align-content : space-around; 
 }
  326. None
  327. Align-self align-self: Overrides for individual flex items .content {
 align-self

    : flex-end; 
 } /* auto|flex-start|flex-end|center|baseline|stretch */
  328. None
  329. None
  330. Pinning elements <article> <img src="gutenberg.svg" alt="">
 <p>…</p>
 <a href="">Find out

    more</a> </article>
  331. article { display : flex; flex-direction : column; } article

    > a { margin-top : auto; } Pinning elements
  332. None
  333. Support 1 Supported with -webkit- prefix 11 30 27 23

    6.1 1 4.4 7.1 1 37
  334. Legacy 10 2012 syntax with -ms- prefix 5.1 Old syntax

    with -webkit- prefix 414 Old syntax with -webkit- prefix 7 Old syntax with -webkit- prefix
  335. .container { display : -webkit-box; display : -moz-box; display :

    -ms-flexbox; display : -webkit-flex; display : flex; 
 } Legacy syntax
  336. @mixin flexbox() { display : -webkit-box; display : -moz-box; display

    : -ms-flexbox; display : -webkit-flex; display : flex; } .container { @include flexbox(); 
 } Flexbox Sass mixin @mixin flex($values) { -webkit-box-flex : $values; -moz-box-flex : $values; -webkit-flex : $values; -ms-flex : $values; flex : $values; } .box { @include flex(1 200px); 
 }
  337. None
  338. Modernizr Isolate Flexbox compatible and non-compatible files Modernizr adds flexbox,

    no-flexbox, and flexboxlegacy classes .no-flexbox .container { /* styles */ }
  339. Designing and developing imaginative layouts, Australia 2016 Viewport units

  340. None
  341. None
  342. vw
 Equal to 1% of the width of the viewport

    
 vh
 Equal to 1% of the height of the viewport 
 vmin/vmax
 Equal to vw or vh, whichever is smaller/larger Viewport units
  343. Viewport units .splash { min-height : 100vh; }

  344. None
  345. None
  346. Designing and developing imaginative layouts, Australia 2016 Grid

  347. Designing and developing imaginative layouts, Australia 2016 Inspiration

  348. None
  349. None
  350. None
  351. None
  352. None
  353. Turn on features chrome://flags/#enable-experimental-web- platform-features or opera://flags/#enable- experimental-web-platform-features and press

    “Enable” Grid works in Firefox Nightly. In Firefox Developer Edition go to about:config and enable layout.css.grid.enabled flag Turn on Grid support in the Develop Menu under Experimental Features
  354. None
  355. Markup <div class="row"> <div class="one column">…</div> <div class="eleven columns">…</div> </div>

    <div class="row"> <div class="one-half column">…</div> <div class="one-half column">…</div> </div>
  356. Markup <div class="row"> <div class="col-xs-12 col-sm-6 col-md-8">…</div> <div class="col-xs-6 col-md-4">…</div>

    </div> <div class="row"> <div class="col-xs-6 col-sm-4">…</div> <div class="col-xs-6 col-sm-4">…</div> </div>
  357. With CSS Grid we can finally stop describing our layout

    in markup. #inspireddesign
  358. Applying grid section { display : grid; } Turns container

    into a grid container and doesn’t remove its block attributes
  359. Applying grid section { display : inline-grid; } Container will

    not fill available horizontal space
  360. Grid lines

  361. Grid track

  362. Grid track

  363. Grid cell

  364. Grid area

  365. Markup <section>
 <article>…</article> 
 <article>…</article> <article>…</article> </section>

  366. None
  367. Columns section { grid-template-columns : 180px 600px 180px; }

  368. None
  369. Columns section { grid-template-columns : 25% auto 25%; }

  370. None
  371. Rows section { grid-template-rows : 300px 300px; }

  372. None
  373. Rows section { grid-template-rows : 300px; }

  374. None
  375. Auto rows section { grid-auto-rows : 200px; }

  376. None
  377. Column gap section { grid-column-gap : 20px; }

  378. None
  379. Row gap section { grid-row-gap : 20px; }

  380. None
  381. Grid gap section { grid-gap : 2vw 4vw; }

  382. Fraction unit section { grid-template-columns : 1fr 1fr 1fr; }

  383. None
  384. Fraction unit section { grid-template-columns : 2fr 1fr 1fr; }

  385. None
  386. Mixed units section { grid-template-columns : 2fr 1fr 300px; }

  387. None
  388. Repeat section { grid-template-columns : repeat(6, 1fr); }

  389. None
  390. Outside repeat section { grid-template-columns : 60px repeat(6, 1fr); }

  391. None
  392. Outside repeat section { grid-template-columns : repeat(6, 1fr) 60px; }

  393. None
  394. Minmax section { grid-template-columns : minmax(100px,300px) 1fr 1fr; }

  395. None
  396. Auto-flow section { grid-auto-flow : column; } // column, row,

    dense, column dense, row dense
  397. None
  398. Order article:nth-child(3) { order : -1; 
 } Grid items

    have a default order of 0.
  399. None
  400. Order article:nth-child(4) { order : 1; 
 } Grid items

    have a default order of 0.
  401. None
  402. Auto-fill section { grid-template-columns : repeat(auto-fill, 100px); 
 } Grid

    items have a default order of 0.
  403. None
  404. Auto-fill section { grid-template-columns : repeat(auto-fill, minmax(100,1fr); 
 } Grid

    items have a default order of 0.
  405. None
  406. Auto-fit section { grid-template-columns : repeat(auto-fit, minmax(100,1fr); 
 } Grid

    items have a default order of 0.
  407. Markup <ul>
 <li>…</li> 
 <li>…</li> <li>…</li> <li>…</li> 
 <li>…</li> <li>…</li>

    … </ul>
  408. Auto-placement ul { display : grid; grid-template-columns : repeat(auto-fill,minmax(100px, 1fr));

    grid-auto-rows : minmax(100px, auto); grid-gap : 2px; }
  409. None
  410. Spanning .span--2 { grid-column-end : span 2; grid-row-end : span

    2; } .span--3 { grid-column-end : span 3; grid-row-end : span 3; }
  411. None
  412. None
  413. Auto-placement ul { grid-auto-flow : dense; } // column, row,

    dense, column dense, row dense
  414. None
  415. None
  416. Placement li:nth-child(1) { grid-row : 3; }

  417. None
  418. Placement li:nth-child(1) { grid-row : 3; grid-column : 1 /

    -1; }
  419. None
  420. Placement li:nth-child(1) { grid-row : 5; }

  421. None
  422. None
  423. Markup <section> <article>…</article> <article>…</article> <article>…</article> <article>…</article> <article>…</article> <article>…</article> </section>

  424. Grid section { display : grid; grid-template-columns : repeat(6, 1fr);

    grid-template-rows : repeat(3, 300px); grid-gap : 2vw; }
  425. None
  426. article:nth-child(1) { grid-column : 1 / -1; 
 }

  427. None
  428. article:nth-child(2) { grid-column : 1 / 3; grid-row : 2;


    }
  429. None
  430. article:nth-child(3) { grid-column : 3 / 7; grid-row : 2;


    }
  431. None
  432. article:nth-child(4) { grid-column : 1 / 4; grid-row : 3;

    
 } article:nth-child(6) { grid-column : 5 / 7; grid-row : 3; 
 }
  433. None
  434. None
  435. Overlapping cells article:nth-child(5) { grid-column : 4 / 5; grid-row

    : 1 / 3; z-index : 2;
 }
  436. None
  437. Markup <body> <header>…</header> <aside>…</aside> <main>…</main> <footer>…</footer> </body>

  438. body { display : grid; grid-template-columns : 2fr 4fr; grid-gap

    : 2vw; 
 } Named lines
  439. body { display : grid; grid-template-columns : 2fr [content-start] 


    4fr [content-end]; grid-gap : 2vw; 
 } Named lines
  440. body { display : grid; grid-template-columns : 2fr [content-start] 


    4fr [content-end]; grid-template-rows : auto [content-start] 
 auto [content-end]; grid-gap : 2vw; 
 } Named lines
  441. main { grid-column : 2; grid-row : 2; } main

    { grid-column : content-start; grid-row : content-start; } Named lines
  442. body { display : grid; grid-template-columns : [content-start] 1fr [content-end];

    grid-template-rows : auto [content-start] 
 auto [content-end]; grid-gap : 2vw; 
 } @media (min-width: 48em) { grid-template-columns : 2fr [content-start] 
 4fr [content-end]; } Breakpoints
  443. Nested grids <section>
 <article>…</article> 
 <article>…</article> <article>…</article> </section>

  444. Nested grids section { display : grid; 
 } article:last-of-type

    { display : grid; 
 }
  445. Designing and developing imaginative layouts, Australia 2016 Get technical

  446. None
  447. None
  448. None
  449. None
  450. None
  451. Designing and developing imaginative layouts, Australia 2016 Resources

  452. None