css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

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. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

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

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

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.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              @import url("https://fonts.googleapis.com/css?family=Montserrat:300,700");

:root {
  --main-border-radius: 12px;
  --height: 730px;
  --width: 411px;
  --font: "Montserrat", sans-serif;
  --black: #292929;
  --red: #e56a77;
  --red-pressed: #b23946;
  --white: #ffffff;
}

body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
  overflow-x: hidden;
}

h1,
p,
button {
  font-family: var(--font);
  /* border: 1px solid red; */
}

h1 {
  font-size: 22px;
  font-weight: 700;
  color: var(--black);
  margin: 0;
}

p {
  font-size: 16px;
  font-weight: 300;
  color: rgba(66, 66, 66, 0.39);
  margin: 5px;
}

button {
  border: none;
  cursor: pointer;
  font-size: 18px;
  font-weight: 700;
  color: var(--black);
}

button:focus {
  outline: 0 !important;
}

button::-moz-focus-inner {
  border: 0;
}

.container {
  position: absolute;
  height: 100%;
  width: 100%;
  background: #ffffff;
}

.card {
  position: relative;
  margin: auto;
  height: var(--height);
  width: var(--width);
  /* border: 1px solid #292929; */
  border-radius: 22px;
  top: 10%;
  z-index: 1;
}

.hot-air {
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  top: 40%;
  animation: hot-air 5s ease-in-out 1s infinite;
  /* z-index: ; */
  /* visibility: hidden; */
}

.start {
  /* border: 1px solid black; */
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  bottom: 11.5%;
  text-align: center;
  z-index: 10;
}

.text {
  margin-bottom: 50px;
}

.shadow {
  box-shadow: 0px 50px 50px rgba(0, 0, 0, 0.15);
}

