HTML preprocessors can make writing HTML more powerful or convenient. For instance, Markdown is designed to be easier to write and read for text documents and you could write a loop in Pug.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. So you don't have access to higher-up elements like the <html>
tag. If you want to add classes there that can affect the whole document, this is the place to do it.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. If you need things in the <head>
of the document, put that code here.
The resource you are linking to is using the 'http' protocol, which may not work when the browser is using https.
CSS preprocessors help make authoring CSS easier. All of them offer things like variables and mixins to provide convenient abstractions.
It's a common practice to apply CSS to a page that styles elements such that they are consistent across all browsers. We offer two of the most popular choices: normalize.css and a reset. Or, choose Neither and nothing will be applied.
To get the best cross-browser support, it is a common practice to apply vendor prefixes to CSS properties and values that require them to work. For instance -webkit-
or -moz-
.
We offer two popular choices: Autoprefixer (which processes your CSS server-side) and -prefix-free (which applies prefixes via a script, client-side).
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.
You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we'll apply it, in the order you have them, before the CSS in the Pen itself.
You can also link to another Pen here (use the .css
URL Extension) and we'll pull the CSS from that Pen and include it. If it's using a matching preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
JavaScript preprocessors can help make authoring JavaScript easier and more convenient.
Babel includes JSX processing.
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.
You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we'll add it, in the order you have them, before the JavaScript in the Pen itself.
If the script you link to has the file extension of a preprocessor, we'll attempt to process it before applying.
You can also link to another Pen here, and we'll pull the JavaScript from that Pen and include it. If it's using a matching preprocessor, we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
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.
Using packages here is powered by esm.sh, which makes packages from npm not only available on a CDN, but prepares them for native JavaScript ESM usage.
All packages are different, so refer to their docs for how they work.
If you're using React / ReactDOM, make sure to turn on Babel for the JSX processing.
If active, Pens will autosave every 30 seconds after being saved once.
If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.
If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.
Visit your global Editor Settings.
<div :class="['container', isSelected ? 'container-selected':'', isReady ? 'container-ready':'']" id="app">
<div class="team-container">
<div class="header">
<h2 class="header-title">Our Ambassadors</h2>
</div>
<div class="person-list">
<div class="person" v-for="(person,index) in persons" @click="selectPerson(index,$event)"><img class="person-img" :src="person.photo">
<div class="person-details">
<h2 class="person-title">{{person.name}}</h2>
<p class="person-desc">{{person.title}}</p>
</div>
</div>
</div>
</div>
<div class="team-detail">
<div class="team-detail-inner" v-if="isOk">
<div class="team-detail-left" :style=`background-image:url(${selectedPersonData.photo})`>
<div class="team-detail-photo"><img :src="selectedPersonData.photo" alt="">
</div>
</div>
<div class="team-detail-right">
<div class="team-detail-bio">
<div class="team-detail-header">
<h2 class="person-title">{{selectedPersonData.name}}</h2>
<p class="person-desc">{{selectedPersonData.title}}</p>
</div>
<div class="team-detail-bio-content" v-html="selectedPersonData.bio">
</div>
</div>
</div>
</div>
</div>
</div>
@charset "UTF-8";
body {
height: 100%;
font-family: "Poppins", sans-serif;
background-color: rgba(61, 5, 125, 0.79);
}
.container {
width: 100%;
display: flex;
align-items: center;
height: 100vh;
flex-wrap: wrap;
}
.header {
width: 100%;
text-align: center;
margin-top: 60px;
margin-bottom: 45px;
overflow: hidden;
transition: 0.45s ease 0.05s;
max-height: 70px;
}
.header-title {
width: 100%;
font-family: "Yeseva One", cursive;
font-size: 2.5em;
color: #fbf9bd;
margin-bottom: 300px;
}
.team-container {
padding: 0 30px;
box-sizing: border-box;
max-width: 1400px;
width: 100%;
margin: auto;
display: flex;
flex-wrap: wrap;
height: auto;
}
.person {
width: calc(33% - 30px);
cursor: pointer;
overflow: hidden;
transition: 0.45s;
position: relative;
}
.person-details {
padding: 0 20px;
box-sizing: border-box;
margin-top: -15px;
margin-bottom: 55px;
transition: 0.3s;
}
.person-img {
width: 100%;
}
.person-title {
color: #fff;
font-size: 2.3em;
margin-top: 25px;
margin-left:-8px
}
.person-desc {
color: rgba(249, 174, 59);
margin-top: 10px;
margin-left:-8px;
text-transform: uppercase;
font-size: 0.8em;
letter-spacing: 2px;
}
.person-list {
display: flex;
flex-wrap: wrap;
width: 100%;
justify-content: space-between;
}
.person-list:hover .person {
opacity: 0.6;
}
.person:hover {
opacity: 1 !important;
}
.person:before {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
background: #fbf9bd;
content: "";
height: 0px;
transition: 0.45s;
}
.person:after {
content: "";
font-family: "Ionicons";
font-size: 36px;
color: #282828;
position: absolute;
width: 100%;
top: 0;
height: 100%;
display: flex;
opacity: 0;
visibility: hidden;
transition: 0.3s;
text-align: center;
flex-wrap: wrap;
align-items: center;
justify-content: center;
left: 0;
flex-direction: column;
}
.container-selected .header {
max-height: 0px;
}
.container-selected .person {
opacity: 0 !important;
pointer-events: none;
}
.container-selected .person-list .person-selected {
opacity: 1 !important;
}
.container-selected .person-list .person-selected:before {
height: 100%;
}
.container-selected .person-list .person-selected .person-details {
margin-top: -40px;
opacity: 0;
}
.team-detail {
position: absolute;
width: calc(100% - 100px);
right: 80px;
top: 0;
height: 100%;
color: #fff;
transition: 0.15s;
opacity: 0;
visibility: hidden;
box-sizing: border-box;
}
.team-detail-bio-content p {
margin-left: 40px;
margin-bottom: 15px;
line-height: 25px;
font-size: 1.05em;
}
.team-detail-header {
margin-left: 40px;
margin-bottom: 30px;
}
.team-detail-inner {
min-height: 100%;
display: flex;
flex-wrap: wrap;
}
.team-detail-left {
position: relative;
width: 650px;
min-height: 100%;
background-size: cover;
background-repeat: no-repeat;
background-position: top;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.team-detail-left:before {
width: 100%;
height: 100%;
content: "";
background: rgba(40, 40, 40, 0.8);
position: absolute;
right: 0;
top: 0;
}
.team-detail-left:after {
width: 100%;
height: 100%;
content: "";
background: linear-gradient(to right, rgba(40, 40, 40, 0) 9%, rgba(40, 40, 40, 0) 10%, rgba(40, 40, 40, 0) 38%, #282828 92%, #282828 100%);
position: absolute;
right: 0;
top: 0;
}
.team-detail-photo {
position: relative;
text-align: center;
z-index: 999;
width: 100%;
font-size: 0px;
}
.team-detail-photo img {
max-width: 100%;
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.3);
}
.team-detail-right {
box-sizing: border-box;
width: calc(100% - 650px);
min-height: 100%;
display: flex;
align-items: center;
padding-right: 10%;
position: relative;
right: 0;
flex-wrap: wrap;
}
.team-detail-right .person-title {
font-family: "Yeseva One", cursive;
font-size: 2.2em;
}
.container-ready .team-detail {
transition: 0.45s ease 0.3s;
opacity: 1;
right: 0;
visibility: visible;
}
.container-ready .team-detail img {
width: 75%;
}
.container-ready .team-container {
height: 0px;
overflow: hidden;
}
.container-ready .person-selected {
left: 0px !important;
top: 0px !important;
z-index: 99;
height: 100% !important;
width: 100px !important;
pointer-events: auto;
}
.container-ready .person-selected:after {
opacity: 1;
visibility: visible;
}
.person-back:before {
height: 0px !important;
}
.person-back .person-details {
margin-top: -15px !important;
transition-delay: 0.35s;
opacity: 1 !important;
}
.social {
margin-top: 15px;
}
.social a {
color: #fbf9bd;
font-size: 20px;
margin-right: 8px;
}
.social a:last-child {
margin-right: 0;
}
@media (max-width: 1200px) {
.team-detail-left {
width: 400px;
padding: 0 40px;
box-sizing: border-box;
}
.team-detail-right {
padding-right: 0;
width: calc(100% - 440px);
}
.person .person-title {
font-size: 1.7em;
}
.person-details {
padding: 0 10px;
}
}
@media (max-width: 970px) {
.team-detail-left {
width: 100%;
padding: 50px 50px 30px 50px;
}
.team-detail-left:after {
background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #212121 83%, #282828 100%);
}
.team-detail-right {
padding: 0 50px;
width: 100%;
}
.team-detail-header {
text-align: center;
}
.container-ready .person-selected {
width: 50px !important;
}
.team-detail {
width: calc(100% - 50px);
}
.person {
width: calc(50% - 20px);
}
.header {
padding-bottom:30px;
}
}
@media (max-width: 480px) {
.person {
width: 100%;
margin-bottom: 30px;
}
.header {
padding-bottom:50px;
margin-top: 50px;
margin-bottom: 50px;
}
}
const persons = [
{
name: "Ressie Luck-Brimmer",
photo:
"https://plandanville.org/wp-content/uploads/2023/03/Karice_Ressie_Luck-Brimmer_1-transformednew.jpg",
title: "Lead Ambassador",
bio:
"<p>Karice Luck-Brimmer is currently a Community Initiatives program associate for Virginia Humanities responsible for supporting the History United Advisory Council in southern Virginia and the General Assembly African American Cultural Resources Task Force. Working primarily in the Dan River/Danville region, Karice collaborates with local community members to sustain a strong network of cultural organizations committed to positive change. Karice is a public historian and genealogist who has done extensive genealogical research on the Pittsylvania County area, specializing in community based family history. She is the founding president of the Danville/Pittsylvania County Chapter of the Afro-American Historical & Genealogical Society (AAHGS). Karice is also a panelist on the genealogy web show BlackprogenLIVE. In 2019, she was appointed by Governor Northam to serve on the Virginia Board of Historic Resources.</p>",
social: {
facebook: "https://www.facebook.com/profile.php?id=100089953976523",
twitter: "https://www.instagram.com/plandanville",
linkedin: "https://www.linkedin.com/company/plan-danville"
}
},
{
name: "Shay Richardson",
photo:
"https://plandanville.org/wp-content/uploads/2023/03/Shay-Richardson-2new.jpg",
title: "Area 3 | Area 4",
bio:
"<p>I am a gatekeeper.<br>A protector of the many transitions that life brings.<br>A birth worker.<br> vessel of divine grace.<br>And I didn't choose this work. This work chose me. <br>A calling that literally wakes me from my sleep. (IYKYK) <br><br>I am a mother, a writer , a doula, lead chair of the first Maternal Health Task Force in Danville, VA, a WIC Breastfeeding Peer Counselor for Danville & Pittsylvania County, a Childbirth Educator, a Placenta Specialist & a future Midwife. I spend my days (and nights) planting seeds & cultivating the space for mamas to bloom into who they are destined to be. I am, simply put, the gardener, but it is you, my dear and my community who blossoms. I am kindly inviting you to help me pollinate.</p>",
social: {
facebook: "https://www.facebook.com/profile.php?id=100089953976523",
twitter: "https://www.instagram.com/plandanville",
linkedin: "https://www.linkedin.com/company/plan-danville"
}
},
{
name: "Amyia Totten",
photo:
"https://plandanville.org/wp-content/uploads/2023/03/Amyia-Totten-1new.jpg",
title: "Area 1",
bio:
"<p>My name is Amyia Totten I am a Danville native. I am currently enrolled at Radford University in pursuing a Master’s in Clinical Mental Health Counseling. I am also an intern as a counselor in training at Family of Hands here in Danville. I am pleased to have been offered this opportunity as community ambassador because one of my goals for this year was to be more involved in the community and connect with people.</p>",
social: {
facebook: "https://www.facebook.com/profile.php?id=100089953976523",
twitter: "https://www.instagram.com/plandanville",
linkedin: "https://www.linkedin.com/company/plan-danville"
}
},
{
name: "James Reynolds",
photo:
"https://plandanville.org/wp-content/uploads/2023/03/Bernard-Reynolds.jpg",
title: "Area 2",
bio:
"<p>My name is James Reynolds. I am the Executive Director of Men for Change/Stop the Violence/Community Outreach Organization. Our mission for this organization/outreach is to help restore, reconcile, and encourage the healing process in our families and communities. It is my desire to build communities up with love and to stop the unnecessary violence amongst us.</p>",
social: {
facebook: "https://www.facebook.com/profile.php?id=100089953976523",
twitter: "https://www.instagram.com/plandanville",
linkedin: "https://www.linkedin.com/company/plan-danville"
}
},
{
name: "Felice McWilliams",
photo:
"https://plandanville.org/wp-content/uploads/2023/03/Felice-McWilliams.jpg",
title: "Area 6",
bio:
"<p>Felice McWilliams has had extensive experience supporting the communities where she has lived. Prior to coming to Danville she served as the recording secretary of the African American Mental Health Coalition in San Bernardino. Additionally she served with the Westside Nubians as the 2nd Vice President, the President’s Personal Assistant and secretary. In this role, she served as a resource to the organization and the community. <br><br>From Felice - ''I have had blessed opportunities to travel as a Missionary, to many places in the world, sharing my gifts of Worship. Training musicians and vocalist to become a team, coaching vocals, using guitars and keyboards. Worked in India, Singapore, Japan, 4 time zones in Russia, and Mexico.''</p>",
social: {
facebook: "https://www.facebook.com/profile.php?id=100089953976523",
twitter: "https://www.instagram.com/plandanville",
linkedin: "https://www.linkedin.com/company/plan-danville"
}
},
{
name: "Sonya Wolen",
photo:
"https://plandanville.org/wp-content/uploads/2023/03/sony-transformednwew.png",
title: "Area 5",
bio:
"<p>The majority of my career was spent in various aspects of education, primarily science education. As an informal science educator and administrator, I led programs and projects in four museums – two in Indiana and two in Virginia. I was also involved as a grant writer and education contractor in the Danville community. As an outgrowth of my paid positions, I have served on community boards and statewide councils. I am currently an active volunteer and board member of the Dan River Basin Association, and do volunteer work with Virginia Master Naturalists and the City of Danville. <br><br>''Never doubt that a small group of thoughtful, committed citizens can change the world: indeed, it’s the only thing that ever has.'' - Margaret Mead</p>",
social: {
facebook: "https://www.facebook.com/profile.php?id=100089953976523",
twitter: "https://www.instagram.com/plandanville",
linkedin: "https://www.linkedin.com/company/plan-danville"
}
}
];
const app = new Vue({
el: "#app",
data() {
return {
persons: persons,
selectedPersonIndex: null,
isSelected: false,
selectedPerson: null,
inlineStyles: null,
isReady: false,
isOk: false,
selectedPersonData: {
name: null,
title: null,
photo: null,
social: {
facebook: null,
twitter: null,
linkedin: null
}
}
};
},
methods: {
selectPerson(index, el) {
if (!this.isOk) {
this.selectedPersonIndex = index;
this.isSelected = true;
el.target.parentElement.className == "person-details"
? (this.selectedPerson = el.target.parentElement.parentElement)
: (this.selectedPerson = el.target.parentElement);
this.selectedPerson.classList.add("person-selected");
this.selectedPerson.setAttribute(
"style",
`width:${this.selectedPerson.offsetWidth}px;`
);
this.selectedPersonData = this.persons[index];
window.setTimeout(() => {
this.inlineStyles = `width:${this.selectedPerson.offsetWidth}px;height:${this.selectedPerson.offsetHeight}px;left:${this.selectedPerson.offsetLeft}px;top:${this.selectedPerson.offsetTop}px;position:fixed`;
this.selectedPerson.setAttribute("style", this.inlineStyles);
}, 400);
window.setTimeout(() => {
this.isReady = true;
this.isOk = true;
}, 420);
} else {
this.reset();
}
},
reset() {
this.isReady = false;
window.setTimeout(() => {
this.selectedPerson.classList.add("person-back");
}, 280);
window.setTimeout(() => {
this.selectedPerson.setAttribute("style", "");
}, 340);
window.setTimeout(() => {
this.isSelected = false;
this.selectedPerson.classList.remove("person-back", "person-selected");
this.isOk = false;
}, 400);
}
}
});
Also see: Tab Triggers