cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

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.

            
              %h1.page-title>Fill-in-the-blank Tweets
%p.page-detail
  Prototype for a suggested tweet template feature for users. 
.custom-tweets
  %span.custom-tweets_trigger
  %ul.list.custom-tweets_list
    %li.list_item
      Hey Internet, I need help with 
      %input{:type=>"text", :class => 'custom-tweets_input'}. 
      What do you recommend?
    %li.list_item
      Hey Internet, my fancy tech 
      %input{:type=>"text", :class => 'custom-tweets_input'} 
      is broken. What do I do now?!
    %li.list_item
      Hey Internet, I'm looking for 
      %input{:type=>"text", :class => 'custom-tweets_input'}. 
      Can you point me in the right direction?
    %li.list_item
      This demo on CodePen is 
      %input{:type=>"text", :class => 'custom-tweets_input'}. 
      Check it out! #webdev
  .custom-tweets_error.error
    %p>Whoops! Looks like you left the blank... blank!
  .custom-tweets_counter
  %button.custom-tweets_submit-button
    Send Tweet

%p.page-detail
  Simply add or subtract list items to the markup and change the text. If you are not familiar with HAML, just click on 'View Compiled' in the HTML section of the CodePen.
%p.page-detail
  Suggested accounts to follow that appear after the tweet has been sent can be added to the Tweet URL in the javascript.
%hr
%p.page-detail
  Drop-down menu effect inspired by  
  %a{ :href => "https://tympanus.net/Development/SimpleDropDownEffects/index.html", :title => "CoDrops Simple Effects for Drop-Down Lists" }CoDrops,
  implemented with CSS3 Perspective and Transform to reduce number of inline attributes.
%p.page-detail
  Created by 
  %a{:href => "https://jannypie.github.io"}Jan Dennison
            
          
!
            
              $textColor: #aaa
$borderColor: #efefef
$highlightColor: #5cdced
$containerWidth: 100%
$containerMargin: 50px
$containerHeight: 60px

html
  box-sizing: border-box
*,*:before,*:after
  box-sizing: inherit

body
  color: $textColor
  padding: 2em

a
  color: $highlightColor
  text-decoration: none
  transition: color 500ms ease
a:hover
  color: #333

.page-title
  font-size: 1.25em
  margin-top: 50px
  text-transform: uppercase
  text-align: center

.page-detail
  font-size: 0.9em
  text-align: center
  max-width: 40em
  margin: 0 auto 1em

.error
  color: orangered
  display: none
  
.custom-tweets
  position: relative
  width: $containerWidth
  margin: $containerMargin auto
  text-align: center

.custom-tweets_trigger
  background: #fff
  border: 10px solid transparent
  border-left: 1px solid $borderColor
  border-right: 0
  cursor: pointer
  display: block
  text-align: left
  position: absolute
  top: 1px
  right: 0
  width: $containerHeight
  height: $containerHeight
  z-index: 10
  &:after
    content: '»'
    color: $highlightColor
    font-family: serif
    font-size: 2em
    width: $containerHeight
    height: $containerHeight
    line-height: $containerHeight - 5
    vertical-align: middle
    text-align: center
    top: -10px
    position: absolute
    transform: rotate(90deg)
    transition: transform 300ms ease, color 300ms ease
  &.open:after
    color: $textColor
    transform: rotate(270deg)
.list
  list-style-type: none
  margin: 0 0 2em 0
  padding: 0
  display: block
  top: 0px
  width: 100%
  height: 100%
  -webkit-perspective: 500px
  perspective: 500px

.list_item
  border: 1px solid $borderColor
  display: block
  position: absolute
  width: 100%
  background: #fff
  line-height: 60px
  padding: 0 10px 0
  color: $textColor
  font-weight: 700
  transition: all 300ms ease
  white-space: nowrap
  overflow: hidden
  &:after
    content: ''
    background: #fff
    height: $containerHeight
    width: 10px
    position: absolute
    right: 0
    top: 0
    -webkit-box-shadow: 0px 0px 10px 10px rgba(255,255,255,1)
    -moz-box-shadow: 0px 0px 10px 10px rgba(255,255,255,1)
    box-shadow: 0px 0px 10px 10px rgba(255,255,255,1)
    transition: all 300ms ease
  &:first-child:after
    right: $containerHeight

.custom-tweets_trigger.open + .list .list_item:not(:first-child):hover
  background: $highlightColor
  border-color: #5cdced
  color: white
  cursor: pointer
  &:after
    background: $highlightColor
    -webkit-box-shadow: 0px 0px 10px 10px $highlightColor
    -moz-box-shadow: 0px 0px 10px 10px $highlightColor
    box-shadow: 0px 0px 10px 10px $highlightColor

.custom-tweets_input
  background: transparent
  border: 0
  border-bottom: 1px solid $textColor
  color: $textColor
  font-size: 17px
  padding: 0
  text-align: center
  width: auto
  max-width: 3em
  transition: max-width 300ms ease
  
.custom-tweets_input:focus
  outline: none
  max-width: 10em

.custom-tweets_counter
  font-size: 0.7em
  text-transform: uppercase

.custom-tweets_submit-button
  color: $highlightColor
  border: 1px solid $highlightColor
  background: #fff
  margin: 1em
  padding: 1em
  transition: color 300ms ease, background 300ms ease
  &:hover
    color: #fff
    background: $highlightColor
  