.gradient {
  background: linear-gradient(209.22deg, #ffffff 4.25%, #f1f1f1 95.6%);
}

.add {
  width: calc(var(--width) / 2.92);
  height: 60px;
  background: #ffffff;
  border-radius: 100px;
  position: relative;
  margin: auto;
}

.none {
  display: none;
}

.todo {
  padding-top: 40px;
  position: relative;
}

.task {
  position: relative;
  border-bottom: 1px solid rgb(234, 234, 234);
  margin: 5px 40px 5px 40px;
  height: 100%;
  color: var(--black);
  min-height: 50px;
  overflow-x: hidden;
  transition: margin 0.2s cubic-bezier(0.68, -0.55, 0.265, 1.55),
    box-shadow 0.3s linear, border-radius 0.25s linear;
  font-family: var(--font);
  font-size: 22px;
  font-weight: 300;
  color: rgba(66, 66, 66, 0.39);
  display: block;
}

.task button {
  padding: 0px;
  background-color: transparent;
  font-family: var(--font);
}

.task:hover {
  border: 0px solid var(--black);
  box-shadow: 0px 50px 50px rgba(0, 0, 0, 0.15);
  margin: 5px 20px 5px 20px;
  border-radius: var(--main-border-radius);
  background-color: var(--black);
  font-size: 22px;
  font-weight: 700;
}

.task:hover .left {
  margin: 12px 0 12px 20px;
  color: var(--white);
}

.content {
  max-width: 70%;
}

.task:hover .right {
  margin: 14px 20px 12px 20px;
  color: var(--white);
  display: inherit;
}

.task:hover .time {
  display: none;
}

.form {
  position: absolute;
  margin: 20px;
  left: -2000px;
  bottom: 41px;
  color: var(--black);
  transition: left 0.45s cubic-bezier(0.68, -0.55, 0.265, 1.55);
  border-radius: var(--main-border-radius);
}

.appear {
  left: 0px;
}

.input {
  height: 50px;
  width: 50%;
  margin: 10px;
  padding: 5px 0 5px 20px;
  font-size: 20px;
  font-weight: 300;
  border: 0px solid var(--black);
  border-radius: var(--main-border-radius);
}

.left {
  float: left;
  margin: 20px 0 0 0px;
}

.right {
  float: right;
  margin: 24px 0 0 0;
  color: #b4b4b4;
  /*     display: none; */
}

.right:visited {
  display: none;
}

.plusButton {
  position: absolute;
  right: 30px;
  bottom: 65px;
  height: 70px;
  width: 70px;
  background-color: var(--red);
  border-radius: 50%;
}

.plusButton:active {
  background-color: var(--red-pressed);
}

.plusIcon {
  position: absolute;
  width: 20px;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  margin: auto;
}

.appear {
  animation-name: appear;
  animation-duration: 0.5s;
  animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.followMe {
  width: 60px;
  position: absolute;
  top: 50%;
  margin: 20px;
  z-index: 0;
}

.icon {
  margin: 10px;
  display: inline-block;
  color: var(--black);
}

@keyframes hot-air {
  0% {
  }
  50% {
    top: 30%;
  }
  100% {
  }
}

@keyframes cloud {
  from {
    left: -100px;
    visibility: visible;
  }
  to {
    left: 100vw;
    visibility: hidden;
  }
}

@keyframes disappear {
  0% {
    right: 0;
    border-radius: var(--main-border-radius);
    background-color: var(--black);
    border: 0;
  }
  25% {
    background-color: var(--red);
    border-radius: var(--main-border-radius);
    color: var(--red);
    border: 0;
  }
  100% {
    right: -150vw;
    background-color: var(--red);
    border-radius: var(--main-border-radius);
    color: var(--red);
    border: 0;
  }
}

@keyframes appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@media (max-width: 400px) {
  :root {
    --height: 100%;
    --width: 100%;
  }

  .card {
    z-index: 99;
  }
}

            
          
!
            
              const HotAir = () => {
  return (
    <div>
      <svg className="hot-air" width="50" viewBox="0 0 84 126" fill="none">
        <path
          d="M75.1224 32.5435C75.1224 53.4471 58.3042 88.0945 37.5602 88.0945C16.8162 88.0945 -1.35462e-07 53.4471 -1.35462e-07 32.5435C-1.35462e-07 11.6379 16.8162 1.85674e-07 37.5602 1.85674e-07C58.3042 1.85674e-07 75.1224 11.6379 75.1224 32.5435Z"
          transform="translate(8.87762 6.95734)"
          fill="#E56A77"
        />
        <path
          d="M34.3288 11.3081C34.3288 16.2847 30.3259 19.8805 25.388 19.8805H13.5196C8.5817 19.8805 4.5769 16.2847 4.5769 11.3081L-8.1277e-07 7.27537e-07H38.9076L34.3288 11.3081Z"
          transform="translate(26.6032 106.12)"
          fill="#EDC951"
        />
        <path
          d="M40.5194 94.0565C18.1518 94.0565 -1.35462e-07 58.6383 -1.35462e-07 35.5235C-1.35462e-07 14.2761 16.2835 0 40.5194 0C64.7553 0 81.0408 14.2761 81.0408 35.5235C81.0408 58.6383 62.8871 94.0565 40.5194 94.0565ZM40.5194 5.96396C23.2949 5.96396 5.91841 15.1046 5.91841 35.5235C5.91841 55.3285 22.0895 88.0925 40.5194 88.0925C58.9493 88.0925 75.1224 55.3285 75.1224 35.5235C75.1224 15.1046 57.742 5.96396 40.5194 5.96396Z"
          fill="black"
        />
        <path
          d="M28.3465 25.8465H16.4781C10.0211 25.8465 4.91744 21.0944 4.59193 14.9159L0.218222 4.10841C-0.152665 3.18859 -0.0461315 2.14361 0.502308 1.31914C1.05075 0.494678 1.97204 -3.57706e-06 2.95845 -3.57706e-06H41.8661C42.8525 -3.57706e-06 43.7738 0.494678 44.3222 1.31914C44.8707 2.14361 44.9772 3.18859 44.6043 4.10841L40.2326 14.9159C39.9071 21.0944 34.8034 25.8465 28.3465 25.8465ZM7.36174 5.96396L10.2756 13.1636C10.4196 13.5212 10.4946 13.9046 10.4946 14.2901C10.4946 17.4786 13.0671 19.8805 16.4781 19.8805H28.3465C31.7574 19.8805 34.33 17.4786 34.33 14.2901C34.33 13.9046 34.4049 13.5212 34.5489 13.1636L37.4628 5.96396H7.36174Z"
          transform="translate(17.7264 98.1669)"
          fill="black"
        />
        <path
          d="M30.5785 5.96395H2.9592C1.32572 5.96395 -8.72975e-07 4.62892 -8.72975e-07 2.98198C-8.72975e-07 1.33305 1.32572 -1.45507e-06 2.9592 -1.45507e-06H30.5785C32.2119 -1.45507e-06 33.5377 1.33305 33.5377 2.98198C33.5377 4.62892 32.2119 5.96395 30.5785 5.96395Z"
          transform="translate(22.4249 110.097)"
          fill="black"
        />
        <path
          d="M2.96042 47.9719C1.86355 47.9719 0.810072 47.3521 0.297143 46.2912C-0.415039 44.8091 0.196527 43.0251 1.66627 42.3059C13.144 36.6897 22.3846 16.2012 22.3846 2.98198C22.3846 1.33305 23.7104 5.45653e-07 25.3439 5.45653e-07C26.9773 5.45653e-07 28.3031 1.33305 28.3031 2.98198C28.3031 18.5216 18.0169 40.9351 4.25261 47.6699C3.83635 47.8746 3.39444 47.9719 2.96042 47.9719Z"
          transform="translate(37.0086 44.3264)"
          fill="black"
        />
        <path
          d="M25.3426 47.9719C24.9086 47.9719 24.4667 47.8746 24.0524 47.6699C10.2862 40.9351 -4.51539e-07 18.5216 -4.51539e-07 2.98198C-4.51539e-07 1.33305 1.32572 5.45653e-07 2.9592 5.45653e-07C4.59269 5.45653e-07 5.91841 1.33305 5.91841 2.98198C5.91841 16.2012 15.161 36.6897 26.6368 42.3059C28.1065 43.0251 28.7201 44.8091 28.0059 46.2912C27.495 47.3521 26.4395 47.9719 25.3426 47.9719Z"
          transform="translate(16.4098 44.3264)"
          fill="black"
        />
      </svg>
    </div>
  );
};

class Button extends React.Component {
  render() {
    const { onClick, className, children } = this.props;

    return (
      <button className={className} onClick={onClick} type="button">
        {children}
      </button>
    );
  }
}

class Sky extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: []
    };
  }
  Cloud = () => {
    // var random = Math.random();
    var top = Math.floor(Math.random() * 65 - 15) + "%";
    var dim = Math.floor((Math.random() + 0.3) * 80) + "px";
    var index = Math.round(Math.random() * 2);
    var velocity = Math.floor(Math.random() * 5 * 10) + "s";
    console.log(top, dim, index, velocity);
    var cloudStyle = {
      top: top,
      height: dim,
      zIndex: index,
      animationDuration: velocity,
      animationTimingFunction: "linear",
      animationName: "cloud",
      animationDelay: "0",
      position: "absolute",
      padding: "0",
      margin: "0",
      left: "-100px",
      visibility: "hidden"
    };

    this.setState({ data: [...this.state.data, cloudStyle] });
  };
  componentDidMount() {
    this.Cloud();
    setInterval(() => this.Cloud(), 5000); //cloud density
  }
  render() {
    // console.log(this.state.data);
    return this.state.data.map((e, i) => {
      return (
        <div style={e} key={i}>
          <svg height={e.height} viewBox="0 0 196 126" fill="none">
            <g id="cloud">
              <ellipse
                id="Ellipse 2"
                cx="44.5"
                cy="56"
                rx="44.5"
                ry="56"
                transform="translate(78 7)"
                fill="white"
              />
              <circle
                id="Ellipse 2.1"
                cx="42"
                cy="42"
                r="42"
                transform="translate(40 35)"
                fill="white"
              />
              <ellipse
                id="Ellipse 2.2"
                cx="33"
                cy="31.5"
                rx="33"
                ry="31.5"
                transform="translate(122 58)"
                fill="white"
              />
              <ellipse
                id="Ellipse 2.3"
                cx="33"
                cy="31.5"
                rx="33"
                ry="31.5"
                transform="translate(7 56)"
                fill="white"
              />
              <g id="cloud_2">
                <g id="Group">
                  <path
                    id="Vector"
                    d="M122.5 12.6C142.621 12.6 159.011 29.31 159.25 49.9326C159.154 50.6957 159.082 51.4584 159.059 52.2459L158.748 61.499L167.265 64.5506C177.123 68.0817 183.75 77.5932 183.75 88.2C183.75 102.104 172.768 113.4 159.25 113.4H36.75C23.244 113.4 12.25 102.104 12.25 88.2C12.25 74.4432 23.0407 63.2213 36.3672 63C36.9414 63.0862 37.5397 63.1599 38.1377 63.1969L47.445 63.8245L50.5075 54.7805C53.9528 44.617 63.1882 37.8 73.5 37.8C74.6963 37.8 76.0124 37.9477 77.7829 38.2678L86.3602 39.855L90.6309 32.0414C97.1865 20.0568 109.389 12.6 122.5 12.6ZM122.5 0C104.149 0 88.3458 10.5084 79.9481 25.8647C77.8545 25.4831 75.713 25.2 73.5 25.2C57.4456 25.2 43.9396 35.8561 38.9393 50.6217C38.2097 50.5725 37.5038 50.4 36.75 50.4C16.4609 50.4 0 67.3312 0 88.2C0 109.069 16.4609 126 36.75 126H159.25C179.539 126 196 109.069 196 88.2C196 71.6869 185.64 57.7828 171.285 52.6393C171.309 51.8766 171.5 51.1631 171.5 50.4C171.5 22.567 149.56 0 122.5 0Z"
                    fill="#292929"
                  />
                </g>
              </g>
            </g>
          </svg>
        </div>
      );
    });
  }
}

