JSFiddle - React, Tailwind, and code Playground

by Derek Wood

HTML

<header class="page-section site-header">
<div class="inner-w">
  
  <p>Just a way to have that ol column... so, you see that it's not integral to the below</p>
  
</div>
</header>



<section class="page-section section-name">
<div class="inner-w">
  
  <aside class="component-name">
    <ul class="list" id="exampleTarget">

      <!-- it's likely - that this will be dynamically populated - by PHP or AJAX or - if you're lucky, Emberjs -->

<!--       
      <li class="item">
        <aside class="card">
          
          <button class="remove-card">
            x
          </button>
        
          <span>{{id}}</span>
        </aside>
      </li>
-->

    </ul>
    
    <footer>
      <button data-trigger='add-card'>
        <span>Add a card</span>
      </button>
    </footer>
  </aside>
  
</div>
</section>

CSS

/* READ IT: https://www.paulirish.com/2012/box-sizing-border-box-ftw/ */

/* apply a natural box layout model to all elements, but allowing components to change */
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}

/* Keep in mind that I added normalize CSS to kinda 'reset' the crappy CSS defaults */

.page-section .inner-w {
  width: 100%; /* let it be as big as it can */
  max-width: 900px; /* not too big though */
  margin-right: auto;
  margin-left: auto;
  padding: 1rem;
  border: 1px solid gray;
}

.site-header {
  background: darkgray;
  color: white;
}

.site-header p {
  opacity: .3;
}

/* .....  */

.component-name {
  background: lightgray;
}

.component-name .list {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
  padding: 1rem;
}

.component-name .item {
  /* ... */
}

.component-name .card {
  position: relative; /* for the remove button */
  padding: 2rem 4rem;
  background: #56B9C6;
  border-radius: .5rem;
  color: white;
}

.component-name footer {
  display: flex;
  justify-content: center;
  margin-top: 3rem;
}

.component-name button.remove-card {
  position: absolute;
  top: 0;
  right: 0;
  opacity: .4;
}

JavaScript

console.clear();


var idMaker = { // there are better ways to do this... but for fun ->
  ids: [],
  removed: [], // you could save the ones you remove
	latestId: 0,
  create: function() {
    this.latestId = this.latestId + 1;
    this.ids.push(this.latestId);
    console.log('ID #' + this.latestId + ' created');
    this.read();
    return this.latestId;
  },
	read: function() {
  	console.clear();
    console.log('created: ', this.ids);
    console.log('removed: ', this.removed);
  },
}; // creates a little library for creating id's for the cards

idMaker.read(); // no ids to start


// will take an object with the list name and the card id
// eventuallly - you'd want the card to have more info sent in...
function addCard(infoObject) {
	var targetList = document.getElementById(infoObject.list);
	var li = document.createElement('li');
  li.classList.add('item');
  var component = document.createElement('aside');
  component.classList.add('card');
  var title = document.createElement('h2');
  var uniqueId = idMaker.create();
  var id = document.createTextNode(uniqueId);
  title.appendChild(id);
  component.appendChild(title)
  li.appendChild(component);
  targetList.appendChild(li);
  // woah... this part is really boring...
  // this is why templating engines and JSON are so popular
  // you could also add 'remove' button etc... right?
  var removeButton = document.createElement('button');
  var removeText = document.createTextNode('x');
  removeButton.appendChild(removeText);
  removeButton.classList.add('remove-card');
  component.appendChild(removeButton);
 	//
  removeButton.addEventListener('click', function() {
  	var parent = document.getElementById(infoObject.list);
    idMaker.removed.push(uniqueId);
  	parent.removeChild(li);
    idMaker.read();
  });
}

// start out with a few?
addCard({list: 'exampleTarget'});
addCard({list: 'exampleTarget'});
addCard({list: 'exampleTarget'});

// start a UI to add cards
var addCardButton =...