This is a one page responsive site for a financial firm in New York, NY built on Bootstrap with additional jQuery enhancements. The site was launched in October 2017.
For this project, I worked closely with a copywriter & project manager who was the bridge between myself and the end client. The design was very client-driven, but kept simple and patterned after a few websites they liked. It was determined that they wanted a one page, site with 100vh background images, links that scrolled to anchors and highlighted when active, and a “parallax” effect on the large images.
The client also wanted a loading/splash screen with their logo that faded in, then faded out into the site. This was accomplished with a combination of CSS keyframes and jQuery.
This is the HTML for the “splash page:”
<div id="overlay" class="overlay">
<div id="animate" class="overlayimgcontainer">
<img id="splashimg" src="images/gclogo.jpg" class="fade-in">
</div>
</div>
.overlay
creates a white background that covers the entire page initially, hiding the content, and .overlayimgcontainer
is the div containing the logo that is faded in.
This bit of the CSS creates the white overlay div, logo image container, and handles the animation of the logo fading in:
.overlay {
position: fixed;
left: 0;
background-color: #fff;
height: 100%;
width: 100%;
}
.overlayimgcontainer {
max-width: 650px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.overlay img {
width: 100%;
min-width: 250px;
}
.fade-in {
animation-name: fade-in;
animation-duration: 2.5s;
animation-iteration-count: 1;
}
@keyframes fade-in {
from {transform: translateX(0); opacity:0; width: 100%;}
to {transform: translateX(0); opacity: 100; width: 100%;}
}
This jQuery function handles the fading out of the overlay and hiding of the logo after 2500ms and 2700ms respectively:
$(document).ready(function() {
setTimeout(function(){
$("#overlay").fadeOut('500');
}, 2500);
setTimeout(function(){
$('#animate').hide();
}, 2700);
});
The client wanted the team bios to be hidden until clicked on, and also wanted the user to be able to click anywhere on the site to hide the bio. This was a rather interesting request, but was acommplished with a few lines of jQuery:
$(document.body).click(function() {
$('#p, #vp, #p2, #vp2').slideUp();
setTimeout(function() {
$('#divider2, #divider1, #divider3, #divider4').removeClass('style14');
}, 400);
});
However, if the user left a bio open, scrolled down to the contact form, and clicked a field or other link, the bio would be hidden, causing the page to scroll away from where the user was clicking. This was solved by stopping the propogation of the click event in certain areas:
$("#ira, #adam, #clint, #harvey, #email, #phone, #name, #message, #mailto, #submit-contact-form, #linkedin").click(function(e) {
e.stopPropagation();
});
To maintain fucntionality of this "click anywhere to close" feature on mobile, I used a (pretty huge, but comprehensive!) regex to check if the user was on a phone, and if they were, add the class .clickable
to the body, which simply turns the cursor into a pointer everywhere on the body, hence creating a "click" event on a touch-screen device.
This is my mobile device detection script:
(function(a) {
(jQuery.browser = jQuery.browser || {}).mobile =
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge
|maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|
treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i
.test(a) ||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)
|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|
c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)
|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|
haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|
ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg(
g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|
bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)
|nok(6|i)|nzph|o2im|op(ti|wv)
|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12
|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0
|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)
|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|
veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|
wonu|x700|yas\-|your|zeto|zte\-/i
.test(a.substr(0, 4))
})(navigator.userAgent || navigator.vendor || window.opera);
if (jQuery.browser.mobile === true) {
$('body').addClass('clickable');
}
});
Finally, they needed users to be able to enter a phone number in almost any format possible, including extentions, whether it was spelled "extention," "ext.," or "x-."
This resulted in a longer-than-usual telephone number validation regex, but allows the user to enter their phone number without issue, even if it's an odd format:
var checkPhone =
/^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i;
var phone = $('#phone').val();
(Disclaimer: My management of this website discontinued in late 2018. Many of the current not-so-elegant bits were modifications made by unknown persons.)