💨

Tailwind CSS+daisy UIを触ってみた!

2022/03/25に公開

概要

勉強がてらにTailwind CSSとdaisy UIを触ってみました。
実際に、ローカルに環境を入れずとも、ウェブで手軽に触れることができたので、そちらの方を利用して触ってみました。

https://daisyui.com/docs/install/

Reactだけでなく、Next.jsやVueなど様々環境が容易されているので、簡単に触ることができますので、ぜひ触ってみてください。

使い方

今回react+Create React AppでTailwind CSS + daisy UIを触ってみます。

このページを開くと、ウェブエディターが開きます。

src/app.jsにTailwindCSSやdaisyUIを記述することができ、気軽試すことができます。

右側に、実装したウェブページが表示されます。もちろんホットリロードが効き、編集後即時反映されるのも便利です。

app.js
import React from 'react';

const App = (props) => {
  return (
    <div>
      <button className="btn">Hello daisyUI</button>
    </div>
  );
};
export default App;

materi-UIの記述と比較

ヘッダー部分を作成し、比較してみます。まずは、materil-uiからです。

  • material-UI

materilHeader.tsx
// 記述が厳密ではありませんがご両所ください。。

function Header() {
  const classes = useStyles();
  const accountMenuAnchorRef = useRef < HTMLButtonElement > null;
  const menuItems = [
    {
      onClick: () => {},
      label: 'アカウント情報',
    },
    {
      onClick: () => {},
      label: 'お気に入り一覧',
    },
  ];
  
  return (
    <AppBar position="fixed" className={classes.menuBar}>
      <Toolbar className={classes.toolbar}>
        <img
          alt="logo"
          src={logo}
          onClick={() => {}}
          className={classes.siteLogo}
          onKeyPress={() => {}}
          role="presentation"
        />
        <div className={classes.menus}>
          <IconButton
            reference={accountMenuAnchorRef}
            onClick={toggleAccountMenu}
            icon={<PersonIcon />}
            label="アカウント"
          />
          <Popper
            open={openMenu}
            anchorEl={accountMenuAnchorRef?.current}
            role={undefined}
            transition
            disablePortal
          >
            {({ TransitionProps }) => (
              <Grow
                in={TransitionProps?.in}
                onEnter={TransitionProps?.onEnter}
                onExited={TransitionProps?.onExited}
              >
                <Paper>
                  <ClickAwayListener onClickAway={closeMenu}>
                    <MenuList autoFocusItem={openMenu} onKeyDown={handleListKeyDown}>
                      {menuItems.map((item) => (
                        <MenuItem key={item.label} onClick={() => {}}>
                          {item.label}
                        </MenuItem>
                      ))}
                    </MenuList>
                  </ClickAwayListener>
                </Paper>
              </Grow>
            )}
          </Popper>
          <IconButton
            onClick={() => {}}
            icon={<PhotoCameraIcon />}
            label="出品"
          />
          <IconButton
            onClick={() => {}}
            icon={<ExitToAppIcon />}
            label="サインアウト"
          />
        </div>
      </Toolbar>
    </AppBar>
  );
}

// スタイル設定
export const useStyles = makeStyles({
  menuBar: {
    backgroundColor: '#fff',
    color: '#444',
  },
  toolbar: {
    padding: 0,
    margin: '0 auto',
    maxWidth: 1024,
    width: '100%',
  },
  menus: {
    margin: '0 0 0 auto',
  },
  siteLogo: {
    width: '66.8px',
    height: '66.8px',
  },
});
  • daisy-UI, TailwindCSS

sample.jsx
import React from 'react';
import './app.css';