//background credit http://www.transparenttextures.com/
body
  background-color: #ededed
  background-image: url(http://www.transparenttextures.com/patterns/45-degree-fabric-light.png)
            
          
!
            
              // Set variables for desired stacking effect depth and top position. Will remain constant.
var perspectiveOffset = 10,
    topOffset = 5,
    itemHeight = 67;

// Will be changed in increments of offset values to position each list item in a staggered effect.
var currentPerspectiveDepth = 0,
    currentTopPosition = 0;

// Since List Items are positioned absolute, set a height on List that contains our items
var setListHeight = function($listItems) {
  $('.list').height(itemHeight + (topOffset * $listItems.length));
}

// Reverse the zIndex stacking order of the List Items so that they appear one over the next rather than over the previous
var orderListItemsIndex = function($listItems) {
  $listItems.each(function(i) {
    $(this).css('z-index', -i);
  });
}

// Sets perspective depth to decrease Item width in increments, and top position to make the stacked edges visible below the one before it
var stackItems = function(listItems) {
  orderListItemsIndex(listItems);
  $(listItems).each(function() {
    $(this).css({
      'transform': 'translateZ(-' + currentPerspectiveDepth + 'px)',
      'top': currentTopPosition + 'px'
    });
    incrementCurrentPositions();
  });
}

// Line everybody up regular list style
var unstackItems = function(listItems) {
  $(listItems).each(function(i) {
    $(this).delay(1000).css({
      'transform': 'translateZ(0)',
      'top': (itemHeight * i) + 'px'
    });
    decrementCurrentPositions();
  });
}

var incrementCurrentPositions = function() {
  currentPerspectiveDepth += perspectiveOffset;
  currentTopPosition += topOffset;
}

var decrementCurrentPositions = function() {
  currentPerspectiveDepth -= perspectiveOffset;
  currentTopPosition -= topOffset;
}

// Expand/collapse the list items
var customTweetsTriggerHandler = function() {
  // reassign this new each time to grab the correct order
  var listItems = $('.list_item');
  
  if (!$(this).hasClass('open')) {
    $(this).addClass('open');
    //expand list items
    unstackItems(listItems);
    // Bind list item click handler
    listItemClickHandler(listItems,$(this));
    // Unbind item input key counter
    unbindTweetCharCounterKeyup(listItems.first());
  } else {
    $(this).removeClass('open');
    // Unbind list item click handler
    unbindListItemClickHandler(listItems);
    // collapse list items
    stackItems(listItems);
    // Update characters remaining count
    updateTweetCharCounter(listItems.first());
  }
}

// When a list item is clicked, move it to the top of the list
// and reset the stack
var listItemClickHandler = function(listItems,listTrigger) {
  $(listItems).each(function() {
    $(this).click(function() { 
      listItems.parent().prepend($(this));
      listTrigger.triggerHandler("click");
    });
  });
}
// Unbind the click handler when the list is collapsed
// so that users can type in the input box
var unbindListItemClickHandler = function(listItems) {
  $(listItems).off("click");
}

// Show count of remaining characters before Tweet length limit
var updateTweetCharCounter = function(item) {
  var tweetCharCounter = $('.custom-tweets_counter'),
      itemInput = item.find('input'),
      itemInputLength = itemInput.val().length,
      itemTemplateLength =  $(item).text().length;
  
  var bindTweetInputCount = function(itemInput) {
    itemInput.keyup(function(){
      itemInputLength = $(this).val().length;
      printTweetCharCount();
    });
  }
  
  var printTweetCharCount = function() {
    tweetCharCounter.html(140 - itemTemplateLength - itemInputLength + " characters left");
  }
  
  bindTweetInputCount(itemInput);
  printTweetCharCount();
}
var unbindTweetCharCounterKeyup = function(item) {
  item.off('keyup');
}

var customTweetsSubmitHandler = function() {
  var selectedTweet = $('.list_item').first(),
      selectedTweetCopy = selectedTweet.clone(),
      selectedTweetInput = selectedTweet.find('input');
  var checkEmptyInput = function() {
    return selectedTweetInput.val().length < 1
  }
  var buildTweetURL = function(){
    // Get value of the input field and convert to text
    var selectedTweetInputText = selectedTweet.find('input').val();
    selectedTweetInput.replaceWith(selectedTweetInputText);
    // grab the text to be tweeted
    encodedTweetText = encodeURIComponent(selectedTweet[0].innerText);
    // build the url
    // if you wish to add a "related" twitter account
    // that shows once the tweet has been published,
    // append ' + &related=yourtwittername' to end
    return "https://twitter.com/share?url=&text=" + encodedTweetText;
  }
  // check if the input field is empty
  if (!checkEmptyInput()) {
    // input has text build the tweet and open the window
    $('.custom-tweets_error.error').fadeOut();
    window.open(buildTweetURL(),'','width=550px,height=420px');
    resetTweetInput(selectedTweetCopy);
  } else {
    // input is empty, show an error message
    $('.custom-tweets_error.error').fadeIn();
  } 
}

// Once a tweet has been sent, reset the input box
var resetTweetInput = function(selectedTweetCopy) {
  var sentTweet = $('.list_item').first();
  sentTweet.replaceWith(selectedTweetCopy);
  selectedTweetCopy.find('input').val("");
}

// Kick it off!
$(document).ready(function() {

  // Hey we're in the DOM now!
  var $listItems = $('.list_item');

  // Initial setup
  setListHeight($listItems);
  stackItems($listItems);
  updateTweetCharCounter($listItems.first());

  // Bind arrow trigger to expand/collapse list
  $('.custom-tweets_trigger').click(customTweetsTriggerHandler);
  
  // Bind send tweet button
  $('.custom-tweets_submit-button').click(customTweetsSubmitHandler);
});
            
          
!
999px
Loading ..................

Console