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

              
                <div id="root"></div>
              
            
!

CSS

              
                @import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&family=Patua+One&display=swap');

.font-Patua {
  font-family: 'Patua One', cursive;
  font-size: 20px;
}

body {
  background-color: #c0a695;
  color: #f9fbf8;
  font-family: 'Open Sans', sans-serif;
}
#root {
  width: 100%;
  display: flex;
  justify-content: center;
}
.main-container {
  background-color: #5b4a42;
}

.item-title {
  color: #c2976c;
}

.item-description {
  color: #d2d0ce;
}

.address,
.item-price {
  background: #51413a;
}
.hero {
  display: flex;
  justify-content: center;
  align-items: center;
  background-image: linear-gradient(
      180deg,
      rgba(34, 34, 34, 0.7) 0%,
      #5b4a42 100%
    ),
    url('https://assets.codepen.io/t-1/nathan-dumlao-6VhPY27jdps-unsplash.jpg');
  height: 500px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: auto 100%;

}
@media (min-width: 640px) {
  .hero {
    justify-content: space-between;
    align-items: flex-end;
    height: 300px;
    background-position: center;
    background-repeat: no-repeat;
    background-size: 100% auto;
  }
}

              
            
!

JS

              
                const data = [
  {
    key: 0,
    title: 'Coffee',
    description: {
      left: {
        text: 'Small : $2',
        image: 'https://assets.codepen.io/3685267/react-cafe-menu-coffee.png',
        scaleDown: true,
      },
      right: {
        text: 'Large : $4',
        image: 'https://assets.codepen.io/3685267/react-cafe-menu-coffee.png',
      },
    },
    list: [
      {
        title: 'House Blend',
        description: 'Smoky, strong, and assertive, just like us.',
      },
      {
        title: 'Organic French Roast',
        description: 'Smooth and mellow with hints of molasses.',
      },
      {
        title: 'Organic Decaf',
        description:
          "Full bodied and rich, we promise you won't miss the caffiene.",
      },
    ],
  },
  {
    key: 1,
    title: 'Tea',
    description: {
      left: {
        text: 'Per Cup : $2',
        image: 'https://assets.codepen.io/3685267/react-cafe-menu-tea.png',
      },
      right: {
        text: '$200 if you break the cup',
        image:
          'https://assets.codepen.io/3685267/react-cafe-menu-tea-broken.png',
      },
      text: 'Served to brave people in our notorious antique tea cups.',
    },
    list: [
      {
        title: 'Earl Grey ',
        description: 'Black tea fragranced with bergamot.',
      },
      {
        title: 'Ginger Hibiscus',
        description: 'Floral, tart, and spicy. Caffeine free.',
      },
      {
        title: 'Cascade Green',
        description:
          'A blend of green teas hand selected by our master teamaker.',
      },
      {
        title: 'Chamomile',
        description:
          'Soothing and slightly sweet. Try it with honey! Caffeine free.',
      },
    ],
  },
  {
    key: 2,
    title: 'Espresso Drinks',
    description: {
      left: {
        text: 'Small : $3',
        image: 'https://assets.codepen.io/3685267/react-cafe-menu-espresso.png',
        scaleDown: true,
      },
      right: {
        text: 'Large : $5',
        image: 'https://assets.codepen.io/3685267/react-cafe-menu-espresso.png',
      },
    },
    list: [
      {
        title: 'Machiatto',
        description:
          'Espressso and steamed milk, served in a demitasse cup. (Size Small Only)',
      },
      {
        title: 'Latte',
        description:
          'Espresso with steamed milk, and sometimes a little art on top. ',
      },
      {
        title: 'Mocha',
        description:
          'Espresso with steamed chocolate milk and whipped cream. Also available with white chocolate milk.',
      },
      {
        title: 'Americano',
        description: '1 shot espresso, two shots hot water.',
      },
    ],
  },

  {
    key: 3,
    title: 'From the Bakery',
    description: {
      left: {
        text: 'Cookies : $2',
        image: 'https://assets.codepen.io/3685267/react-cafe-menu-cookie.png',
      },
      right: {
        text: 'Muffins & Pastries : $3',
        image: 'https://assets.codepen.io/3685267/react-cafe-menu-muffin.png',
      },
    },
    list: [
      {
        title: "Mallory's Famous Snickerdoodles",
        description:
          "Creamy cinnamony goodness made from scratch with our founder Mallory's prizewinning recipe.",
      },
      {
        title: 'Oatmeal Cookie',
        description:
          'Packed with rolled oats, raisins, and cranberries, these monster cookies are (almost) good for ya!',
      },
      {
        title: 'Mixed Berry Muffins',
        description:
          'Filled with the best berries of the season and topped with a crumb crust.',
      },
      {
        title: 'Croissant',
        description:
          'Our oversized croissants are buttery, flaky, and usually all sold out by 7 a.m.',
      },
    ],
  },
];