const Header = (props) => {
  return (
    <div className="max-w-5xl w-full mx-auto my-0">
      <div className="navbar text-white bg-black bg-base-100">
        <div className="flex-1">
          <img
            className="btn w-16 h-16"
            src="https://api.lorem.space/image/shoes?w=400&h=225"
            alt="Shoes"
          />
        </div>
        <div className="flex-none">
          <ul className="menu menu-horizontal p-0">
            <li tabIndex="0">
              <a>
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-5 w-5"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth="2"
                    d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
                  />
                </svg>
                アカウント
              </a>
              <ul className="p-2  bg-base-100">
                <li>
                  <a onClick={() => {alert("hoge")}}>アカウント情報</a>
                </li>
                <li>
                  <a onClick={()=>{}}>お気に入り登録</a>
                </li>
              </ul>
            </li>
            <li>
              <a>
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-6 w-6"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  strokeWidth={2}
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"
                  />
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"
                  />
                </svg>
                出品
              </a>
            </li>
            <li>
              <a onClick={()=>{}}>
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-5 w-5"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                >
                  <path
                    fillRule="evenodd"
                    d="M3 3a1 1 0 00-1 1v12a1 1 0 102 0V4a1 1 0 00-1-1zm10.293 9.293a1 1 0 001.414 1.414l3-3a1 1 0 000-1.414l-3-3a1 1 0 10-1.414 1.414L14.586 9H7a1 1 0 100 2h7.586l-1.293 1.293z"
                    clipRule="evenodd"
                  />
                </svg>
                サインアウト
              </a>
            </li>
          </ul>
        </div>
      </div>
    </div>
  );
};
export default Header;

少し、daisy UI + Tailwind CSSの方がすっきりしているように見えますね。(SVGのところはゴチャゴチャしてますが。。)

実装した感じでは、Material-UIを利用した時は、メニュー、アイコン部分などを細かく指定する必要があり、少しコード量が増えてしまっていると思います。

しかし、Tailwind CSSでは、メニューも細かくコンポーネントを構成してあげる必要がないため、比較的簡単に実装することができました。

なんと言っても、CSSのためのクラス名を記述する部分が亡くなっていることが大きいです!クラス名を考える必要もなく、その分コード量も少なくなりました。

ただ、materil UIもごちゃこちゃしているとはゆっても、しっかり細かくコンポーネント化することで、分かりやすいコードになると思うので、そこを設計をしっかりすれば、手軽でいいライブラリであるとは思います!

  • カスタマイズ性

Tailwind CSSでは、細かいCSSを組み合わせて、スタイルを指定できるので、カスタマイズ性高いです。materil UIでもできますが、別途関数を用意してあげる必要があるのでちょっとていう感じです。

アイコンについて

material UIでは、UIコンポーネントが用意されています。

daisy UIは、用意されていません。ただし、svgを埋め込むことができます。公式では、その1つの手段として、heroiconsが紹介されており、そちらを利用するのがいいかなと思います。

好きなアイコンを選んで、JSXをコピーと選択して、それを貼り付けるだけで、アイコンを利用することができます。

それを自身のプロジェクト内でコンポーネント化して利用すれば、いいのかなって思っています。

<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
  <path strokeLinecap="round" strokeLinejoin="round" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z" />
</svg>

特徴

  • 軽量

JvaaScriptを利用しないため、動作が軽量です。また、purgeCSSを利用すると余分なCSSを省くことができるので、容量も軽量になる点は優れています。
また、CSSを記述するコード量も少なくなるので自信が記述するソースコード自体も軽量になるでしょう!

使ってみた感想

使ってみた感想ですが、初回の学習コストは少し高めかなっって思いました。daisy UI, Tailwindも使ったことない人は、このクラス名はdaisy UI? Tailwind CSS?ってなり双方のサイトから探すことになるので、少し大変かなって思いました。

また、JavaScriptで制御したい時、少し大変です。たとえば、モーダルをエラーによりスクリプトより表示させたいとなるとクラスを追加する必要があるので、少しやり方を考える必要がありそうです。
materil UIなどは、フラグによってスクリプトから簡単に直感的に制御できるのでその点は優れています。
何かいい方法あれば、教えていただきたいです。

書き方に関しては慣れれば、全然使いやすくなると思うので、ちょこちょこ触っていこうかなと思います。

最後に

何か間違っている内容、アドバイスあれば、よろしくお願いします!

GitHubで編集を提案

Discussion