beginn to learn tailwindcss

This commit is contained in:
Michi 2025-04-19 10:16:01 +02:00
parent 6d6dd37f72
commit 968a0b7de9
6 changed files with 180 additions and 103 deletions

121
README.md
View file

@ -1,9 +1,7 @@
# Next.js # Next.js
A place for me to learn Next.js A place for me to learn Next.js
Official Next.js docs: https://nextjs.org/docs/app/getting-started/installation > Next.js is developed & maintained by Vercel
Next.js is developed & maintained by Vercel
## Installation (macOS) ## Installation (macOS)
Requirements: Requirements:
@ -39,6 +37,11 @@ npx create-next-app@latest
Afterwards some questions about the project will be asked. Afterwards some questions about the project will be asked.
You can leave the settings as default. You can leave the settings as default.
## Upgrade to newer Next.js version
```zsh
npx @next/codemod@canary upgrade latest
```
## Run development server ## Run development server
```zsh ```zsh
npm run dev npm run dev
@ -76,8 +79,114 @@ The main function of the app or just a file is defined by `export default`.
The layout of the app is defined in `layout.js`. The content of `layout.js` is shared between all pages. The layout of the app is defined in `layout.js`. The content of `layout.js` is shared between all pages.
## Styling
In `global.css` some global CSS styling rules were defined. Usally this file is imported in the root layout of the app `layout.js`/`layout.jsx`/`layout.tsx`.
## Upgrade to newer Next.js version Commonly TailwindCSS is used with Next.js for easier stylings. This can be recognized in the beginning of the `global.css`-File:
```zsh ```css
npx @next/codemod@canary upgrade latest @tailwind base;
@tailwind components;
@tailwind utilities;
``` ```
As an alternative to TailwindCSS also CSS modules can be used for styling. There you would create a own CSS file for every component which needs styling and only import those into the project. More details about that can be found in the [Next.js docs](https://nextjs.org/learn/dashboard-app/css-styling).
Additionaly there are other, less popular methods for styling your Next.js app like Sass or CSS-in-JS libraries. And, because in the end just normal CSS is rendered, you can use any styling solution you want/already know too with Next.js.
### TailwindCSS
Tailwind is a CSS framework, which enables you to style the whole website without ever leaving the HTML or Next.js code. You never have to touch a CSS file. All styling is done via predefined CSS classes.
When using VScode as Editor the [`Tailwind CSS IntelliSense`](https://marketplace.visualstudio.com/items/?itemName=bradlc.vscode-tailwindcss) should be installed. It enables autofill for Tailwind css classes aund adds preview of the css behind a class when hovering over it. It improves the development process with TailwindCSS a lot.
The styling is applied when adding a css class to an HTML object.
```jsx
<div className="fixed top-0"></div>
```
When non existing tailwind class matches the value you need, a custom value can be assigend, which will automatically be generated by tailwind on build.
```jsx
<div className="top-[-27px]"></div>
```
#### Common classes
| class | what it does |
| --- | --- |
| top-0 | top: 0; |
| left-0 | left: 0; |
| w-0 | width |
| h-0 | height |
| m-0 | margin |
| mx-auto | margin-inline: auto; |
| p-0 | padding |
| flex | display: flex; |
| h-screen | 100vh; -> viewport height |
| bg-gray-900 | background-color |
| text-white | text color |
| shadow-lg | adds a nice shadow (different variantes are available) |
| rounded-3xl | border-radius |
| transition-all | add a transition to every property that changes |
| hover:<CLASS> | Adds class on hover state |
| group | defines a parent element for a group |
| group-hover:<CLASS> | adds a class on hover over the parent of the group |
| dark:<CLASS> | only apply styling in dark mode |
Tailwind uses a custom spacing scale. The translation table can be found [here](https://gist.github.com/crswll/5d91b14373f53d66317e407bbba6d3dd).
To specify a hover state in tailwind just add a prefix of `hover:` in front of the styling class.
```jsx
<div className="hover:bg-green-600 hover:text-white"></div>
```
When having a lot of styling on a element it can make sense to create a custom css class combining thoose tailwind classes. This can be done by adding the following to `globals.css`:
```css
@layer components{
.sidebar-icon{
@apply relative flex items-center justify-center
h-12 w-12 mt-2 mb-2 mx-auto shadow-lg
bg-gray-800 text-green-400
hover:bg-green-600 hover:text-white;
}
/* more custom classes... */
}
```
With `@apply` other css classes can be applied to an element.
With a group in tailwind its possible to change the state of an child based on the parent like on hover over the parent. But groups don't work when using `@apply` in css.
The class `group` has to be added to the parent element. Then a connected hover action can be added to the child via `group-hover:<CLASS>`.
Example:
```jsx
<div className="sidebar-icon group">
{icon}
<span className="sidebar-tooltip group-hover:scale-100">
{text}
</span>
</div>
```
### Clsx
`clsx` is a library which adds the possibility to toggle css classes based on JS conditions. This is useful to change a styling depending on the value of a state.
## React Icons
React Icons is a easy way to import the most popular icons into a react project.
It can be installed via npm.
```zsh
npm install react-icons --save
```
Now the icons can be used after importing them. Each icon is a custom react component.
```jsx
import { FaPlay } from "react-icons/fa";
<FaPlay />
```
## Ressources
- [Next.js Installation](https://nextjs.org/docs/app/getting-started/installation)
- [Next.js React Foundations Course](https://nextjs.org/learn/react-foundations)
- [Next.js Dashboard App Course](https://nextjs.org/learn/dashboard-app)
- [Tailwind in 100 Seconds](https://youtu.be/mr15Xzb1Ook)
- [Ultimate Tailwind CSS Tutorial // Build a Discord-inspired Animated Navbar](https://youtu.be/pfaSUYaSgRo)

View file

@ -16,6 +16,7 @@
"next": "15.3.0", "next": "15.3.0",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-icons": "^5.5.0",
"tailwind-merge": "^3.2.0", "tailwind-merge": "^3.2.0",
"tw-animate-css": "^1.2.5" "tw-animate-css": "^1.2.5"
}, },
@ -1501,6 +1502,15 @@
"react": "^19.1.0" "react": "^19.1.0"
} }
}, },
"node_modules/react-icons": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
"license": "MIT",
"peerDependencies": {
"react": "*"
}
},
"node_modules/scheduler": { "node_modules/scheduler": {
"version": "0.26.0", "version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",

View file

@ -17,6 +17,7 @@
"next": "15.3.0", "next": "15.3.0",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-icons": "^5.5.0",
"tailwind-merge": "^3.2.0", "tailwind-merge": "^3.2.0",
"tw-animate-css": "^1.2.5" "tw-animate-css": "^1.2.5"
}, },

View file

@ -120,3 +120,24 @@
@apply bg-background text-foreground; @apply bg-background text-foreground;
} }
} }
@layer components{
.sidebar-icon{
@apply relative flex items-center justify-center
h-12 w-12 mt-2 mb-2 mx-auto shadow-lg
bg-gray-800 text-green-400
hover:bg-green-600 hover:text-white
rounded-3xl hover:rounded-xl
transition-all duration-300 ease-linear
cursor-pointer;
}
.sidebar-tooltip{
@apply absolute w-auto p-2 m-2 min-w-max left-14
rounded-md shadow-md
text-white bg-gray-900
text-xs font-bold
transition-all duration-100 scale-0 origin-left;
}
}

