Instantly share code, notes, and snippets.
Last active
October 22, 2021 13:40
-
Star
(10)
10
You must be signed in to star a gist -
Fork
(1)
1
You must be signed in to fork a gist
-
Save ScottSmith95/4417738 to your computer and use it in GitHub Desktop.
A responsive web version of iOS Share Sheets. More info: https://ScottHSmith.com/projects/share-sheets/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<style> | |
body { | |
margin: 0; | |
font: normal 300 1em sans-serif; | |
} | |
h1 { | |
text-align: center; | |
} | |
ul { | |
padding: 0; | |
} | |
.AllLinks { | |
margin: 1.5% auto 5% auto; | |
text-align: center; | |
height: 1em; | |
} | |
.Link { | |
display: inline; | |
text-align: center; | |
line-height: 3.5em; | |
margin: 0px 0.4%; | |
cursor: pointer; | |
} | |
/* Share Sheets */ | |
.darklayer { | |
display: none; | |
position: fixed; | |
z-index: 9; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
background-color: rgba(0,0,0,0.65); | |
} | |
.darklayer.loaded { | |
display: block; | |
} | |
.darklayer.on { | |
animation: fade-in 0.25s ease-out forwards; | |
} | |
.darklayer.off { | |
animation: fade-out 0.25s ease-out forwards; | |
} | |
/* If you use Modernizr.js, the commented code will set nice fallbacks, | |
instead of the darklayer stuff above. | |
.js .darklayer { | |
display: none; | |
position: fixed; | |
z-index: 9; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
background-color: rgba(0,0,0,0.5); | |
} | |
.js .darklayer.loaded { | |
display: block; | |
} | |
.js .darklayer.on { | |
animation: fade-in 0.25s ease-out forwards; | |
} | |
.js.no-cssanimations .darklayer.on { | |
display: block; | |
} | |
.js .darklayer.off { | |
animation: fade-out 0.25s ease-out forwards; | |
} | |
.js.no-cssanimations .darklayer.off { | |
display: none; | |
}*/ | |
.Sheet { | |
transition: transform 0.25s ease-out; | |
visibility: hidden; | |
position: fixed; | |
z-index: 10; | |
bottom: 0; | |
width: 100%; | |
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; | |
font-weight: 400; | |
user-select: none; | |
margin: 0 auto; | |
} | |
.Sheet.loaded { | |
visibility: visible; | |
} | |
.Sheet.unselected { | |
transform: translateY(100%); | |
} | |
.Sheet.selected { | |
transform: translateY(0%); | |
} | |
.SheetContent { | |
max-width: 375px; | |
margin: 0 auto; | |
} | |
.itemset { | |
text-align: left; | |
background: rgba(248,248,248,0.95); | |
backdrop-filter: blur(5px); | |
padding: 1.5em 0 1em; | |
border-radius: 15px; | |
margin: 0.6rem auto 0.5rem; | |
} | |
.itemset section { | |
overflow-x: scroll; | |
-webkit-overflow-scrolling: touch; | |
padding: 20px 1.5%; | |
white-space: nowrap; | |
border-width: 1px; | |
border-style: solid; | |
border-image: linear-gradient(to right, #C2C2C6 0%, #D6D6DA 5%, #D6D6DA 95%, #C2C2C6 100%) 100% 0 0 0; | |
} | |
.itemset section:first-of-type { | |
padding-top: 0; | |
border: none; | |
} | |
.itemset section:last-of-type { | |
padding-bottom: 0; | |
} | |
.itemset section:only-child { | |
padding-top: 0; | |
padding-bottom: 0; | |
border: none; | |
} | |
.itemset .itemcontainer { | |
display: inline; | |
margin: 0; | |
text-align: center; | |
} | |
.itemset li { | |
display: inline-block; | |
width: 22.5%; | |
height: 100%; | |
margin: 0 auto; | |
color: #000000; | |
font-size: 12px; | |
line-height: 1.3em; | |
text-align: center; | |
vertical-align: top; | |
white-space: normal; | |
} | |
.itemset li img { | |
border-radius: 10px; | |
} | |
.itemset li a { | |
color: inherit; | |
text-decoration: none; | |
} | |
.appicon { | |
width: auto; | |
height: 60px; | |
} | |
.cancel { | |
display: block; | |
width: 100%; | |
color: #0076FF; | |
background: rgba(248,248,248,1); | |
font-size: 20px; | |
font-weight: 600; | |
text-align: center; | |
text-decoration: none; | |
cursor: pointer; | |
-webkit-tap-highlight-color: transparent; | |
padding: 0.8em 0; | |
border: none; | |
border-radius: 15px; | |
margin: 0.5rem auto 0.6rem; | |
} | |
.cancel.touched, | |
.cancel:active { | |
background: rgba(232, 232, 235, 0.95); | |
} | |
/* Landscape */ | |
@media (orientation: landscape) { | |
.itemset .itemcontainer { | |
margin: 0 7px; | |
} | |
.itemset .itemcontainer:first-child { | |
margin-left: 0; | |
} | |
.itemset .itemcontainer:last-child { | |
margin-right: 0; | |
} | |
} | |
/* Tablet */ | |
@media (min-width: 45em) { | |
.SheetContent { | |
max-width: 450px; | |
} | |
.itemset section { | |
padding-right: 2.5%; | |
padding-left: 2.5%; | |
} | |
.itemset .itemcontainer { | |
width: 24.5%; | |
} | |
.itemset .itemcontainer { | |
margin: 0 0.25em; | |
} | |
.itemset .itemcontainer:first-child { | |
margin-left: 0; | |
} | |
.itemset .itemcontainer:last-child { | |
margin-right: 0; | |
} | |
.itemset li { | |
width: 20%; | |
} | |
.appicon { | |
height: 75px; | |
} | |
} | |
/* Animations */ | |
@keyframes fade-in { | |
0% { | |
visibility: visible; | |
opacity: 0; | |
} | |
100% { | |
opacity: 1; | |
} | |
} | |
@keyframes fade-out { | |
0% { | |
opacity: 1; | |
} | |
100% { | |
visibility: hidden; | |
opacity: 0; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Select one of the links below to bring up a sheet.</h1> | |
<ul class="AllLinks"> | |
<li class="Link"> | |
<a class="Twitter">Twitter</a> | |
</li> | |
<li class="Link"> | |
<a class="Facebook">Facebook</a> | |
</li> | |
</ul> | |
<!-- Share Sheets --> | |
<!-- Twitter Share Sheet --> | |
<div class="Sheet unselected" id="Twitter"> | |
<div class="SheetContent"> | |
<ul class="itemset"> | |
<section class="clients"> | |
<div class="itemcontainer"> | |
<li><a href="twitter://user?screen_name=ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Twitter.png" alt=""> | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a href="twitterrific:///profile?screen_name=ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Twitterrific.png" alt=""> | |
Twitterrific | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a href="tweetbot:///user_profile/ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Tweetbot.png" alt=""> | |
Tweetbot | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Placeholder-Icon.png" alt=""> | |
Placeholder | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Placeholder-Icon.png" alt=""> | |
Placeholder | |
</a></li> | |
</div> | |
</section> | |
<section class="browsers"> | |
<div class="itemcontainer"> | |
<li><a href="https://twitter.com/ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Safari.png" alt=""> | |
Right here | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a href="googlechrome://twitter.com/ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Chrome.png" alt=""> | |
Chrome | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a href="ophttp://twitter.com/ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/1Password.png" alt=""> | |
1Password | |
</a></li> | |
</div> | |
</section> | |
</ul> | |
<h2 class="cancel">Cancel</h2> | |
</div> | |
</div> | |
<!-- Facebook Share Sheet --> | |
<div class="Sheet unselected" id="Facebook"> | |
<div class="SheetContent"> | |
<ul class="itemset"> | |
<section> | |
<div class="itemcontainer"> | |
<li><a href="fb://profile/1618900176"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Facebook.png" alt=""> | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a href="https://facebook.com/ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Safari.png" alt=""> | |
Right here | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a href="googlechrome://facebook.com/ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/Chrome.png" alt=""> | |
Chrome | |
</a></li> | |
</div> | |
<div class="itemcontainer"> | |
<li><a href="ophttp://facebook.com/ScottSmith95"> | |
<img class="appicon" src="https://files.scottshar.es/Share%20Sheets/app-icons/1Password.png" alt=""> | |
1Password | |
</a></li> | |
</div> | |
</section> | |
</ul> | |
<h2 class="cancel">Cancel</h2> | |
</div> | |
</div> | |
<script> | |
var sheets = document.querySelectorAll('.Sheet'); | |
var triggers = [document.querySelector('.Twitter'), document.querySelector('.Facebook')]; | |
// Shows sheets after they have loaded. | |
setTimeout(function(){ | |
// Iterate through the NodeList. | |
for (var i = 0; i < sheets.length; ++i) { | |
sheets[i].classList.add('loaded'); | |
} | |
}); | |
// Handles opening the sheets. | |
function toggleSheet(sheetID) { | |
sheet = document.querySelector(sheetID); | |
if ( sheet.classList.contains('selected') ) { | |
sheet.classList.remove('selected'); | |
sheet.classList.add('unselected'); | |
sheet.blur(); | |
offDarkLayer(); | |
} | |
else { | |
sheet.classList.add('selected'); | |
sheet.classList.remove('unselected'); | |
sheet.focus(); | |
onDarkLayer(); | |
} | |
} | |
// Handles adding `<div class="darklayer"></div>` to DOM. | |
function addDarklayer() { | |
var element = document.createElement("div"); | |
element.setAttribute('class', 'darklayer off'); | |
document.body.appendChild(element); | |
} | |
function onDarkLayer() { | |
var darkLayer = document.querySelector('.darklayer'); | |
darkLayer.classList.add('loaded'); | |
darkLayer.classList.remove('off'); | |
darkLayer.classList.add('on'); | |
} | |
function offDarkLayer() { | |
darkLayer = document.querySelector('.darklayer'); | |
darkLayer.classList.remove('on'); | |
darkLayer.classList.add('off'); | |
} | |
// Close selected sheet and turn darklayer off. | |
function offSelectedSheet() { | |
selectedSheet = document.querySelector('.Sheet.selected'); | |
selectedSheet.blur(); | |
selectedSheet.classList.remove('selected'); | |
selectedSheet.classList.add('unselected'); | |
offDarkLayer(); | |
} | |
// Add dark layer to DOM. | |
addDarklayer(); | |
// Link triggers to sheets. | |
document.querySelector('.Twitter').addEventListener('click', function() { | |
toggleSheet('#Twitter'); | |
}); | |
document.querySelector('.Facebook').addEventListener('click', function() { | |
toggleSheet('#Facebook'); | |
}); | |
// Handles all cancel button behviours. | |
cancelBtns = document.querySelectorAll('.cancel'); | |
for (var i = 0; i < cancelBtns.length; ++i) { // Iterate through the NodeList. | |
var element = cancelBtns[i]; | |
element.addEventListener('touchstart', function(element) { | |
element.classList.add('touched'); | |
}); | |
element.addEventListener('touchend', function(element) { | |
element.classList.remove('touched'); | |
}); | |
element.addEventListener('click', function() { | |
offSelectedSheet(); | |
}); | |
} | |
// Handles clicking the darklayer to dismiss sheets. | |
document.querySelector('.darklayer').addEventListener('click', function() { | |
offSelectedSheet(); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment