Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                    <div class="container mt-5">
      <h1>Meet Our Leadership Team</h1>
        <div class="leadershipContainer">
            <div class="leadershipCard" data-headshot='https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/97d96c17-588a-475e-8ed5-e88c96c84aa0/photo1.jpg' data-name='David Flux' data-titles='DevOps Engineer' data-bio='David has been working in the DevOps space for 14 years. He has run systems serving over 5,000,000 requests every half second.' data-linkedin='' data-twitter=''>
                <div class="leadershipCard__headshot">
                    <img src="https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/97d96c17-588a-475e-8ed5-e88c96c84aa0/photo1.jpg" alt="Photo1" srcset="">
                </div>
                <div class="leadershipCard__titles">
                    <h3>David Flux</h3>
                    <p class="text-muted">DevOps Engineer</p>
                    <p class="mobileBio">David has been working in the DevOps space for 14 years. He has run systems serving over 5,000,000 requests every half second.</p>
                </div>
            </div>
            <div class="leadershipCard" data-headshot='https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/4b9ade7e-ec05-4d55-b781-38f48893b282/photo2.jpg' data-name='Cameron Johnson' data-titles='Automation Expert' data-bio='Cameron has been working in the Automation space for 14 years. She has run systems serving over 5,000,000 requests every half second.' data-linkedin='' data-twitter=''>
                <div class="leadershipCard__headshot">
                    <img src="https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/4b9ade7e-ec05-4d55-b781-38f48893b282/photo2.jpg" alt="Photo1" srcset="">
                </div>
                <div class="leadershipCard__titles">
                    <h3>Cameron Johnson</h3>
                    <p class="text-muted">Automation Expert</p>
                    <p class="mobileBio">David has been working in the DevOps space for 14 years. He has run systems serving over 5,000,000 requests every half second.</p>
                </div>
            </div>
            <div class="leadershipCard" data-headshot='https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/eac01b91-9cb9-4ac0-8339-121b4de3c192/photo3.jpg' data-name='Randy Johnson' data-titles='Shirt Wearer' data-bio='Randy has been working in the Shirt Wearing space for 14 years. He has run shirt wearing systems serving over 5,000,000 requests every half second.' data-linkedin='' data-twitter=''>
                <div class="leadershipCard__headshot">
                    <img src="https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/eac01b91-9cb9-4ac0-8339-121b4de3c192/photo3.jpg" alt="Photo2" srcset="">
                </div>
                <div class="leadershipCard__titles">
                    <h3>Randy Johnson</h3>
                    <p class="text-muted">Shirt Wearer</p>
                    <p class="mobileBio">David has been working in the DevOps space for 14 years. He has run systems serving over 5,000,000 requests every half second.</p>
                </div>
            </div>
            <div class="leadershipCard" data-headshot='https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/8e0f1cf0-37e5-4025-8383-425a58113207/photo4.jpg' data-name='Lonnie Smith' data-titles='Social Media Expert' data-bio='Lonnie has been working in the Twitter space for 14 years. He has run tweets serving over 5,000,000 requests every half second.' data-linkedin='' data-twitter=''>
                <div class="leadershipCard__headshot">
                    <img src="https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/8e0f1cf0-37e5-4025-8383-425a58113207/photo4.jpg" alt="Photo3" srcset="">
                </div>
                <div class="leadershipCard__titles">
                    <h3>Lonnie Smith</h3>
                    <p class="text-muted">Social Media Expert</p>
                    <p class="mobileBio">David has been working in the DevOps space for 14 years. He has run systems serving over 5,000,000 requests every half second.</p>
                </div>
            </div>
            <div class="leadershipCard" data-headshot='https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/6a90d8e7-b06b-4f53-a233-41f2aac5b58d/photo5.jpg' data-name='Sarah Larson' data-titles='Quality Coordinator' data-bio='Sarah has been working in the Quality space for 14 years. She has run QA Systems serving over 5,000,000 requests every half second.' data-linkedin='' data-twitter=''>
                <div class="leadershipCard__headshot">
                    <img src="https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/6a90d8e7-b06b-4f53-a233-41f2aac5b58d/photo5.jpg" alt="Photo4" srcset="">
                </div>
                <div class="leadershipCard__titles">
                    <h3>Sarah Larson</h3>
                    <p class="text-muted">Quality Coordinator</p>
                    <p class="mobileBio">David has been working in the DevOps space for 14 years. He has run systems serving over 5,000,000 requests every half second.</p>
                </div>
            </div>
            <div class="leadershipCard" data-headshot='https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/882b2346-e4b6-4520-a879-62de40808e2b/photo6.jpg' data-name='Jessica Person' data-titles='Customer Service Director' data-bio='Jessica has been working in the customer service space for 14 years. She has run systems serving over 5,000,000 requests every half second.' data-linkedin='' data-twitter=''>
                <div class="leadershipCard__headshot">
                    <img src="https://assets-us-01.kc-usercontent.com/469992e5-7cbd-0032-ead4-f2db9237053a/882b2346-e4b6-4520-a879-62de40808e2b/photo6.jpg" alt="Photo5" srcset="">
                </div>
                <div class="leadershipCard__titles">
                    <h3>Jessica Person</h3>
                    <p class="text-muted">Customer Service Director</p>
                    <p class="mobileBio">David has been working in the DevOps space for 14 years. He has run systems serving over 5,000,000 requests every half second.</p>
                </div>
            </div>
        </div>
    </div>
    <div class="leadershipExpandedContainer">
        <div class="leadershipExpandedContainer__headshot">
            <img src="" alt="">
        </div>
        <div class="leadershipExpandedContainer__bio p-5">
            <h3 class="name"></h3>
            <p class="title text-muted"></p>
            <p class="bio"></p>
            <div class="social">
                <i class="fab fa-linkedin-in"></i>
                <i class="fab fa-twitter"></i>
                <i class="fad fa-file-code"></i>
            </div>
        </div>
    </div>
              
            
!

CSS

              
                body{
    background: #f9f9f9;
}
h1{
  font-family: 'Open Sans', sans-serif;
  font-weight: 800;
  margin-bottom:3rem;
}

.leadershipContainer{
    display: grid;
    grid-template-columns: 1fr;
    grid-gap:3rem;
    @media (min-width:800px) {
        
        grid-template-columns: repeat(3, 1fr);
        grid-template-rows: 1fr 1fr;
        grid-gap:20px 80px;
    }
}

.leadershipCard{
    background:#ffffff;
    box-shadow: 0px 10px 15px -3px rgba(0,0,0,0.1);
    border-radius:.45rem;
    cursor: pointer;
    visibility: hidden;
    &__headshot{
        img{
            width: 100%;
            height: auto;
        }
    }

    &__titles{
        margin-left:.5rem;
        font-family: 'Open Sans', sans-serif;
        h3{
            font-weight: 800;
            margin-bottom: 0;
            margin-top:.5rem;
        }

        @media(min-width:800px){
            .mobileBio{
                display: none;
            }
        }
    }
}

.leadershipExpandedContainer{
    font-family: 'Open Sans', sans-serif;
    //background:white;
    visibility: hidden;
    position:fixed;
    left:50%;
    top:50%;
    transform: translate(-50%, -50%);
    width: 900px;
    display: flex;

    &__headshot{
        img{
            max-width: 375px;
            height:auto;
        }
    }

    &__bio{
        background:white;
        .name{
            font-weight:800;

        }
        .title{
            font-weight: 600;
            font-size: 1.25rem;
        }

        .social{
            font-size:1.75rem;
            display: flex;
            justify-content: flex-start;
            i:nth-child(2){
                margin-left:1.25rem;
            }
            i:nth-child(3){
                margin-left:1.25rem;
            }
        }
    }
}
              
            
!

JS

              
                window.addEventListener('load', () => {
  //this is just an example plugin that allows us to animate a "blur" property like gsap.to(target, {blur:10}) and it'll feed that value to this plugin which will do all the necessary calculations to add/update a blur() value in the CSS "filter" property (in browsers that support it). We wrap it in an iife just so that we can declare some local variables in a private scope at the top.
(function() {
    const blurProperty = gsap.utils.checkPrefix("filter"),
          blurExp = /blur\((.+)?px\)/,
          getBlurMatch = target => (gsap.getProperty(target, blurProperty) || "").match(blurExp) || [];
  
    gsap.registerPlugin({
      name: "blur",
      get(target) {
        return +(getBlurMatch(target)[1]) || 0;
      },
      init(target, endValue) {
        let data = this,
            filter = gsap.getProperty(target, blurProperty),
            endBlur = "blur(" + endValue + "px)",
            match = getBlurMatch(target)[0],
            index;
        if (filter === "none") {
          filter = "";
        }
        if (match) {
          index = filter.indexOf(match);
          endValue = filter.substr(0, index) + endBlur + filter.substr(index + match.length);
        } else {
          endValue = filter + endBlur;
          filter += filter ? " blur(0px)" : "blur(0px)";
        }
        data.target = target; 
        data.interp = gsap.utils.interpolate(filter, endValue); 
      },
      render(progress, data) {
        data.target.style[blurProperty] = data.interp(progress);
      }
    });
  })();
  
  
    const headshots = gsap.utils.toArray('.leadershipCard'),
          expandedContainer = document.querySelector('.leadershipExpandedContainer'),
          expandedBioContainer = document.querySelector('.leadershipExpandedContainer__bio'),
          expandedImage = document.querySelector('.leadershipExpandedContainer__headshot img'),
          expandedName = document.querySelector('.leadershipExpandedContainer__bio .name'),
          expandedTitle = document.querySelector('.leadershipExpandedContainer__bio .title'),
          expandedBio = document.querySelector('.leadershipExpandedContainer__bio .bio'),
          expandedSocial = document.querySelector('.leadershipExpandedContainer__bio .social')

    let activeHeadshot;

    gsap.set(expandedBioContainer, {xPercent:15, opacity:0});

    function expandHeadshot(card){
        console.log(card.querySelector('img'))
        //If someone clicks on element behind expanded headshot, then we should 
        //just close the currently expanded headshot
        if(activeHeadshot){
            return closeHeadshot()
        }

        //If we're on a small screen, just return. The bios are expanded via css
        if(window.innerWidth < 800){
            return;
        }

        //When the image in the detail DOM is loaded, we run the GSAP flip stuff.
        //Anything outside this function isn't related to FLIPing the headshot
        const onload = () => {
            
            //Position the expanded container on top of the headshot.
            //Make sure to use fitChild on the image so that's what looks like
            //it's growing. 
            Flip.fit(expandedContainer, card.querySelector('img'), {scale: true, fitChild: expandedImage})

            //Record the state that everything is in.
            const state = Flip.getState(expandedContainer);

            //Set the final state
            gsap.set(expandedContainer, {clearProps: true});
            gsap.set(expandedContainer, {visibility: 'visible'});

            Flip.from(state, {
                duration: 0.45,
                scale: true,
                ease: "power2.in",
                absolute: true
            }).to(expandedBioContainer, {xPercent: 0, opacity:1, duration:.25})

            expandedImage.removeEventListener('load', onload);
            document.addEventListener('click', closeHeadshot);

        }


        //Change image and text
        const data = card.dataset;
        expandedImage.addEventListener('load', onload);
        expandedImage.src = data.headshot;
        expandedName.innerText = data.name;
        expandedTitle.innerText = data.titles;
        expandedBio.innerText = data.bio;

        //Fade out the other items
        gsap.to(headshots, {opacity:0.3, stagger: { amount: 0.7, from: headshots.indexOf(card), grid: 'auto' }})
        gsap.to(headshots, {blur: 6})
        activeHeadshot = card;

    }

    function closeHeadshot(){
        document.removeEventListener('click', closeHeadshot);

        //Record current state
        const state = Flip.getState(expandedContainer);

        //Scale details down so that it's image fits exactly on top of the active headshot
        Flip.fit(expandedContainer, activeHeadshot.querySelector('img'), {scale: true, fitChild: expandedImage});

        //Put the bio container back and then fade in the other headshots
        
        const tl = gsap.timeline();
        tl.to(expandedBioContainer, {xPercent: 5, opacity: 0, duration:.25})
          .to(headshots, {blur:0})
          .to(headshots, {opacity:1, stagger: {amount: 0.3, from: headshots.indexOf(activeHeadshot), grid: 'auto'}}, 0);
          

        Flip.from(state, {
            scale: true,
            duration: .5,
            delay: 0.2,
            ease: "power2.inOut",
            absolute: true
        }).to(expandedContainer, {visibility: 'hidden'})

        activeHeadshot = null;
    }

    function generateHoverTimeline(target){
        const tl = gsap.timeline({paused:true});
        tl.to(target, {yPercent:-2, duration:.25, ease: "power2.inOut"});
        return tl;
    }

    //Add click events
    gsap.utils.toArray('.leadershipCard').forEach(item => {
        item.addEventListener('click', () => {
            expandHeadshot(item);
        });
        const cardTimeline = generateHoverTimeline(item);
        item.addEventListener('mouseenter', () => {
            if(activeHeadshot){
                return;
            }
            else{
                cardTimeline.play()
            }
        })
        item.addEventListener('mouseleave', () => {
            if(activeHeadshot){
                return;
            }
            else{
                cardTimeline.reverse();
            }
        })
    });

    gsap.set('.leadershipCard', {autoAlpha: 1});
    gsap.from('.leadershipCard', {opacity:0, yPercent:30, stagger: 0.14})
});
              
            
!
999px

Console