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

Auto Save

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="hero">
  <h1 class="hero__title js-hero-title" data-job-rotate="Marketeer,Back-end developer,Project manager">
    <span class="hero__label js-hero-label">
      Ben jij onze nieuwe
    </span>
    <br>    
    <div class="hero__job-line js-hero-job-line">
      <span class="hero__job js-hero-job">
        <span>Marketeer</span>
      </span>
    </div>
  </h1>
</div>

<!-- 
Titles:
- Marketeer
- Back-end developer
- Front-end developer
- Project manager
- Grafisch vormgever
- Interactief vormgever
- Interaction designer
-->
              
            
!

CSS

              
                body {
  background-color: #222;
}

.hero {
  padding: 40px;
  background: #222;
  font-family: Century Gothic, CenturyGothic, AppleGothic, sans-serif;
  text-transform: uppercase;
}

.hero__title {
  font-size: 4rem;
}

.hero__label,
.hero__job {
  margin: 0;
  padding: .5rem 0;
  white-space: nowrap;
  overflow: hidden;
  display: inline-block;
}

.hero__label {
  color: #fff;
  padding-left: 0;
  padding-right: 0;
}

.hero__job-line {
  text-align: right;
}

.hero__job {
  color: #333;
  background: #fff;
  direction: rtl;
  transition: width 1s cubic-bezier(0.77, 0, 0.175, 1), opacity .75s ease-in;
}

.hero__job span {
  display: block;
  margin-left: .75rem;
  margin-right: .75rem;
}
              
            
!

JS

              
                // Elements
const titleEl = document.querySelector('.js-hero-title');
const jobEl = document.querySelector('.js-hero-job');
const jobLineEl = document.querySelector('.js-hero-job-line');
const labelEl = document.querySelector('.js-hero-label');

// Label
const labelText = labelEl.textContent.trim();
const labelTextLen = labelText.length;
let labelTextTick = 0;

// Timing
const LABEL_TICK_INTERVAL = 100;
const LABEL_TICKER_DURATION = (labelTextLen + 1) * LABEL_TICK_INTERVAL;
const JOB_SWITCH_SPEED = 4000;
const JOB_TRANSITION_DURATION = 1000;

// Get a list of jobs
const jobs = titleEl.getAttribute('data-job-rotate').split(',');

let currentJob = jobs[0];
let currentJobNr = 0;

/**
 * Set the job line wrapping element width
 */
function setJobLineWidth() {
  jobEl.style.width = 'auto';
  jobLineEl.style.width = jobEl.offsetWidth + 'px';
  jobEl.style.width = 0;
}

/**
 * Output the job title to the DOM
 * @param {String} name Name of the job title
 * @return {Void}
 */
function outputJob(name) {
  jobEl.innerHTML = `<span>${name}</span>`;
}

/**
 * Get the next job title
 * @return {Void}
 */
function getNextJob() {
  currentJobNr += 1;
    
  if (currentJobNr >= jobs.length) {
    currentJobNr = 0;
  }

  currentJob = jobs[currentJobNr];
}

/**
 * Go to the next job in the list
 * @return {Void}
 */
function goToNextJob() {
  getNextJob();

  // Transition to origin (collapsed)
  jobEl.style.width = 0;
  jobEl.style.opacity = 0;
  
  // Wait for the transition to finish, and after we set the next job title
  setTimeout(() => {
    // Output the job title to the DOM
    outputJob(currentJob);
    
    // Calculate the width
    jobEl.style.width = 'auto';
    const jobElWidth = jobEl.offsetWidth;
    jobEl.style.width = 0;
    
    // Wait a little while and set the new styles
    setTimeout(() => {
      jobLineEl.style.width = jobElWidth + 'px';
      jobEl.style.width = jobElWidth + 'px';
      jobEl.style.opacity = 1;
    }, 100);
  }, JOB_TRANSITION_DURATION);
}

// Remove the label initially
labelEl.innerHTML = '';

// Output the first job title
outputJob(currentJob);

// Hide the job title initially
jobEl.style.opacity = 0;

// Set the width for the job title
setJobLineWidth();

// 'Type' each letter
const labelTicker = setInterval(() => {
  labelTextTick += 1;
  
  // Output the string
  labelEl.textContent = labelText.substring(0, labelTextTick);
  
  // Stop the interval when all letters are outputted
  if (labelTextTick >= labelTextLen) {
    clearInterval(labelTicker);
  }
}, LABEL_TICK_INTERVAL);

// Show the first job title
setTimeout(() => {
  // Fade in, this will hide the padding transition a little
  jobEl.style.opacity = 1;
  
  // Set to full width, CSS will transition to it
  jobEl.style.width = jobLineEl.offsetWidth + 'px';
  
  // Create a loop where the job title switches on every iteration
  setInterval(() => {
    goToNextJob();
  }, JOB_SWITCH_SPEED);
}, LABEL_TICKER_DURATION);

              
            
!
999px

Console