Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's 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 it's URL and the proper URL extention.

+ 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

              
                <button id="add-snackbar" onclick="add_snackbar()">add snackbar</button>

<!--   snackbarを配置する要素はどこにあっても良い。中身だけがfixedになるので。 -->
<div class="snackbar-area"></div>

<template id="snackbar-template">
  <div class="snackbar-outer">
    <div class="snackbar-inner">notification.</div>
  </div>
</template>
              
            
!

CSS

              
                .snackbar-outer{
  // positionは画面ベースで固定
  position: fixed;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 5px;
  // width, heightは具体的に指定しておく
  width: 200px;
  height: 40px;
  // 挿入時の初期位置(X方向)
  left: -300px;
  // Y方向の初期位置は状況により変わるので初期値は適当で良い
  bottom: 0;
  background-color: #333;
  color: #ddd;
  border-radius: 5px;
  box-shadow: 2px 2px 5px 1px #00000080;
  // 比較的早目で、functionをease-inにすると軽く重力で落下するようなエフェクトになる
  transition: all .3s ease-in;  
  .snackbar-inner{
    width: 100%;
    text-align: center;
  }
}

              
            
!

JS

              
                var snackbar_stack = [];  // 画面上に出ているスナックバーを入れておく配列
var SNACKBAR_MAX = 3;   //画面上に配置できるsnackbarの最大数
var SNACKBAR_HEIGHT = 50;  // スナックバーのheight値
var snackbar_area = document.querySelector('div.snackbar-area');

function add_snackbar(){
  let sb = document.querySelector('#snackbar-template').content.cloneNode(true);
  let outer = sb.querySelector('.snackbar-outer');
  // console.log(outer);
  let shiftbar = null;  // もし最大数を超えるスナックバーを追加する際、追い出されるスナックバーのNode
  let idx = snackbar_stack.push(outer) -1;  // idxはスナックバー挿入位置
  if(snackbar_stack.length > SNACKBAR_MAX){
    // 最大数を超えるスナックバーがpushされている場合は、先頭を取り出しておく。
    shiftbar = snackbar_stack.shift();
  }
  // console.log(shiftbar);
  // スナックバーをDOMに追加
  snackbar_area.appendChild(sb);
  // 追加するスナックバーの初期Y位置。
  outer.style.bottom = `${idx * SNACKBAR_HEIGHT}px`;
  // 追加するスナックバーと追い出されるスナックバーのX位置をsetTimeoutで指定。
  // こうすることでtransitionが有効になる。(ディレイ0でもOK)
  setTimeout(() => {
    // スライドアウトするほう
    if(shiftbar){
      shiftbar.style.left = '-500px';
    }
    // スライドインしてくる方
    outer.style.left = `0px`;
  },0);

  // スナックバーのスライドイン、スライドアウトアニメが終了した後に残りのスナックバーを
  // 下方向にスライドさせる。ディレイ値にtransitionで指定したtransition-durationと同じ秒数を設定。
  // 同じくtransitionが有効。
  setTimeout( () => {
    // スライドアウトしたスナックバーはこのタイミングでDOMから削除すれば表示に影響はない。
    if(shiftbar){
      shiftbar.remove();
    }
    // 各スナックバーのY方向を再設定。
    snackbar_stack.forEach((e,i) => e.style.bottom = `${i * SNACKBAR_HEIGHT}px` );
  }, 300);
}
              
            
!
999px

Console