How to flip iron-icon vertically in css - css

I'm using iron-icon components for my Polymer 2 application, and I want to know how to flip these icons vertically or horizontally? I've tried the transform attribute and equivalent for other browsers, but it didn't work for me. as below:
.my-icon-class {
color: #55555A;
margin-top: 10px;
width: 30px;
height: 50px;
transform: scale(-1);
}
I've even tried ´filter´ attributte on IE:
.my-icon-class {
color: #55555A;
margin-top: 10px;
width: 30px;
height: 50px;
filter: FLipH;
}
And my icon instantiation looks like:
<iron-icon class="my-icon-class" icon="icons:room"></iron-icon>
The imports statement goes like this:
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
You can find a snippest here below:
// Load webcomponents.js polyfill if browser doesn't support native Web Components.
var webComponentsSupported = (
'registerElement' in document
&& 'import' in document.createElement('link')
&& 'content' in document.createElement('template')
);
if (webComponentsSupported) {
// For native Imports, manually fire WebComponentsReady so user code
// can use the same code path for native and polyfill'd imports.
if (!window.HTMLImports) {
document.dispatchEvent(
new CustomEvent('WebComponentsReady', {bubbles: true})
);
}
} else {
// Load webcomponents.js polyfill
var script = document.createElement('script');
script.async = true;
script.src = 'https://cdn.rawgit.com/StartPolymer/cdn/1.8.1/components/webcomponentsjs/webcomponents-lite.min.js';
document.head.appendChild(script);
}
h1 {
font-size: 24px;
font-weight: 500;
line-height: 32px;
margin: 24px 0;
}
.my-icon-class {
color: #55555A;
margin-top: 10px;
width: 50px;
height: 70px;
}
<!-- <base href="https://gitcdn.xyz/cdn/StartPolymer/cdn/v1.11.0/components/"> -->
<!-- <base href="https://cdn.rawgit.com/StartPolymer/cdn/v1.11.0/components/"> -->
<base href="https://rawcdn.githack.com/StartPolymer/cdn/v1.11.0/components/">
<link rel="import" href="iron-icon/iron-icon.html">
<link rel="import" href="iron-icons/iron-icons.html">
<style is="custom-style">
body {
#apply(--layout-vertical);
#apply(--layout-center-center);
}
</style>
<h1>Polymer Icon to Flip</h1>
<p>And I want to flip it vertically and/or horizontally, need only the css. Thanks</p>
<iron-icon class="my-icon-class" icon="icons:room"></iron-icon>
icon to flip
<script>
window.addEventListener('WebComponentsReady', function() {
// Async call needed here for IE11 compatibility.
Polymer.Base.async(function() {
});
});
</script>
If need more info plz ask in comments.

I found a solution by using:
.my-class {
transform: rotate(180deg);
}

Hi please have a look in updated snippet.
// Load webcomponents.js polyfill if browser doesn't support native Web Components.
var webComponentsSupported = (
'registerElement' in document
&& 'import' in document.createElement('link')
&& 'content' in document.createElement('template')
);
if (webComponentsSupported) {
// For native Imports, manually fire WebComponentsReady so user code
// can use the same code path for native and polyfill'd imports.
if (!window.HTMLImports) {
document.dispatchEvent(
new CustomEvent('WebComponentsReady', {bubbles: true})
);
}
} else {
// Load webcomponents.js polyfill
var script = document.createElement('script');
script.async = true;
script.src = 'https://cdn.rawgit.com/StartPolymer/cdn/1.8.1/components/webcomponentsjs/webcomponents-lite.min.js';
document.head.appendChild(script);
}
h1 {
font-size: 24px;
font-weight: 500;
line-height: 32px;
margin: 24px 0;
}
.my-icon-class {
color: #55555A;
margin-top: 10px;
width: 50px;
height: 70px;
transform: rotateX(180deg);
}
.my-icon-class:hover {
transform: rotateY(180deg);
}
<!-- <base href="https://gitcdn.xyz/cdn/StartPolymer/cdn/v1.11.0/components/"> -->
<!-- <base href="https://cdn.rawgit.com/StartPolymer/cdn/v1.11.0/components/"> -->
<base href="https://rawcdn.githack.com/StartPolymer/cdn/v1.11.0/components/">
<link rel="import" href="iron-icon/iron-icon.html">
<link rel="import" href="iron-icons/iron-icons.html">
<style is="custom-style">
body {
#apply(--layout-vertical);
#apply(--layout-center-center);
}
</style>
<h1>Polymer Icon to Flip</h1>
<p>And I want to flip it vertically and/or horizontally, need only the css. Thanks</p>
<iron-icon class="my-icon-class" icon="icons:room"></iron-icon>
icon to flip
<script>
window.addEventListener('WebComponentsReady', function() {
// Async call needed here for IE11 compatibility.
Polymer.Base.async(function() {
});
});
</script>

