Reputation: 41
/**
* Plugin: RichTile
*
* Because I got a little ambitious and decided to include ARIA attributes
* and stuff, it became easier to manage this as a plugin.
*/
var RichTile = function (element, options) {
this.element = $(element);
this.options = $.extend({}, RichTile.DEFAULTS, options);
this.flyoutElement = this.element.find(this.options.flyout);
this.toggleElement = this.element.find(this.options.toggle);
this.toggleElement.on({
'click.RichTile': $.proxy(this.clickHandler, this),
'keyup.RichTile': $.proxy(this.keyHandler, this)
});
};
RichTile.DATA_KEY = 'plugin_richTile';
RichTile.DEFAULTS = {
flyout: '.js-tile-flyout',
toggle: '.js-toggle-tile',
expandedClass: 'is-expanded',
disabledClass: 'is-disabled',
toggleKeyCodes: [13, 32] // ENTER, SPACE
};
RichTile.prototype.isExpanded = function() {
return this.element.hasClass(this.options.expandedClass);
};
RichTile.prototype.isDisabled = function() {
return this.element.hasClass(this.options.disabledClass);
};
RichTile.prototype.isEnabled = function() {
return ! this.isDisabled();
};
RichTile.prototype.toggle = function(expand) {
if (typeof expand === 'undefined') {
expand = ! this.isExpanded();
}
if (this.isEnabled() || !expand) {
this.flyoutElement.attr('aria-hidden', ! expand);
this.toggleElement.attr('aria-expanded', expand);
this.element.toggleClass(this.options.expandedClass, expand);
this.element.trigger((expand ? 'expanded' : 'collapsed') + '.RichTile', [ this ]);
}
return this;
};
RichTile.prototype.expand = function() {
return this.toggle(true);
};
RichTile.prototype.collapse = function() {
return this.toggle(false);
};
RichTile.prototype.toggleEnable = function(enable) {
if (typeof enable === 'undefined') {
enable = this.isDisabled();
}
this.toggleElement.filter('[tabindex]').attr({
'tabindex': enable ? 0 : -1,
'aria-disabled': ! enable
});
if (! enable) {
this.toggle(false);
}
this.element.toggleClass(this.options.disabledClass, ! enable);
this.element.trigger((enable ? 'enabled' : 'disabled') + '.RichTile', [ this ]);
return this;
};
RichTile.prototype.enable = function() {
return this.toggleEnable(true);
};
RichTile.prototype.disable = function() {
return this.toggleEnable(false);
};
RichTile.prototype.clickHandler = function(event) {
event.preventDefault();
return this.toggle();
};
RichTile.prototype.keyHandler = function(event) {
if (this.options.toggleKeyCodes.indexOf(event.which) > -1) {
event.preventDefault();
return this.toggle();
}
};
$.fn.richTile = function(option) {
return this.each(function() {
var data = $.data(this, RichTile.DATA_KEY);
if (!data) {
$.data(this, RichTile.DATA_KEY, (data = new RichTile(this, typeof option === 'object' && option)));
}
if (typeof option === 'string') {
data[option]();
}
});
};
/**
* Apply plugin and account for desired behavior outside of individual toggles.
*/
$('.js-tile').richTile().on({
'expanded.RichTile': function(event, tile) {
// disable siblings on expand
var siblings = tile.element.siblings('.js-tile');
siblings.richTile('disable');
// re-enable when this tile is collapsed
tile.element.one('collapsed.RichTile', function() {
siblings.richTile('enable');
});
}
});
/**
* Variables
*/
/**
* Scaffolding
*/
* {
margin: 0;
}
* + * {
margin-top: 1rem;
}
html {
background: #444;
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
color: #e1e1e1;
font: 1em/1.5 "Source Sans Pro", sans-serif;
margin: 0 auto 1rem;
max-width: 64em;
}
h1,
a {
color: #fff;
font-weight: 600;
}
h1 {
font-size: 2.25em;
line-height: 1.1;
text-rendering: optimizeLegibility;
}
label {
display: block;
}
pre,
code {
font-family: "Source Code Pro", monospace;
}
/**
* Component: Grid
*
* https://github.com/suitcss/components-grid/
*/
.Grid {
display: block;
font-size: 0;
margin: 0;
padding: 0;
text-align: left;
}
.Grid--withGutter {
margin: 0 -0.5rem;
}
.Grid--withGutter > .Grid-cell {
padding: 0 0.5rem;
}
.Grid-cell {
box-sizing: border-box;
display: inline-block;
font-size: 1rem;
margin: 0;
padding: 0;
text-align: left;
vertical-align: top;
width: 100%;
}
/**
* Component: Card
*/
.Card-image {
display: inline-block;
position: relative;
width: 100%;
}
.Card-image:after {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.Card-image img {
display: block;
height: 100%;
width: 100%;
}
.Card-expiry {
color: #aaa;
font-size: 0.6666666667em;
}
/**
* Component: Input
*/
.Input {
background: #fff;
border: 3px solid #e1e1e1;
border-radius: 0.375rem;
color: #444;
display: block;
font: inherit;
padding: 0.5rem 1rem;
width: 100%;
-webkit-appearance: none;
}
.Input:hover {
border-color: #aaa;
}
.Input:focus {
border-color: #08c;
outline: 0;
}
.Input.is-visa, .Input.is-mastercard, .Input.is-amex {
background-position: 0.75rem center;
background-repeat: no-repeat;
padding-left: 3.375rem;
}
.Input.is-visa {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-visa.svg");
}
.Input.is-mastercard {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-mastercard.svg");
}
.Input.is-amex {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-amex.svg");
}
/**
* Component: Button
*/
.Button {
background: #fff;
border: 3px solid transparent;
border-radius: 0.375rem;
color: #08c;
cursor: pointer;
display: inline-block;
font: inherit;
font-weight: 600;
line-height: normal;
margin: 0;
padding: 0.5rem 1rem;
}
.Button:focus, .Button:hover {
color: #00aaff;
}
.Button--primary {
background: #08c;
color: #fff !important;
}
.Button--primary:focus, .Button--primary:hover {
background: #00aaff;
}
/**
* Component: Tiles
*/
.Tiles {
font-size: 0;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.Tile {
display: inline-block;
font-size: 1rem;
margin: 0;
vertical-align: top;
width: 100%;
}
.Tile-content {
background: #fff;
border-radius: 0.375rem;
color: #444;
margin: 1rem 0.5rem 0;
min-height: 10em;
padding: 1rem;
position: relative;
}
.Tile-content--toggle {
cursor: pointer;
}
.Tile-content--toggle:focus, .Tile-content--toggle:hover {
box-shadow: 0 0 0 3px #75d1ff;
outline: 0;
}
.Tile.is-disabled .Tile-content--toggle {
cursor: default;
opacity: 0.5;
}
.Tile.is-disabled .Tile-content--toggle:focus, .Tile.is-disabled .Tile-content--toggle:hover {
box-shadow: none;
}
.Tile-flyout {
display: none;
position: relative;
}
.Tile.is-expanded .Tile-flyout {
display: block;
}
.Tile-flyout:before {
background: #fff;
content: "";
left: 50%;
margin-left: -0.5rem;
position: absolute;
height: 1rem;
top: -0.5rem;
transform: rotate(45deg);
width: 1rem;
}
/**
* Breakpoint layout changes
*/
@media (min-width: 30em) {
.Tile {
width: 50%;
}
.Tile-flyout {
width: 200%;
}
.Tile:nth-child(2n+1) .Tile-flyout {
margin-left: 0%;
}
.Tile:nth-child(2n+1) .Tile-flyout:before {
left: 25%;
}
.Tile:nth-child(2n+2) .Tile-flyout {
margin-left: -100%;
}
.Tile:nth-child(2n+2) .Tile-flyout:before {
left: 75%;
}
}
@media (min-width: 48em) {
.Tile {
width: 33.3333333333%;
}
.Tile-flyout {
width: 300%;
}
.Tile:nth-child(3n+1) .Tile-flyout {
margin-left: 0%;
}
.Tile:nth-child(3n+1) .Tile-flyout:before {
left: 16.6666666667%;
}
.Tile:nth-child(3n+2) .Tile-flyout {
margin-left: -100%;
}
.Tile:nth-child(3n+2) .Tile-flyout:before {
left: 50%;
}
.Tile:nth-child(3n+3) .Tile-flyout {
margin-left: -200%;
}
.Tile:nth-child(3n+3) .Tile-flyout:before {
left: 83.3333333333%;
}
}
@media (min-width: 64em) {
.Tile {
width: 25%;
}
.Tile-flyout {
width: 400%;
}
.Tile:nth-child(4n+1) .Tile-flyout {
margin-left: 0%;
}
.Tile:nth-child(4n+1) .Tile-flyout:before {
left: 12.5%;
}
.Tile:nth-child(4n+2) .Tile-flyout {
margin-left: -100%;
}
.Tile:nth-child(4n+2) .Tile-flyout:before {
left: 37.5%;
}
.Tile:nth-child(4n+3) .Tile-flyout {
margin-left: -200%;
}
.Tile:nth-child(4n+3) .Tile-flyout:before {
left: 62.5%;
}
.Tile:nth-child(4n+4) .Tile-flyout {
margin-left: -300%;
}
.Tile:nth-child(4n+4) .Tile-flyout:before {
left: 87.5%;
}
}
/**
* Utilities: Space
*/
.u-marginTop {
margin-top: 1rem;
}
@media (min-width: 48em) {
.u-md-no-marginTop {
margin-top: 0;
}
}
/**
* Utilities: Size
*
* https://github.com/suitcss/utils-size/
*/
.u-size1of2 {
width: 50% !important;
}
@media (min-width: 48em) {
.u-md-size1of2 {
width: 50% !important;
}
}
/**
* Utilities: Text
*
* https://github.com/suitcss/utils-text/
*/
.u-textCenter {
text-align: center !important;
}
.u-textRight {
text-align: right !important;
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Responsive tiles with column-spanning flyouts</title>
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Source+Code+Pro'><link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<div class="Tiles">
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-0">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-visa.svg" alt="Visa">
</div>
<pre class="Card-code"><code>●●●● ●●●● ●●●● 1234</code></pre>
<p class="Card-expiry">Expires May 2017</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-0"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-visa" type="text" value="XXXX XXXX XXXX 1234">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="05 / 17" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-1">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-mastercard.svg" alt="Mastercard">
</div>
<pre class="Card-code"><code>●●●● ●●●● ●●●● 0000</code></pre>
<p class="Card-expiry">Expires July 2018</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-1"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-mastercard" type="text" value="XXXX XXXX XXXX 0000">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="07 / 18" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-2">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-amex.svg" alt="American Express">
</div>
<pre class="Card-code"><code>●●●● ●●●●●● ●1001</code></pre>
<p class="Card-expiry">Expires February 2019</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-2"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-amex" type="text" value="XXXX XXXXXX X1001">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="02 / 19" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-3">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-visa.svg" alt="Visa">
</div>
<pre class="Card-code"><code>●●●● ●●●● ●●●● 1234</code></pre>
<p class="Card-expiry">Expires May 2017</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-3"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-visa" type="text" value="XXXX XXXX XXXX 1234">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="05 / 17" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-4">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-mastercard.svg" alt="Mastercard">
</div>
<pre class="Card-code"><code>●●●● ●●●● ●●●● 0000</code></pre>
<p class="Card-expiry">Expires July 2018</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-4"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-mastercard" type="text" value="XXXX XXXX XXXX 0000">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="07 / 18" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-5">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-amex.svg" alt="American Express">
</div>
<pre class="Card-code"><code>●●●● ●●●●●● ●1001</code></pre>
<p class="Card-expiry">Expires February 2019</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-5"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-amex" type="text" value="XXXX XXXXXX X1001">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="02 / 19" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
</div>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script><script src="./script.js"></script>
</body>
</html>
I am really new with html / javascript.
I am playing around with this code i found in google.
I wanted to know how would i make the flyout hide when i click anywhere on the window part from the flyout itself.
Currently to hide the flyout you have to click back on the main picture, or click a button.
Thanks.
Upvotes: 2
Views: 504
Reputation: 33933
I added this to determine if a click made anywhere in the document has been done inside a .Tile-flyout
or inside a .js-tile
that is not "disabled".
// A click outside something active
$(document).on("click", function(e){
// the click did not occur inside a tile "flyout" or inside an "not disabled" tile
if(!($(e.target).closest(".Tile-flyout").length == 1 || $(e.target).closest(".js-tile:not(.is-disabled)").length == 1)){
console.log("CLOSE!")
// Then simply simulate a click in the active one
$(".is-expanded>div").trigger("click")
}
})
/**
* Plugin: RichTile
*
* Because I got a little ambitious and decided to include ARIA attributes
* and stuff, it became easier to manage this as a plugin.
*/
var RichTile = function (element, options) {
this.element = $(element);
this.options = $.extend({}, RichTile.DEFAULTS, options);
this.flyoutElement = this.element.find(this.options.flyout);
this.toggleElement = this.element.find(this.options.toggle);
this.toggleElement.on({
'click.RichTile': $.proxy(this.clickHandler, this),
'keyup.RichTile': $.proxy(this.keyHandler, this)
});
};
RichTile.DATA_KEY = 'plugin_richTile';
RichTile.DEFAULTS = {
flyout: '.js-tile-flyout',
toggle: '.js-toggle-tile',
expandedClass: 'is-expanded',
disabledClass: 'is-disabled',
toggleKeyCodes: [13, 32] // ENTER, SPACE
};
RichTile.prototype.isExpanded = function() {
return this.element.hasClass(this.options.expandedClass);
};
RichTile.prototype.isDisabled = function() {
return this.element.hasClass(this.options.disabledClass);
};
RichTile.prototype.isEnabled = function() {
return ! this.isDisabled();
};
RichTile.prototype.toggle = function(expand) {
if (typeof expand === 'undefined') {
expand = ! this.isExpanded();
}
if (this.isEnabled() || !expand) {
this.flyoutElement.attr('aria-hidden', ! expand);
this.toggleElement.attr('aria-expanded', expand);
this.element.toggleClass(this.options.expandedClass, expand);
this.element.trigger((expand ? 'expanded' : 'collapsed') + '.RichTile', [ this ]);
}
return this;
};
RichTile.prototype.expand = function() {
return this.toggle(true);
};
RichTile.prototype.collapse = function() {
return this.toggle(false);
};
RichTile.prototype.toggleEnable = function(enable) {
if (typeof enable === 'undefined') {
enable = this.isDisabled();
}
this.toggleElement.filter('[tabindex]').attr({
'tabindex': enable ? 0 : -1,
'aria-disabled': ! enable
});
if (! enable) {
this.toggle(false);
}
this.element.toggleClass(this.options.disabledClass, ! enable);
this.element.trigger((enable ? 'enabled' : 'disabled') + '.RichTile', [ this ]);
return this;
};
RichTile.prototype.enable = function() {
return this.toggleEnable(true);
};
RichTile.prototype.disable = function() {
return this.toggleEnable(false);
};
RichTile.prototype.clickHandler = function(event) {
event.preventDefault();
return this.toggle();
};
RichTile.prototype.keyHandler = function(event) {
if (this.options.toggleKeyCodes.indexOf(event.which) > -1) {
event.preventDefault();
return this.toggle();
}
};
$.fn.richTile = function(option) {
return this.each(function() {
var data = $.data(this, RichTile.DATA_KEY);
if (!data) {
$.data(this, RichTile.DATA_KEY, (data = new RichTile(this, typeof option === 'object' && option)));
}
if (typeof option === 'string') {
data[option]();
}
});
};
/**
* Apply plugin and account for desired behavior outside of individual toggles.
*/
$('.js-tile').richTile().on({
'expanded.RichTile': function(event, tile) {
// disable siblings on expand
var siblings = tile.element.siblings('.js-tile');
siblings.richTile('disable');
// re-enable when this tile is collapsed
tile.element.one('collapsed.RichTile', function() {
siblings.richTile('enable');
});
}
});
// A click outside something active
$(document).on("click", function(e){
// the click did not occur inside a tile "flyout" or inside an "not disabled" tile
if(!($(e.target).closest(".Tile-flyout").length == 1 || $(e.target).closest(".js-tile:not(.is-disabled)").length == 1)){
console.log("CLOSE!")
// Then simply simulate a click in the active one
$(".is-expanded>div").trigger("click")
}
})
/**
* Variables
*/
/**
* Scaffolding
*/
* {
margin: 0;
}
* + * {
margin-top: 1rem;
}
html {
background: #444;
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
color: #e1e1e1;
font: 1em/1.5 "Source Sans Pro", sans-serif;
margin: 0 auto 1rem;
max-width: 64em;
}
h1,
a {
color: #fff;
font-weight: 600;
}
h1 {
font-size: 2.25em;
line-height: 1.1;
text-rendering: optimizeLegibility;
}
label {
display: block;
}
pre,
code {
font-family: "Source Code Pro", monospace;
}
/**
* Component: Grid
*
* https://github.com/suitcss/components-grid/
*/
.Grid {
display: block;
font-size: 0;
margin: 0;
padding: 0;
text-align: left;
}
.Grid--withGutter {
margin: 0 -0.5rem;
}
.Grid--withGutter > .Grid-cell {
padding: 0 0.5rem;
}
.Grid-cell {
box-sizing: border-box;
display: inline-block;
font-size: 1rem;
margin: 0;
padding: 0;
text-align: left;
vertical-align: top;
width: 100%;
}
/**
* Component: Card
*/
.Card-image {
display: inline-block;
position: relative;
width: 100%;
}
.Card-image:after {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.Card-image img {
display: block;
height: 100%;
width: 100%;
}
.Card-expiry {
color: #aaa;
font-size: 0.6666666667em;
}
/**
* Component: Input
*/
.Input {
background: #fff;
border: 3px solid #e1e1e1;
border-radius: 0.375rem;
color: #444;
display: block;
font: inherit;
padding: 0.5rem 1rem;
width: 100%;
-webkit-appearance: none;
}
.Input:hover {
border-color: #aaa;
}
.Input:focus {
border-color: #08c;
outline: 0;
}
.Input.is-visa, .Input.is-mastercard, .Input.is-amex {
background-position: 0.75rem center;
background-repeat: no-repeat;
padding-left: 3.375rem;
}
.Input.is-visa {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-visa.svg");
}
.Input.is-mastercard {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-mastercard.svg");
}
.Input.is-amex {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-amex.svg");
}
/**
* Component: Button
*/
.Button {
background: #fff;
border: 3px solid transparent;
border-radius: 0.375rem;
color: #08c;
cursor: pointer;
display: inline-block;
font: inherit;
font-weight: 600;
line-height: normal;
margin: 0;
padding: 0.5rem 1rem;
}
.Button:focus, .Button:hover {
color: #00aaff;
}
.Button--primary {
background: #08c;
color: #fff !important;
}
.Button--primary:focus, .Button--primary:hover {
background: #00aaff;
}
/**
* Component: Tiles
*/
.Tiles {
font-size: 0;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.Tile {
display: inline-block;
font-size: 1rem;
margin: 0;
vertical-align: top;
width: 100%;
}
.Tile-content {
background: #fff;
border-radius: 0.375rem;
color: #444;
margin: 1rem 0.5rem 0;
min-height: 10em;
padding: 1rem;
position: relative;
}
.Tile-content--toggle {
cursor: pointer;
}
.Tile-content--toggle:focus, .Tile-content--toggle:hover {
box-shadow: 0 0 0 3px #75d1ff;
outline: 0;
}
.Tile.is-disabled .Tile-content--toggle {
cursor: default;
opacity: 0.5;
}
.Tile.is-disabled .Tile-content--toggle:focus, .Tile.is-disabled .Tile-content--toggle:hover {
box-shadow: none;
}
.Tile-flyout {
display: none;
position: relative;
}
.Tile.is-expanded .Tile-flyout {
display: block;
}
.Tile-flyout:before {
background: #fff;
content: "";
left: 50%;
margin-left: -0.5rem;
position: absolute;
height: 1rem;
top: -0.5rem;
transform: rotate(45deg);
width: 1rem;
}
/**
* Breakpoint layout changes
*/
@media (min-width: 30em) {
.Tile {
width: 50%;
}
.Tile-flyout {
width: 200%;
}
.Tile:nth-child(2n+1) .Tile-flyout {
margin-left: 0%;
}
.Tile:nth-child(2n+1) .Tile-flyout:before {
left: 25%;
}
.Tile:nth-child(2n+2) .Tile-flyout {
margin-left: -100%;
}
.Tile:nth-child(2n+2) .Tile-flyout:before {
left: 75%;
}
}
@media (min-width: 48em) {
.Tile {
width: 33.3333333333%;
}
.Tile-flyout {
width: 300%;
}
.Tile:nth-child(3n+1) .Tile-flyout {
margin-left: 0%;
}
.Tile:nth-child(3n+1) .Tile-flyout:before {
left: 16.6666666667%;
}
.Tile:nth-child(3n+2) .Tile-flyout {
margin-left: -100%;
}
.Tile:nth-child(3n+2) .Tile-flyout:before {
left: 50%;
}
.Tile:nth-child(3n+3) .Tile-flyout {
margin-left: -200%;
}
.Tile:nth-child(3n+3) .Tile-flyout:before {
left: 83.3333333333%;
}
}
@media (min-width: 64em) {
.Tile {
width: 25%;
}
.Tile-flyout {
width: 400%;
}
.Tile:nth-child(4n+1) .Tile-flyout {
margin-left: 0%;
}
.Tile:nth-child(4n+1) .Tile-flyout:before {
left: 12.5%;
}
.Tile:nth-child(4n+2) .Tile-flyout {
margin-left: -100%;
}
.Tile:nth-child(4n+2) .Tile-flyout:before {
left: 37.5%;
}
.Tile:nth-child(4n+3) .Tile-flyout {
margin-left: -200%;
}
.Tile:nth-child(4n+3) .Tile-flyout:before {
left: 62.5%;
}
.Tile:nth-child(4n+4) .Tile-flyout {
margin-left: -300%;
}
.Tile:nth-child(4n+4) .Tile-flyout:before {
left: 87.5%;
}
}
/**
* Utilities: Space
*/
.u-marginTop {
margin-top: 1rem;
}
@media (min-width: 48em) {
.u-md-no-marginTop {
margin-top: 0;
}
}
/**
* Utilities: Size
*
* https://github.com/suitcss/utils-size/
*/
.u-size1of2 {
width: 50% !important;
}
@media (min-width: 48em) {
.u-md-size1of2 {
width: 50% !important;
}
}
/**
* Utilities: Text
*
* https://github.com/suitcss/utils-text/
*/
.u-textCenter {
text-align: center !important;
}
.u-textRight {
text-align: right !important;
}
/* ADDED to restore the SO console's style */
.as-console{
color: black !important;
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Responsive tiles with column-spanning flyouts</title>
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Source+Code+Pro'><link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<div class="Tiles">
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-0">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-visa.svg" alt="Visa">
</div>
<pre class="Card-code"><code>●●●● ●●●● ●●●● 1234</code></pre>
<p class="Card-expiry">Expires May 2017</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-0"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-visa" type="text" value="XXXX XXXX XXXX 1234">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="05 / 17" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-1">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-mastercard.svg" alt="Mastercard">
</div>
<pre class="Card-code"><code>●●●● ●●●● ●●●● 0000</code></pre>
<p class="Card-expiry">Expires July 2018</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-1"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-mastercard" type="text" value="XXXX XXXX XXXX 0000">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="07 / 18" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-2">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-amex.svg" alt="American Express">
</div>
<pre class="Card-code"><code>●●●● ●●●●●● ●1001</code></pre>
<p class="Card-expiry">Expires February 2019</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-2"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-amex" type="text" value="XXXX XXXXXX X1001">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="02 / 19" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-3">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-visa.svg" alt="Visa">
</div>
<pre class="Card-code"><code>●●●● ●●●● ●●●● 1234</code></pre>
<p class="Card-expiry">Expires May 2017</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-3"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-visa" type="text" value="XXXX XXXX XXXX 1234">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="05 / 17" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-4">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-mastercard.svg" alt="Mastercard">
</div>
<pre class="Card-code"><code>●●●● ●●●● ●●●● 0000</code></pre>
<p class="Card-expiry">Expires July 2018</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-4"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-mastercard" type="text" value="XXXX XXXX XXXX 0000">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="07 / 18" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="Tile js-tile">
<div class="Tile-content Tile-content--toggle js-toggle-tile"
role="button"
tabindex="0"
aria-expanded="false"
aria-controls="edit-flyout-5">
<div class="Card-image">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/creditcard-amex.svg" alt="American Express">
</div>
<pre class="Card-code"><code>●●●● ●●●●●● ●1001</code></pre>
<p class="Card-expiry">Expires February 2019</p>
</div>
<form class="Tile-flyout js-tile-flyout"
id="edit-flyout-5"
aria-hidden="true">
<div class="Tile-content">
<div class="Grid Grid--withGutter">
<div class="Grid-cell u-md-size1of2">
<label>
Card Number
<input class="Input is-amex" type="text" value="XXXX XXXXXX X1001">
</label>
<label>
Full Name on Card
<input class="Input" type="text" value="John Smith">
</label>
<div class="Grid Grid--withGutter u-marginTop">
<div class="Grid-cell u-size1of2">
<label>
Expiration Date
<input class="Input" type="text" value="02 / 19" placeholder="MM / YY">
</label>
</div>
<div class="Grid-cell u-size1of2">
<label>
Security Code
<input class="Input" type="text" value="XXX">
</label>
</div>
</div>
</div>
<div class="Grid-cell u-md-size1of2 u-marginTop u-md-no-marginTop">
<label>
Address Line 1
<input class="Input" type="text" value="208 SW 1st Ave">
</label>
<label>
Address Line 2
<input class="Input" type="text" value="Ste. 240">
</label>
<label>
Zip/Postal Code
<input class="Input" type="text" value="97204">
</label>
</div>
</div>
<div class="u-textRight">
<button class="Button js-toggle-tile" type="button">Never Mind</button>
<button class="Button Button--primary js-toggle-tile" type="submit">Save</button>
</div>
</div>
</form>
</div>
</div>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script><script src="./script.js"></script>
</body>
</html>
Upvotes: 1