View file

@ -1,103 +1,9 @@
import Image from "next/image"; import SideBar from '@/components/SideBar'
export default function Home() { export default function Home() {
return ( return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]"> <div className="flex">
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start"> <SideBar />
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
<li className="mb-2 tracking-[-.01em]">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-[family-name:var(--font-geist-mono)] font-semibold">
src/app/page.tsx
</code>
.
</li>
<li className="tracking-[-.01em]">
Save and see your changes instantly.
</li>
</ol>
<div className="flex gap-4 items-center flex-col sm:flex-row">
<a
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
</a>
<a
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Read our docs
</a>
</div>
</main>
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org
</a>
</footer>
</div> </div>
); );
} }

View file

@ -0,0 +1,30 @@
import { BsPlus, BsFillLightningFill, BsGearFill } from 'react-icons/bs';
import { FaFire, FaPoo } from 'react-icons/fa';
function SideBar(){
return (
<div className="fixed top-0 left-0 h-screen w-16 m-0
flex flex-col
bg-gray-100 text-gray-900 shadow-lg
dark:bg-gray-900 dark:text-white">
<SideBarIcon icon={<FaFire size="28" />} />
<SideBarIcon icon={<BsPlus size="32" />} />
<SideBarIcon icon={<BsFillLightningFill size="20" />} />
<SideBarIcon icon={<FaPoo size="20" />} />
</div>
);
}
function SideBarIcon({icon, text = 'tooltip'}){
return (
<div className="sidebar-icon group">
{icon}
<span className="sidebar-tooltip group-hover:scale-100">
{text}
</span>
</div>
)
}
export default SideBar;