const title = 'The Cascade Cafe'.split('');
const est = 'Est - 1896'.split('');

est.reverse();

function App() {
  return (
    <div className="py-0 sm:py-10 max-w-screen-lg">
      <div className=" main-container rounded-none sm:rounded overflow-hidden">
        <div className="hero flex-col sm:flex-row">
          <Header />
          <Hours />
        </div>
        <div className="flex flex-wrap">
          {data.map((item, index) => (
            <MenuSection key={item.key} item={item} index={index} />
          ))}
        </div>
        <Address />
      </div>
    </div>
  );
}

function Header() {
  return (
    <div
      className=""
      style={{ width: '300px', height: '300px', position: 'relative' }}
    >
      {title.map((i, index) => (
        <div
          key={index}
          className="flex justify-center font-Patua"
          style={{
            position: 'absolute',
            height: '205px',
            width: '40px',
            left: '50%',
            top: '50%',
            transform: `translate(-50%, -50%) rotate(${
              index * 10 - ((title.length - 1) * 10) / 2
            }deg)`,
          }}
        >
          {i}
        </div>
      ))}
      {est.map((i, index) => (
        <div
          key={index}
          className="flex justify-center items-end font-Patua"
          style={{
            position: 'absolute',
            height: '205px',
            width: '40px',
            left: '50%',
            top: '50%',
            transform: `translate(-50%, -50%) rotate(${
              index * 10 - ((est.length - 1) * 10) / 2
            }deg)`,
          }}
        >
          {i}
        </div>
      ))}
      <div
        className=""
        style={{
          position: 'absolute',
          left: '50%',
          top: '50%',
          transform: 'translate(-50%, -50%)',
          border: '4px solid #fff',
          width: '220px',
          height: '220px',
          borderRadius: '999px',
        }}
      />
      <div
        className=""
        style={{
          position: 'absolute',
          left: '50%',
          top: '50%',
          transform: 'translate(-50%, -50%)',
          border: '2px solid #fff',
          width: '140px',
          height: '140px',
          borderRadius: '999px',
        }}
      />
      <div
        className=""
        style={{
          position: 'absolute',
          left: '50%',
          top: '50%',
          transform: 'translate(-50%, -50%)',
          width: '120px',
          height: '120px',
          borderRadius: '999px',
        }}
      >
        <svg
          width="100%"
          height="100%"
          viewBox="0 0 252 252"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d="M125.51 0C56.74 0 1 56.31 1 125.78C1 195.25 56.74 251.56 125.51 251.56C194.28 251.56 250.02 195.25 250.02 125.78C250.02 56.31 194.28 0 125.51 0ZM114.45 24.78C118.24 25.85 120.99 30.64 124.17 33.78H124.24C127.42 30.65 130.17 25.86 133.96 24.78C138.15 23.59 143.47 34.18 140.74 39.97C136.65 48.68 131.31 56.88 125.54 66.57C125.18 67.43 124.81 68.29 124.43 69.19L124.21 68.81L123.98 69.19C123.6 68.29 123.24 67.43 122.87 66.57C117.11 56.88 111.76 48.68 107.67 39.97C104.94 34.18 110.26 23.59 114.45 24.78V24.78ZM108.59 55.26L125.34 81.56L142.14 52.22C151.97 75.84 128.14 85.63 125.35 102.98C109.29 87.23 101.65 66.31 108.59 55.26ZM98.5 77.45L124.64 122.15C132.06 107.29 140.57 90.23 149.13 73.06C156.91 84.8 155.75 107.34 146.54 116.8C139.67 123.85 132.24 130.33 125.54 136.66C117.69 129.72 109.47 122.73 101.54 115.39C91.35 105.99 90.04 90.03 98.5 77.45ZM105.94 132.59C114.94 139.02 119.42 148.21 121.08 159.04C115.37 146.58 106.5 137.85 92.38 134.68L116.6 160.68C91.91 149.38 74.6 132.54 74.6 102.97C80.31 118.32 94.25 124.2 105.94 132.59V132.59ZM57.48 124.59C60.48 129.17 62.79 132.48 64.93 135.88C72.93 148.59 84.57 155.28 98.93 158.68C113.86 162.23 122.02 171.91 123.39 187.82C118.6 175.65 109.68 172.39 100.27 169.65C91.43 167.04 82.72 164 73.34 160.95C78.61 171.02 87.49 175.36 97.24 178.74C103.07 180.74 109.47 182.42 114.17 186.12C118.87 189.82 121.76 195.85 124.17 202.03C116.17 189.71 103.51 187.03 90.96 183.72C63.06 176.34 48.56 151.42 57.48 124.59V124.59ZM121.41 232.59C113.19 227.31 105.47 220.99 96.75 216.78C86.44 211.78 74.95 209.34 64.57 204.47C44.38 195.01 32.57 170.41 38.22 148.72C38.6991 146.73 39.547 144.847 40.72 143.17C45.67 169.99 64.12 180.68 87.43 186.17C99.77 189.08 110.98 194.61 118.97 205.08C121.526 208.451 122.901 212.57 122.88 216.8C120.99 214.8 119.42 212.21 117.15 210.8C109.08 205.8 101.79 197.96 92.48 196.52C79.3653 194.211 66.9422 188.967 56.14 181.18C60.14 188.07 60.39 189.33 68.82 197.53C75.68 204.2 83.5 203.53 92.71 206.29C106.19 210.36 118.79 215.22 124.28 230.04C124.68 231.1 126.1 231.78 126.19 234.55C124.541 234.067 122.941 233.431 121.41 232.65V232.59ZM139.73 130.59C150.48 120.02 163.95 111.7 167.37 94.94C172.11 125.48 156.88 145.67 133.16 161.34L154.07 130.65C139.98 136.21 132.21 146.65 128.28 160.46C128.27 148.96 131.5 138.73 139.73 130.65V130.59ZM152.47 163.01C138.85 166.93 139.91 168.69 132.04 179.85C131.84 179.75 131.64 179.67 131.44 179.59C134.01 174.4 136.52 169.17 140.19 164.96C145.63 158.71 153.4 154.59 159.67 148.96C169.47 140.21 178.86 130.96 187.98 122.4C192.98 132.54 189.73 152.51 177.72 163.28C168.81 171.28 157.83 176.92 147.67 183.44C141.99 187.08 136.2 190.44 130.59 193.82C130.777 191.345 131.669 188.975 133.16 186.99C139.08 180.93 142.48 174.15 148.84 171.48C155.84 168.54 163.94 160.78 169.21 155.31C168.52 154.76 160.14 160.44 152.47 163.06V163.01ZM213.04 169.39C209.48 184.69 198.94 194.39 185.77 201.18C177.77 205.29 169.11 208.08 160.63 211.18C151.71 214.42 142.63 217.3 131.32 221.18C148.19 202.79 175.32 205.98 189.89 186.58L131.27 211.19C132.76 204.99 138.08 199.8 145.08 196.28C154 191.79 163.21 187.91 172.16 183.5C190.33 174.5 203.02 161.3 204.5 137.02C214.47 147.88 215.64 158.33 213.04 169.44V169.39Z"
            fill="#ffffff"
          />
        </svg>
      </div>
    </div>
  );
}