const init = [
  {
    value: "Don't",
    // style: {}
  },
  {
    value: "forget",
    // style: {}
  },
  {
    value: "to like (:",
    // style: {}
  }
];

class ToDo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      init: init,
      adder: false,
      value: ""
    };

    this.handleText = this.handleText.bind(this);
    this.remove = this.remove.bind(this);
    this.add = this.add.bind(this);
  }

  handleText(text) {
    this.setState({
      todo: {
        value: text.target.value,
        time: this.state.time
      },
      value: text.target.value
    });
  }

  remove(el) {
    el.style = {
      animationName: "disappear",
      animationDuration: ".6s",
      animationTimingFunction: "cubic-bezier(.53,-0.17,.91,-0.2)"
    };
    this.setState(this.state);
    const update = this.state.init.filter(e => {
      console.log(e !== el);
      return e !== el;
    });
    setTimeout(() => {
      this.setState({ init: update });
    }, 600);
  }

  add(e) {
    e.preventDefault();
    e.stopPropagation();

    var todo = [this.state.todo];
    todo.push(...this.state.init);
    console.log(todo);
    this.setState({
      init: todo,
      adder: false,
      value: "",
      time: ""
    });
  }

  showAdder() {
    this.setState({ adder: true });
  }

  render() {
    return (
      <div>
        <div className="todo">
          {/* <h1>Tasks:</h1> */}
          {this.state.init.map((e, i) => {
            return (
              <div style={e.style} className="task" key={i}>
                <div className="content">
                  <div className="left">{e.value}</div>
                </div>
                <button onClick={() => this.remove(e)} className="right">
                  ×
                </button>
              </div>
            );
          })}
        </div>
        <div className="addControls">
          <form
            className={this.state.adder ? "appear form" : "form"}
            onKeyDown={e =>
              e.keyCode == 13 ? this.add(e) : console.log("please press enter")
            }
          >
            <input
              onChange={this.handleText}
              className="input shadow"
              type="text"
              value={this.state.value}
              placeholder="Type your task..."
            />
            <button onClick={e => this.add(e)} type="button">
              add
            </button>
          </form>
          <button
            onClick={() => this.showAdder()}
            className="plusButton shadow"
          >
             <svg className="plusIcon" width="38" height="38" viewBox="0 0 38 38" fill="none">
              <g id="+">
              <path id="Stroke 112" d="M0 0H32.6733" transform="translate(2.97028 18.3466)"       stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
              <path id="Stroke 113" d="M0 0V32.6733" transform="translate(18.6534 2.66339)" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
              </g>
            </svg>

          </button>
        </div>
      </div>
    );
  }
}

class Card extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: true
    };
    this.switchToTasks = this.switchToTasks.bind(this);
  }
  switchToTasks() {
    this.setState({ data: false });
  }
  render() {
    const { data } = this.state;
    return (
      <div className="card shadow gradient">
        <div className={data ? "" : "none"}>
          <HotAir />
          <div className="start">
            <div className="text">
              <h1>Your day’s still empty...</h1>
              <p>Put in some tasks and make your day!</p>
            </div>
            <Button
              className="add shadow"
              onClick={() => {
                this.switchToTasks();
              }}
            >
              Add
            </Button>
          </div>
        </div>
        <div className={!data ? "appear" : "none"}>
          <ToDo />
        </div>
      </div>
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <Sky />
        <div className="container">
          <Card />
          <div className="followMe">
            <a className="icon" href="https://github.com/lucagez/react-cloudy-todo-list" target="_blank"><i className="fab fa-github fa-3x"></i></a>
            <a className="icon" href="https://codepen.io/lucagez" target="_blank"><i className="fab fa-codepen fa-3x"></i></a>
          </div>
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.querySelector("#root"));

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console