Related

the function display_html not working in Jupyter Lab

This "R code" works fine in Jupyter but not in lab:
library(IRdisplay)
display_html(
'
<script>
code_show=true;
function code_toggle() {
if (code_show){
$(\'div.input\').hide();
} else {
$(\'div.input\').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()">
<input type="submit" value="Code On/Off">
</form>
<style type="text/css">
.container { width:80% !important; }
.main-container {
max-width: 2000px;
margin-left: 100px;
margin-right: 10px;
}
/*body{font-family: Lucida Sans Unicode} */
.nav>li>a {
position: relative;
display: block;
padding: 10px 15px;
color: #004F59;
}
.nav-pills>li.active>a, .nav-pills>li.active>a:hover, .nav-pills>li.active>a:focus {
color: #ffffff;
background-color: #004F59;
}
.list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover {
background-color: #004F59;
}
</style>
'
)
I also tried to use display_html in other contexts. Is there a reason why this does not work in lab? Can it easily be fixed? Thanks.
The IRdisplay::display_html() works fine in JupyterLab, as does the callback to your function. The only differences between Notebook v6 and JupyterLab are:
jQuery is not available by default in JupyterLab (as it is no longer needed in 2020's), so the selection by $(\'div.input\').hide(); will not work - use standard document.querySelectorAll() instead
CSS classes are different so styles (and selectors need to be adjusted); it is not clear what you wanted to achieve but for hiding input areas you can achieve the same effect with standard JS in JupyterLab:
IRdisplay::display_html('
<script type="text/javascript">
let code_show = true;
function code_toggle() {
if (code_show) {
document.querySelectorAll(".jp-Cell-inputArea").forEach(function(inputArea) {
inputArea.style.display = "none";
});
} else {
document.querySelectorAll(".jp-Cell-inputArea").forEach(function(inputArea) {
inputArea.style.display = "";
});
}
code_show = !code_show;
}
</script>
<form action="javascript:code_toggle()">
<input type="submit" value="Code On/Off">
</form>
')

how to dynamically apply Multiple CSS files as per URL Param value in typescript or in Javascript

I have written the code for getting the URL param value
export class RedirectingComponent implements OnInit {
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit()
{
this.activatedRoute.paramMap.subscribe(params=>
{
let color=params.get('color');
console.log(color);
if(color)
{
if(color=='red')
{
//So If the color is red then we should apply red.css
}
}
})
}
}
Here are the css files
red.css
.my-container{
height: 100%;
background-color: red;
}
blue.css
.my-container{
height: 100%;
background-color: red;
}
Here is the Main Page
<mat-toolbar color="primary">
<span class="mainheading">Theme Changing</span>
</mat-toolbar>
<div class="my-container">
<h1 class="sideheading">URL that entered are processed for Theme Changing of the Page</h1>
</div>
Now I have to use the param value like color and change the background to the color mentioned like if the color mentioned is red the background should change in to red.
Note:Their should be different CSS files
You can't control header tags by angular directives.
You can create style tags and import different files in them. then control them by *ngIf directive.
<style type="text/css" *ngIf="rule1">
#import 'path\to\file-1';
</style>
<style type="text/css" *ngIf="rule2">
#import 'path\to\file-2';
</style>
Guys I have found a solution for this question
import { ActivatedRoute } from '#angular/router';
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit()
{
this.activatedRoute.paramMap.subscribe(params=>
{
let color=params.get('color');
console.log(color);
if(color)
{
if(color=="red")
{
loadCss("assets/styles/red.css");
console.log("This should be able to change to red color background");
}
else if(color=='blue')
{
loadCss("assets/styles/blue.css");
console.log("This should be able to change to Blue color background");
}
else if(color=='green')
{
loadCss("assets/styles/green.css");
console.log("This should be able to change to Green color background");
}
}
function loadCss(filename:any)
{
var fileref=document.createElement("link");
fileref.setAttribute("rel","stylesheet");
fileref.setAttribute("type","text/css");
fileref.setAttribute("href",filename);
if(typeof fileref!="undefined")
{
document.getElementsByTagName("head")[0].appendChild(fileref)
}
}
})
}
}
Main CSS Files
.mainheading
{
width: 100%;
text-align: center;
}
.sideheading{
padding-top: 20px;
color: white;
font-style:italic;
text-align:center ;
}
red.css
.my-container{
height: 100%;
background-color: red;
}
blue.css
.my-container{
height: 100%;
background-color: blue;
}
green.css
.my-container{
height: 100%;
background-color: green;
}
<mat-toolbar color="primary">
<span class="mainheading">Theme Changing</span>
</mat-toolbar>
<div id="theme" class="my-container" >
<h1 class="sideheading">
URL that entered are processed for Theme Changing of the Page
</h1>
</div>
Note:
Put the css files in assets/styles folder.
For getting the value from the url you should add the script in the app routing module
const routes: Routes = [
{
path:'redirecting/:color',component:RedirectingComponent
}];

Calculate CSS transform displacement while scaling around origin point using react-use-gesture [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm creating a zoomable and "pannable" canvas by using useWheel from react-use-gesture.
The progress is good so far, until I tried to zoom around origin point (which is the mouse position).
I'm having trouble calculating the position displacement to accommodate the changes caused by scaling around a different origin point.
Here's a code sandbox (check App.js around line 60):
https://codesandbox.io/s/usewheel-zoom-pan-stackoverflow-27o0l
Thanks
Solved!
Borrowed the solution from here and applied it to my react app
How to zoom on a point with JavaScript?
The takeaway is that I don't rely on transform-origin anymore, because changing it is what caused the jump. The solution now calculates the new origin point and scales towards it.
For Reference (this code doesn't work in code snippets here because of modules, try it in code sandbox)
import React from "react";
import ReactDOM from "react-dom";
import { useWheel } from "react-use-gesture";
import clamp from "lodash/clamp";
import "./styles.css";
const STEP = 0.995;
const MAX_SCALE = 5;
const MIN_SCALE = 0.25;
export default function App() {
const [isChecked, setIsChecked] = React.useState(true);
const canvasRef = React.useRef();
const [canvasTransform, setCanvasTransform] = React.useState({
x: 0,
y: 0,
originCenterX: window.innerWidth / 2,
originCenterY: window.innerHeight / 2,
wheeling: false,
scale: 1
});
// Set the drag hook and define component movement based on gesture data
const bind = useWheel(
({ wheeling, metaKey, delta: [deltaX, deltaY], event }) => {
if (metaKey && event) {
const factor = deltaY;
const { clientX, clientY } = event;
const scaleChanged = Math.pow(STEP, factor);
const newScale = clamp(
scaleChanged * canvasTransform.scale,
MIN_SCALE,
MAX_SCALE
);
const rect = canvasRef.current.getBoundingClientRect();
const currentCenterX = rect.x + rect.width / 2;
const currentCenterY = rect.y + rect.height / 2;
const mousePosToCurrentCenterDistanceX = clientX - currentCenterX;
const mousePosToCurrentCenterDistanceY = clientY - currentCenterY;
const newCenterX =
currentCenterX +
mousePosToCurrentCenterDistanceX * (1 - scaleChanged);
const newCenterY =
currentCenterY +
mousePosToCurrentCenterDistanceY * (1 - scaleChanged);
// All we are doing above is: getting the target center, then calculate the offset from origin center.
const offsetX = newCenterX - canvasTransform.originCenterX;
const offsetY = newCenterY - canvasTransform.originCenterY;
if (newScale !== canvasTransform.scale) {
setCanvasTransform({
...canvasTransform,
scale: newScale,
x: offsetX,
y: offsetY,
scaleChanged,
currentCenterX,
currentCenterY,
wheeling
});
}
} else {
setCanvasTransform({
...canvasTransform,
x: canvasTransform.x - deltaX,
y: canvasTransform.y - deltaY,
wheeling
});
}
}
);
return (
<div className="outer" {...bind()}>
<div
className="inner"
style={{
transform: `translateX(${canvasTransform.x}px) translateY(${
canvasTransform.y
}px) scale3d(${canvasTransform.scale}, ${canvasTransform.scale}, 1)`
}}
ref={canvasRef}
id="canvas"
>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
<span>
<input
type="checkbox"
checked={isChecked}
onChange={() => setIsChecked(!isChecked)}
/>{" "}
Around Mouse
</span>
<pre>{JSON.stringify(canvasTransform, null, 2)}</pre>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
body {
margin: 0;
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
overscroll-behavior-x: none;
overscroll-behavior-y: none;
max-height: 100vh;
overflow: hidden;
background-color: #f0f4f7 !important;
}
div > div {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
div > div > div {
font-family: sans-serif;
text-align: center;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: white;
background-image: linear-gradient(#eee 0.1em, transparent 0.1em),
linear-gradient(90deg, #eee 0.1em, transparent 0.1em);
background-size: 3em 3em;
}
span {
position: fixed;
top: 10px;
left: 10px;
z-index: 1;
display: flex;
color: #fff;
background-color: #333;
padding: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
justify-content: space-between;
align-items: center;
}
span input {
font-size: 16px;
}
pre {
position: fixed;
bottom: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Relate CSS variables to each other in context

Background: trying to create an element for easily embedding Font Awesome 5.10.2 Duotone icons into any piece of HTML.
This icon element uses HTML attributes which should map to a specific icon where the mapping is purely controlled by the CSS author.
<x pay></x> <!-- <- icon value for pay should be customizable by CSS author -->
Below is my solution but I wonder ...
Can one reduce
x {
position: relative;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-style: normal;
font-variant: normal;
text-rendering: auto;
white-space: nowrap;
font-family: var(--fa-5-d);
font-weight: var(--fa-d);
background: var(--x-background);
line-height: 1em !important;
}
x::after { position: absolute; left: 0; bottom: 0; }
x::before { color: var(--fa-primary-color, inherit); opacity: 1; opacity: var(--fa-primary-opacity, 1.0); }
x::after { color: var(--fa-secondary-color, inherit); opacity: var(--fa-secondary-opacity, 0.4); }
x:before { --fa-credit-card: "\f09d"; }
x:after { --fa-credit-card: "\10f09d"; }
<x pay></x>
this ↓
x[pay]:before,
x[pay]:after { content: var(--fa-credit-card); }
to this ↓ (avoiding x[pay]:before, x[pay]:after repetition)
x[pay] { --content: var(--fa-credit-card); }
in essence
set a CSS variable once on a parent to a value v
that diverges into different child values v₁ and v₂ related to v?
?
A convenience improvement using web components / custom elements:
<link href='//cdn.blue/{fa-5.10.2}/css/all.css' rel=stylesheet>
<link href='//cdn.blue/{fa+}/var.css' rel=stylesheet>
<link href='//cdn.blue/{fa+}/x-i.css' rel=stylesheet>
<script src='//cdn.blue/<shin>/shin-element.js'></script>
<script>
class XI extends ShinElement {
constructor() {
super(`<style></style>`);
ShinElement.IPA(this, 'jsUpdate', { a: 'js-update', t: ShinElement.Number0 });
}
connectedCallback() { XI.css(this); }
static css(t) {
const c = getComputedStyle(t);
const i = c.getPropertyValue('--i').trim();
const s = t._.QS("style");
s.textContent = `:host:before, :host:after { content: var(${i}); }`;
}
static get observedAttributes() { return [ 'js-update' ]; }
attributeChangedCallback(a, o, n) {
switch (a) {
case "js-update":
const u = this.jsUpdate;
if (u > 0) this._jsu = setInterval(XI.css, u, this);
else { clearInterval(this._jsu); delete this._jsu; }
break;
}
}
}
XI.define();
</script>
<style>x-i[pay] { --i: --fa-user-edit; }</style>
<x-i pay js-update=200 id=x></x-i>
https://cdn.blue/<shin>/docs/ShinElement.html
https://codepen.io/cetinsert/pen/QWLZgwZ?editors=1000
The need for js-update (HTML), jsUpdate (JS) for doing live CSS edits is unfortunate.
x.jsUpdate = 0; // to disable getComputedStyle updates
Thus I still wonder if there is a better solution - be it CSS-only or using web components.

Shiny Server custom Handlebars.js templates

I'm not at all familiar with handlebars.js but I'd like to customize the directory index template that comes with Shiny Server. Specifically, what I'm looking to do is render a page of thumbnails of the different apps.
The file /opt/shiny-server/templates/directorIndex.html comes with the code below which reference a number of expressions including {{title}}, references to apps, dirs and files.
<!DOCTYPE html>
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{title}}</title>
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro' rel='stylesheet' type='text/css'>
<style type="text/css">
body {
font-family: Helvetica, Arial, sans-serif;
background-color: #F5F5F5;
}
pre, tt, code, .code, #detail {
font-family: 'Consolas', 'Courier New', 'Courier', monospace;
}
h1 {
font-size: 40px;
}
a {
text-decoration: none;
}
</style>
</head>
<body>
<h1>{{title}}</h1>
<ul>
{{#each apps}}
<li><a class="code" href="{{this.url}}">{{this.name}}</a> (application)</li>
{{/each}}
{{#each dirs}}
<li><a class="code" href="{{this.url}}/">{{this.name}}</a></li>
{{/each}}
{{#each files}}
<li><a class="code" href="{{this.url}}">{{this.name}}</a></li>
{{/each}}
</ul>
</body>
</html>
So I have two questions.
First - how can I know what expressions are available to call?
Second - give that I just have this one html page (as far as I can tell) how do I register a helper, e.g.
Handlebars.registerHelper('splitURL', function(url) {
var t = url.split("/");
return t[1];
});
I had the same desire to customize the directoryIndex.html template and enjoyed the same lack of documentation about what handlebars expressions could be used. I'm not a web developer so the code here is probably rubbish, but it works well enough. It sounds like you already solved your issue, but others may find some use in this approach. Images for each app are saved in site_dir/images.
screenshot of end result
directoryIndex.html:
<!DOCTYPE html>
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{title}}</title>
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro' rel='stylesheet' type='text/css'>
<link href="main.css" rel="stylesheet">
<script type='text/javascript'>
function include(arr,obj) {
return(arr.indexOf(obj) != -1);
}
function updateView(data) {
//update title and heading
if ("title" in data) {
var host = document.location.hostname;
if (host in data.title) {
document.title = data.title[host];
document.getElementById("title").innerHTML = data.title[host];
} else if ("default" in data.title) {
document.title = data.title.default;
document.getElementById("title").innerHTML = data.title.default;
}
}
//hide cards (for directories like /images)
if ("ignore" in data) {
var element;
for (var i in data.ignore) {
if (element = document.getElementById("card_"+data.ignore[i])) {
element.parentNode.removeChild(element);
}
}
}
//update each shiny app if it has JSON data
if ("apps" in data) {
for (var item in data.apps) {
if (document.getElementById("card_"+item)) {
if ("img" in data.apps[item])
document.getElementById("img_"+item).src = "/images/" + data.apps[item].img;
if ("name" in data.apps[item])
document.getElementById("name_"+item).innerHTML = data.apps[item].name;
if ("desc" in data.apps[item])
document.getElementById("desc_"+item).innerHTML = data.apps[item].desc;
}
}
}
}
function loadJSON(url) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var data = JSON.parse(this.responseText);
updateView(data)
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
document.addEventListener("DOMContentLoaded", function() {
loadJSON("data.json");
});
</script>
</head>
<body>
<div id="title_bar">
<h1 id="title"></h1>
</div>
<div id="apps">
{{#each dirs}}
<div id="card_{{name}}" class="card" onclick="location.href='{{url}}';" style="cursor: pointer;">
<img id="img_{{name}}" src="" alt="{{name}}" onerror="if (this.src != '/images/missing.png') this.src = '/images/missing.png';">
<div class="container">
<h4 id="name_{{name}}">{{name}}</h4>
<p id="desc_{{name}}"></p>
</div>
</div>
{{/each}}
</div>
</body>
</html>
data.json (located in the site_dir root location):
{
"title": {
"default": "Shiny Server",
"dev_host": "Shiny Server (Development)",
"accp_host": "Shiny Server (Acceptance)",
"prod_host": "Shiny Server",
"dev_host.fully.qualified.name": "Shiny Server (Development)",
"accp_host.fully.qualified.name": "Shiny Server (Acceptance)",
"prod_host.fully.qualified.name": "Shiny Server"
},
"ignore": [ "app_4", "app_5", "images" ],
"apps": {
"app_1": {
"name": "app 1 name goes here",
"desc": "app 1 description goes here",
"img": "app1.png"
},
"app_2": {
"name": "app 2 name",
"desc": "app 2 desc",
"img": "app2.png"
},
"app_3": {
"name": "app 3 name",
"desc": "",
"img": "app3.png"
}
}
}
main.css (located in the site_dir root location):
body, html {
font-family: Helvetica, Arial, sans-serif;
background-color: #F5F5F5;
color: #114;
margin: 0;
padding: 0;
}
#title_bar {
height: 80px;
background-color: #3475b4;
overflow: hidden;
border-bottom: 1px solid #3475b3;
-moz-box-shadow: 0px 0px 10px 3px #BBC;
-webkit-box-shadow: 0px 0px 10px 3px #BBC;
box-shadow: 0px 0px 10px 3px #BBC;
}
#title_bar h1 {
margin: 14px auto .5em auto;
padding: .2em;
color: #EEE;
text-align: center;
}
#apps {
margin-top: 14px;
}
.card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
border-radius: 5px;
width: 300px;
margin: 10px;
display: inline-block;
vertical-align: top;
}
.card:hover {
box-shadow: 0 12px 24px 0 rgba(0,0,0,0.2);
}
.card img {
display: block;
margin: 0 auto;
max-width: 300px;
max-height: 250px;
}
.container {
padding: 2px 16px;
}

Resources