function Hours() {
  return (
    <div className="pb-4 pr-4">
      <table className="hours justify-self-end">
        <thead>
          <tr>
            <th colSpan="2">Hours</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td className="pr-4">Mon. - Thurs.</td>
            <td>6 a.m. - 9 p.m.</td>
          </tr>
          <tr>
            <td>Fri. - Sat.</td>
            <td>6 a.m. - 11 p.m.</td>
          </tr>
          <tr>
            <td>Sunday</td>
            <td>8 a.m. - 2 p.m.</td>
          </tr>
        </tbody>
      </table>
    </div>
  );
}

function MenuSection({
  item: {
    title: mainTitle,
    list,
    description: {
      left: { text: titleLeft, image: imageLeft, scaleDown },
      right: { text: titleRight, image: imageRight },
      text: subTitle,
    },
  },
  index,
}) {
  return (
    <div
      className={`w-full md:w-1/2 p-6 flex-shrink-0 ${index > 1 && 'mt-16'}`}
    >
      <h2 className="item-title text-2xl font-bold">{mainTitle}</h2>

      <div className="item-price flex justify-between items-center p-2 mt-3 rounded">
        <div className="flex items-center">
          <img
            src={imageLeft}
            alt=""
            className={scaleDown ? 'w-5 h-5' : 'w-8 h-8'}
          />
          <div className="ml-3 text-sm md:text-base">{titleLeft}</div>
        </div>
        <div className="flex items-center">
          <div className="mr-3 text-sm md:text-base">{titleRight}</div>
          <img src={imageRight} alt="" className="w-8 h-8 " />
        </div>
      </div>
      <div className="mt-4">{subTitle}</div>
      <dl>
        {list.map(({ title, description }) => (
          <React.Fragment key={title}>
            <dt className="text-lg font-semibold mt-3">{title}</dt>
            <dd className="description item-description italic">
              <p>{description}</p>
            </dd>
          </React.Fragment>
        ))}
      </dl>
    </div>
  );
}

