<div id="root">
</div>
body {
  position: relative;
}

.container {
  position: relative;
  display: flex;
  flex-direction: row;
  flex-wrap: no-wrap;
  overflow-x: auto;
  padding: 20px;
}

.item {
  position: relative;
  flex-shrink: 0;
  width: 500px;
  height: 400px;
  border-radius: 5px;
  border: 2px solid #dedede;
  margin-right: 15px;
  padding: 10px;
  box-shadow: 5px 5px 10px #78787888;
}

.heading {
  font-size: 1.5rem;
  font-family: sans-serif;
  overflow: hidden;
   text-overflow: ellipsis;
   display: -webkit-box;
   -webkit-line-clamp: 2; /* number of lines to show */
   -webkit-box-orient: vertical;
}

.description {
  font-size: 2rem;
  background-color: #dedede;
  padding: 10px;
  height: 200px;
}

.icons {
  width: 100%;
  position: absolute;
  bottom: 10px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-around;
}

.icons p {
  font-size: 2rem;
  margin-left: -90px;
  margin-top: -30px;
}

.open:hover {
  cursor: pointer;
}

View Compiled

class DevArticles extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      articles: [],
    }
  }
  
  callApi = (username = 'comscience') => {
    fetch(`https://dev.to/api/articles?username=${username}`)
    .then((result) => {
      // Get the result
      // If we want text, call result.text()
      return result.json();
    }).then((jsonResult) => {
      // Do something with the result
      console.log('result: ', jsonResult);
      this.setState({articles: jsonResult})
    })
  }
  
  componentDidMount() {
    this.callApi(this.props.username);
  }
  
  render(){
    return (
      <div>
        <div className="container">
        {this.state.articles.map(
          item => 
            <div className="item">
              <h1 className="heading"><strong>{item.title}</strong></h1>
              {item.cover_image ? 
                <img src={item.cover_image}></img> :
                <div className="description"><h2>{item.description}</h2></div>
              }
              <div className="icons">
                  <Icon icon="heart" width="80px" fill="#898989"/>
                  <p><strong>{item.positive_reactions_count}</strong></p>
                  <Icon icon="comments" width="80px" fill="#898989"/>
                  <p><strong>{item.comments_count}</strong></p>
                <a href={item.canonical_url} className="open"><Icon icon="open" width="80px" fill="#898989"/></a>
              </div>
            </div>      
          )}
        </div>
      </div>
    )
  }
}


ReactDOM.render(<DevArticles />, document.getElementById('root'))

class Icon extends React.Component {
  renderIcon = () => {
    switch (this.props.icon) {
      case 'comments':
        return (
          <g>
            <path d="M14.999,8.543c0,0.229-0.188,0.417-0.416,0.417H5.417C5.187,8.959,5,8.772,5,8.543s0.188-0.417,0.417-0.417h9.167C14.812,8.126,14.999,8.314,14.999,8.543 M12.037,10.213H5.417C5.187,10.213,5,10.4,5,10.63c0,0.229,0.188,0.416,0.417,0.416h6.621c0.229,0,0.416-0.188,0.416-0.416C12.453,10.4,12.266,10.213,12.037,10.213 M14.583,6.046H5.417C5.187,6.046,5,6.233,5,6.463c0,0.229,0.188,0.417,0.417,0.417h9.167c0.229,0,0.416-0.188,0.416-0.417C14.999,6.233,14.812,6.046,14.583,6.046 M17.916,3.542v10c0,0.229-0.188,0.417-0.417,0.417H9.373l-2.829,2.796c-0.117,0.116-0.71,0.297-0.71-0.296v-2.5H2.5c-0.229,0-0.417-0.188-0.417-0.417v-10c0-0.229,0.188-0.417,0.417-0.417h15C17.729,3.126,17.916,3.313,17.916,3.542 M17.083,3.959H2.917v9.167H6.25c0.229,0,0.417,0.187,0.417,0.416v1.919l2.242-2.215c0.079-0.077,0.184-0.12,0.294-0.12h7.881V3.959z"></path>
          </g>
        );
      case 'heart':
        return (
          <g>
            <path d="M9.719,17.073l-6.562-6.51c-0.27-0.268-0.504-0.567-0.696-0.888C1.385,7.89,1.67,5.613,3.155,4.14c0.864-0.856,2.012-1.329,3.233-1.329c1.924,0,3.115,1.12,3.612,1.752c0.499-0.634,1.689-1.752,3.612-1.752c1.221,0,2.369,0.472,3.233,1.329c1.484,1.473,1.771,3.75,0.693,5.537c-0.19,0.32-0.425,0.618-0.695,0.887l-6.562,6.51C10.125,17.229,9.875,17.229,9.719,17.073 M6.388,3.61C5.379,3.61,4.431,4,3.717,4.707C2.495,5.92,2.259,7.794,3.145,9.265c0.158,0.265,0.351,0.51,0.574,0.731L10,16.228l6.281-6.232c0.224-0.221,0.416-0.466,0.573-0.729c0.887-1.472,0.651-3.346-0.571-4.56C15.57,4,14.621,3.61,13.612,3.61c-1.43,0-2.639,0.786-3.268,1.863c-0.154,0.264-0.536,0.264-0.69,0C9.029,4.397,7.82,3.61,6.388,3.61"></path>
          </g>
        );
      case 'open':
        return (
          <g>
            <path d="M16.76,7.51l-5.199-5.196c-0.234-0.239-0.633-0.066-0.633,0.261v2.534c-0.267-0.035-0.575-0.063-0.881-0.063c-3.813,0-6.915,3.042-6.915,6.783c0,2.516,1.394,4.729,3.729,5.924c0.367,0.189,0.71-0.266,0.451-0.572c-0.678-0.793-1.008-1.645-1.008-2.602c0-2.348,1.93-4.258,4.303-4.258c0.108,0,0.215,0.003,0.321,0.011v2.634c0,0.326,0.398,0.5,0.633,0.262l5.199-5.193C16.906,7.891,16.906,7.652,16.76,7.51 M11.672,12.068V9.995c0-0.185-0.137-0.341-0.318-0.367c-0.219-0.032-0.49-0.05-0.747-0.05c-2.78,0-5.046,2.241-5.046,5c0,0.557,0.099,1.092,0.292,1.602c-1.261-1.111-1.979-2.656-1.979-4.352c0-3.331,2.77-6.041,6.172-6.041c0.438,0,0.886,0.067,1.184,0.123c0.231,0.043,0.441-0.134,0.441-0.366V3.472l4.301,4.3L11.672,12.068z"></path>
          </g>
        )
      // add more icons here
    }
  };

  render() {
    return(
      <svg 
        xmlns="http://www.w3.org/2000/svg" 
        icon={this.props.icon}
        width={this.props.width} 
        height={this.props.height} 
        viewBox="0 0 32 32"
        aria-labelledby={this.props.title}
        fill={this.props.fill}
       >
        <title id={this.props.title}>{this.props.description}</title>
        {this.renderIcon()}
      </svg>
    );
  }
}
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.2/css/bulma.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js
  3. https://unpkg.com/@material-ui/core@latest/umd/material-ui.production.min.js