Skip to content

Commit

Permalink
Implement: new layout type flex-item (#2856)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhouyx authored and erwinmombay committed May 2, 2016
1 parent cfb22ca commit 162356c
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 3 deletions.
6 changes: 6 additions & 0 deletions css/amp.css
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ body {
right: 0;
}

.-amp-layout-flex-item {
display: block;
position: relative;
flex: 1 1 auto;
}

.-amp-layout-size-defined {
overflow: hidden !important;
}
Expand Down
105 changes: 105 additions & 0 deletions examples/layout-flex-item.amp.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!doctype html>
<html >
<head>
<meta charset="utf-8">
<title>AMP #0</title>
<link rel="canonical" href="amps.html" >
<meta name="viewport" content="width=device-width,minimum-scale=1">
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>

<style amp-custom>
.container {
display: flex;
flex-direction: row;
width: 450px;
height: 200px;
}
.container-col {
display: flex;
flex-direction: column;
width: 150px;
height: 300px;
}
.container-no-flex {
display: block;
overflow: auto;
width: 450px;
height: 200px;
}

.child-flex-basis-50 {
flex-basis: 50%;
}

.child-flex-basis-25 {
flex-basis: 25%;
}

.child-flex-grow-2 {
flex-grow: 2;
}

.child-flex-default {
}

.child-flex-size-set {
width: 150px;
height: 100px;
}
</style>

<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>

<body>
<h3>Flex-item in row. Flex-item elements will fill up availabe parent's space.</h3>
<div class="container">
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/5rcQ32ml8E5ONp9f9-Rf78IofLb9QjS5_0mqsY1zEFc=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/Z4gtm5Bkxyv21Z2PtbTf95Clb9AE4VTR6olbBKYrenM=w400-h300-no-n" layout=flex-item></amp-img>
</div>

<h3>Flex-item in column. Flex-item elements will fill up availabe parent's space.</h3>
<div class="container-col">
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-default"src="https://lh3.googleusercontent.com/5rcQ32ml8E5ONp9f9-Rf78IofLb9QjS5_0mqsY1zEFc=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/Z4gtm5Bkxyv21Z2PtbTf95Clb9AE4VTR6olbBKYrenM=w400-h300-no-n" layout=flex-item></amp-img>
</div>

<h3>Set flex-item's size through flex-basis.</h3>
<div class="container">
<amp-img class="child-flex-basis-25" src="https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-basis-50" src="https://lh3.googleusercontent.com/5rcQ32ml8E5ONp9f9-Rf78IofLb9QjS5_0mqsY1zEFc=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-basis-25" src="https://lh3.googleusercontent.com/Z4gtm5Bkxyv21Z2PtbTf95Clb9AE4VTR6olbBKYrenM=w400-h300-no-n" layout=flex-item></amp-img>
</div>

<h3>Set flex-item's size through flex-grow.</h3>
<div class="container">
<amp-img class="child-flex-grow-2" src="https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/5rcQ32ml8E5ONp9f9-Rf78IofLb9QjS5_0mqsY1zEFc=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/Z4gtm5Bkxyv21Z2PtbTf95Clb9AE4VTR6olbBKYrenM=w400-h300-no-n" layout=flex-item></amp-img>
</div>

<h3>Non flex container parent with flex-item children.</h3>
<div class="container-no-flex">
<amp-img class="child-flex-size-set" src="https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-size-set" src="https://lh3.googleusercontent.com/5rcQ32ml8E5ONp9f9-Rf78IofLb9QjS5_0mqsY1zEFc=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-size-set" src="https://lh3.googleusercontent.com/Z4gtm5Bkxyv21Z2PtbTf95Clb9AE4VTR6olbBKYrenM=w400-h300-no-n" layout=flex-item></amp-img>
</div>

<h3>Flex container parent contain both flex-item children and non flex-item children.</h3>
<div class="container">
<amp-img src="https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n" layout=fixed width="200" height="150"></amp-img>
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n" width="100" height="75" layout=flex-item></amp-img>
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/5rcQ32ml8E5ONp9f9-Rf78IofLb9QjS5_0mqsY1zEFc=w400-h300-no-n" layout=flex-item></amp-img>
<amp-img class="child-flex-default" src="https://lh3.googleusercontent.com/Z4gtm5Bkxyv21Z2PtbTf95Clb9AE4VTR6olbBKYrenM=w400-h300-no-n" layout=flex-item></amp-img>
</div>

<h3>Flex container parent with non flex-item children. Children's width and height have to be set manually.</h3>
<div class="container">
<amp-img src="https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n" width="100" height="75"></amp-img>
<amp-img src="https://lh3.googleusercontent.com/5rcQ32ml8E5ONp9f9-Rf78IofLb9QjS5_0mqsY1zEFc=w400-h300-no-n" width="100" height="75"></amp-img>
<amp-img src="https://lh3.googleusercontent.com/Z4gtm5Bkxyv21Z2PtbTf95Clb9AE4VTR6olbBKYrenM=w400-h300-no-n" width="100" height="75"></amp-img>
</div>
</body>
</html>
1 change: 1 addition & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ function buildExamples(watch) {
buildExample('dailymotion.amp.html');
buildExample('carousel.amp.html');
buildExample('csp.amp.html');
buildExample('layout-flex-item.amp.html');
buildExample('metadata-examples/article-json-ld.amp.html');
buildExample('metadata-examples/article-microdata.amp.html');
buildExample('metadata-examples/recipe-json-ld.amp.html');
Expand Down
8 changes: 6 additions & 2 deletions spec/amp-html-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ the layout of a `fill` element matches its parent.

The element lets its children to define its size, much like a normal HTML `div`.

### `flex-item`
The element and other elements in its parent with layout type `flex-item` take their parent container's remaining space when parent has `display: flex`.

## Layout Attributes

Expand Down Expand Up @@ -104,6 +106,7 @@ maintaining the height based on the aspect ratio.
container. Its children are rendered immediately.
- `nodisplay`: The component takes up zero space on the screen as if its display style was `none`.
The `width` and `height` attributes are not required.
- `flex-item`: Element size will be determined by the parent element and the number of other elements inside parent according to `display:flex` CSS layout.

Each element documents which `layout` values it supported. If an element does not support the
specified value it would trigger a runtime error.
Expand Down Expand Up @@ -215,8 +218,8 @@ The element is sized and displayed based on the `layout`, `width`, `height` and
by the runtime. All of the layout rules are implemented via CSS internally. The element is said to
"define size" if its size is inferrable via CSS styles and does not change based on its children:
available immediately or inserted dynamically. This does not mean that this element's size cannot
change. The layout could be fully responsive as is the case with `responsive`, `fixed-height` and
`fill` layouts. It simply means that the size does not change without an explicit user action, e.g.
change. The layout could be fully responsive as is the case with `responsive`, `fixed-height`, `fill` and
`flex-item` layouts. It simply means that the size does not change without an explicit user action, e.g.
during rendering or scrolling or post download.

If the element has been configured incorrectly it will not be rendered at all in PROD and in DEV mode
Expand All @@ -242,3 +245,4 @@ apply as is the case with `amp-pixel` and `amp-audio`.
| fixed-height | `height` only. `width` can be `auto` | yes, specified by the parent container and `height` | no | `block` |
| fill | no | yes, parent's size | no | `block` |
| container | no | no | no | `block` |
| flex-item | no | no | yes, based on parent container | `block` |
9 changes: 9 additions & 0 deletions src/custom-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ export function applyLayout_(element) {
// Do nothing. Elements themselves will check whether the supplied
// layout value is acceptable. In particular container is only OK
// sometimes.
} else if (layout == Layout.FLEX_ITEM) {
// Set height and width to a flex item if they exist.
// The size set to a flex item could be overridden by `display: flex` later.
if (width) {
element.style.width = width;
}
if (height) {
element.style.height = height;
}
}
return layout;
}
Expand Down
4 changes: 3 additions & 1 deletion src/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const Layout = {
RESPONSIVE: 'responsive',
CONTAINER: 'container',
FILL: 'fill',
FLEX_ITEM: 'flex-item',
};


Expand Down Expand Up @@ -122,7 +123,8 @@ export function isLayoutSizeDefined(layout) {
return (layout == Layout.FIXED ||
layout == Layout.FIXED_HEIGHT ||
layout == Layout.RESPONSIVE ||
layout == Layout.FILL);
layout == Layout.FILL ||
layout == Layout.FLEX_ITEM);
}


Expand Down
12 changes: 12 additions & 0 deletions test/functional/test-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,18 @@ describe('Layout', () => {
expect(div.children.length).to.equal(0);
});

it('layout=flex-item', () => {
div.setAttribute('layout', 'flex-item');
div.setAttribute('width', 100);
div.setAttribute('height', 200);
expect(applyLayout_(div)).to.equal(Layout.FLEX_ITEM);
expect(div.style.width).to.equal('100px');
expect(div.style.height).to.equal('200px');
expect(div).to.have.class('-amp-layout-flex-item');
expect(div).to.have.class('-amp-layout-size-defined');
expect(div.children.length).to.equal(0);
});

it('layout=unknown', () => {
div.setAttribute('layout', 'foo');
expect(function() {
Expand Down

0 comments on commit 162356c

Please sign in to comment.