function Address() {
  return (
    <address className="flex py-3 justify-center mt-6 flex-wrap address">
      <div className="flex">
        <svg
          viewBox="0 0 384 512"
          width="15"
          title="map-marker-alt"
          fill="currentColor"
        >
          <path d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z" />
        </svg>
        <p className="ml-4">123 Main Street &middot; Smalltown, PA</p>
      </div>
      <div className="flex  mt-2 md:mt-0">
        <svg
          viewBox="0 0 512 512"
          width="15"
          title="phone-alt"
          fill="currentColor"
          className="ml-8"
        >
          <path d="M497.39 361.8l-112-48a24 24 0 0 0-28 6.9l-49.6 60.6A370.66 370.66 0 0 1 130.6 204.11l60.6-49.6a23.94 23.94 0 0 0 6.9-28l-48-112A24.16 24.16 0 0 0 122.6.61l-104 24A24 24 0 0 0 0 48c0 256.5 207.9 464 464 464a24 24 0 0 0 23.4-18.6l24-104a24.29 24.29 0 0 0-14.01-27.6z" />
        </svg>
        <a href="4125550100" className="ml-4">
          412-555-0100
        </a>
      </div>
    </address>
  );
}

ReactDOM.render(<App />,
document.getElementById("root"))
              
            
!
999px

Console