Jump to content

Doğuhan ELMA

Administrators
  • Posts

    25
  • Joined

  • Last visited

About Doğuhan ELMA

  • Birthday 11-02-1982

Doğuhan ELMA's Achievements

Contributor

Contributor (5/14)

  • Dedicated
  • Conversation Starter
  • Week One Done
  • One Month Later

Recent Badges

0

Reputation

  1. Doğuhan ELMA

    CSS'te Scrollbar

    1. Scrollbar Anatomisi ve Tarayıcı Davranışı a) Scrollbar Bileşenleri ┌─────────────────────────┐ │ ▲ (up button) │ ← Scrollbar button ├─────────────────────────┤ │ │ ← Track (kanal) │ ████ │ ← Thumb (kaydırıcı) │ │ │ │ ├─────────────────────────┤ │ ▼ (down button) │ └─────────────────────────┘ Bileşenler: Track (Kanal): Scrollbar'ın arka plan alanı Thumb (Kaydırıcı): Hareket eden kısım Buttons: Ok butonları (bazı işletim sistemlerinde) Corner: İki scrollbar'ın kesiştiği köşe b) Scrollbar Türleri /* Klasik (Classic) Scrollbar */ /* - Her zaman görünür - Sabit genişlik (genellikle 15-17px) - Layout'u etkiler */ /* Overlay Scrollbar */ /* - İçerik üzerinde yüzer - Layout'u etkilemez - Kullanılmadığında kaybolur - macOS, mobil cihazlar */ 2. Scrollbar ve Layout İlişkisi a) Scrollbar'ın Layout'a Etkisi <div class="container"> <div class="content">İçerik</div> </div> /* Klasik Scrollbar Davranışı */ .container { width: 500px; height: 300px; overflow: auto; } /* Scrollbar YOKSA: - İçerik alanı: 500px genişlik Scrollbar VARSA (Windows, Linux): - İçerik alanı: ~483px genişlik (scrollbar ~17px) - Scrollbar içerik alanından yer kaplar Scrollbar VARSA (macOS overlay): - İçerik alanı: 500px genişlik - Scrollbar içerik üzerinde yüzer */ b) Scrollbar Width Tespiti /* Scrollbar genişliğini hesaba kat */ .container { width: 500px; padding-right: 20px; /* İçerik için padding */ } /* Scrollbar göründüğünde içerik kayması */ .container { overflow-y: scroll; /* Her zaman göster */ /* veya */ scrollbar-gutter: stable; /* Alan rezerve et */ } 3. Scrollbar ve Relative Birimlerin Hesaplanması a) Viewport Birimleri (vw, vh) /* KRITIK: Viewport birimleri scrollbar'ı DIKKATE ALMAZ */ body { margin: 0; } .full-width { width: 100vw; /* Viewport genişliği */ /* Scrollbar varsa yatay taşma oluşur! */ } /* Problem gösterimi: */ html { overflow-y: scroll; /* Dikey scrollbar var */ } .container { width: 100vw; /* ~1920px (scrollbar dahil) */ /* Ama gerçek alan: ~1903px (scrollbar hariç) */ /* Sonuç: Yatay scrollbar belirir! */ } Çözüm Stratejileri: /* Çözüm 1: 100% kullan (önerilen) */ .full-width { width: 100%; /* Mevcut alanın tamamı */ } /* Çözüm 2: dvw kullan (modern) */ .full-width { width: 100dvw; /* Dynamic viewport width */ /* Scrollbar'ı dikkate alır */ } /* Çözüm 3: scrollbar-gutter */ html { overflow-y: scroll; scrollbar-gutter: stable; } .full-width { width: 100vw; /* scrollbar-gutter alanı rezerve ettiği için sorun yok */ } /* Çözüm 4: calc ile manuel düzeltme */ .full-width { width: calc(100vw - 20px); } b) Percentage (%) Birimleri /* Parent container'a göre hesaplama */ .parent { width: 500px; height: 300px; overflow: auto; } .child { width: 100%; /* Scrollbar YOKSA: 500px Scrollbar VARSA (klasik): ~483px Scrollbar VARSA (overlay): 500px */ } /* Yüzde hesaplaması her zaman CONTENT BOX üzerinden */ .parent { width: 500px; padding: 20px; overflow-y: scroll; /* Scrollbar: 17px */ box-sizing: border-box; } .child { width: 100%; /* 500px (total) - 40px (padding) - 17px (scrollbar) = 443px */ } c) Container Query Birimleri (cqw, cqh) .container { container-type: inline-size; width: 500px; overflow-y: auto; } .child { width: 50cqw; /* Container'ın genişliğinin %50'si Scrollbar varsa, scrollbar hariç alan üzerinden */ font-size: 5cqw; } d) ch ve em Birimleri /* ch ve em scrollbar'dan BAĞIMSIZDIR */ .text { max-width: 65ch; /* 65 karakter genişliği */ /* Scrollbar olup olmaması etkilemez */ } .spacing { padding: 1em; /* Font size'a göre */ /* Scrollbar etkisi yok */ } 4. Scrollbar'ı Etkileyen CSS Özellikleri a) overflow Ailesi /* overflow - temel kontrol */ .element { overflow: visible; /* Varsayılan - taşma görünür */ overflow: hidden; /* Taşma gizli - scrollbar yok */ overflow: scroll; /* Her zaman scrollbar */ overflow: auto; /* Gerektiğinde scrollbar */ overflow: clip; /* Taşma kesilir, scroll yok */ } /* Eksen bazlı kontrol */ .element { overflow-x: auto; /* Yatay scroll */ overflow-y: scroll; /* Dikey scroll */ } /* Modern: overflow inline/block */ .element { overflow-inline: auto; /* Yazı yönü bazlı */ overflow-block: scroll; /* Block yönü bazlı */ } /* overflow-anchor - scroll pozisyon kontrolü */ .chat-container { overflow-anchor: auto; /* DOM değişikliklerinde pozisyonu koru */ } b) scrollbar-gutter (Modern) /* Scrollbar için alan rezerve et */ .container { overflow-y: auto; scrollbar-gutter: auto; /* Varsayılan */ } /* Her zaman alan rezerve et */ .stable-layout { overflow-y: auto; scrollbar-gutter: stable; /* Scrollbar olmasa bile alan ayrılır Layout shift'i önler */ } /* İki taraflı (simetrik) */ .centered-content { overflow-y: auto; scrollbar-gutter: stable both-edges; /* Sağ ve solda simetrik alan */ } Kullanım Senaryosu: /* Modal açıldığında body scrollbar kaybolur */ body { overflow: hidden; /* Modal açık */ } /* Problem: Layout kayar (scrollbar alanı kaybolur) */ /* Çözüm: */ body { overflow-y: auto; scrollbar-gutter: stable; /* Scrollbar kaybolsa bile alan rezerve kalır */ } d) scrollbar-color (Firefox) /* Firefox için scrollbar renklendirme */ .custom-scrollbar { scrollbar-color: #888 #f1f1f1; /* İlk değer: thumb, İkinci değer: track */ } /* Temaya göre */ .dark-theme { scrollbar-color: #555 #222; } .light-theme { scrollbar-color: #ccc #fff; } /* Transparent */ .overlay-style { scrollbar-color: rgba(0, 0, 0, 0.3) transparent; } e) ::-webkit-scrollbar (Webkit/Blink) /* Webkit tabanlı tarayıcılar için özelleştirme */ /* Scrollbar genişliği */ .container::-webkit-scrollbar { width: 12px; /* Dikey scrollbar */ height: 12px; /* Yatay scrollbar */ } /* Track (kanal) */ .container::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } /* Thumb (kaydırıcı) */ .container::-webkit-scrollbar-thumb { background: #888; border-radius: 10px; border: 2px solid #f1f1f1; /* Track rengiyle padding efekti */ } /* Hover durumu */ .container::-webkit-scrollbar-thumb:hover { background: #555; } /* Active durumu */ .container::-webkit-scrollbar-thumb:active { background: #333; } /* Corner (köşe) */ .container::-webkit-scrollbar-corner { background: #f1f1f1; } /* Buttons */ .container::-webkit-scrollbar-button { display: none; /* Ok butonlarını gizle */ } Detaylı Özelleştirme: /* Minimal modern scrollbar */ .modern-scroll { scrollbar-width: thin; scrollbar-color: rgba(0, 0, 0, 0.2) transparent; } .modern-scroll::-webkit-scrollbar { width: 8px; } .modern-scroll::-webkit-scrollbar-track { background: transparent; } .modern-scroll::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.2); border-radius: 4px; } .modern-scroll::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.4); } /* macOS benzeri */ .macos-style { scrollbar-width: thin; } .macos-style::-webkit-scrollbar { width: 10px; } .macos-style::-webkit-scrollbar-track { background: transparent; } .macos-style::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.3); border-radius: 10px; border: 2px solid transparent; background-clip: padding-box; } .macos-style::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.5); background-clip: padding-box; } f) scroll-behavior /* Smooth scroll davranışı */ html { scroll-behavior: smooth; } /* Anchor linkler için */ a[href^="#"] { scroll-behavior: smooth; } /* Kullanıcı tercihine saygı */ @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } } g) overscroll-behavior /* Scroll sınırlarında davranış */ .modal-content { overscroll-behavior: contain; /* Scroll sonunda parent'a geçmez */ } body { overscroll-behavior-y: none; /* Bounce/pull-to-refresh engellenmiş */ } /* Eksen bazlı */ .horizontal-scroller { overscroll-behavior-x: contain; overscroll-behavior-y: auto; } h) scroll-snap /* Snap scroll davranışı */ .gallery { scroll-snap-type: x mandatory; overflow-x: auto; } .gallery-item { scroll-snap-align: start; scroll-snap-stop: always; /* Her öğede dur */ } /* Dikey snap */ .fullpage-sections { scroll-snap-type: y proximity; overflow-y: auto; } .section { scroll-snap-align: center; min-height: 100vh; } 5. Scrollbar ve Modern Tasarım a) Minimal/Invisible Scrollbar Trendi /* Gizli ama fonksiyonel scrollbar */ .minimal-scroll { overflow: auto; scrollbar-width: none; /* Firefox */ } .minimal-scroll::-webkit-scrollbar { display: none; /* Webkit/Blink */ } /* Hover'da görünen scrollbar */ .hover-scrollbar { scrollbar-width: none; } .hover-scrollbar:hover { scrollbar-width: thin; } .hover-scrollbar::-webkit-scrollbar { width: 0; transition: width 0.3s; } .hover-scrollbar:hover::-webkit-scrollbar { width: 8px; } b) Custom Scrollbar Tasarımları 1. Minimal Modern: .minimal { scrollbar-width: thin; scrollbar-color: #e0e0e0 transparent; } .minimal::-webkit-scrollbar { width: 6px; } .minimal::-webkit-scrollbar-track { background: transparent; } .minimal::-webkit-scrollbar-thumb { background: #e0e0e0; border-radius: 3px; } 2. Branded/Colorful: .branded { scrollbar-width: auto; scrollbar-color: var(--brand-color) var(--bg-color); } .branded::-webkit-scrollbar { width: 12px; } .branded::-webkit-scrollbar-track { background: var(--bg-color); } .branded::-webkit-scrollbar-thumb { background: linear-gradient( 180deg, var(--brand-color-light), var(--brand-color-dark) ); border-radius: 6px; } 3. Animated/Interactive: .interactive::-webkit-scrollbar-thumb { background: #888; transition: background 0.2s, transform 0.2s; } .interactive::-webkit-scrollbar-thumb:hover { background: #555; transform: scaleX(1.2); } .interactive::-webkit-scrollbar-thumb:active { background: #333; } Responsive Scrollbar Stratejileri /* Desktop - normal scrollbar */ @media (min-width: 1024px) { .content { scrollbar-width: auto; } .content::-webkit-scrollbar { width: 12px; } } /* Tablet - ince scrollbar */ @media (max-width: 1023px) and (min-width: 768px) { .content { scrollbar-width: thin; } .content::-webkit-scrollbar { width: 8px; } } /* Mobile - gizli scrollbar */ @media (max-width: 767px) { .content { scrollbar-width: none; } .content::-webkit-scrollbar { display: none; } } /* Touch device tespiti */ @media (hover: none) and (pointer: coarse) { .content { scrollbar-width: none; } } Scrollbar ve Performans a) will-change ile Optimizasyon .smooth-scroll { overflow-y: auto; will-change: scroll-position; /* GPU hızlandırma aktif */ } /* Dikkat: Sürekli kullanma */ .scroll-container:hover { will-change: scroll-position; } .scroll-container { will-change: auto; /* Hover sonrası kapat */ } b) contain ile İzolasyon .scroll-section { overflow: auto; contain: layout style paint; /* Scroll bu element içinde kalır */ /* Tarayıcı optimize edebilir */ } b) Split Panel Layout .split-panel { display: grid; grid-template-columns: 300px 1fr; height: 100vh; } .sidebar { overflow-y: auto; scrollbar-width: thin; overscroll-behavior: contain; } .main-content { overflow-y: auto; scrollbar-gutter: stable; } c) Horizontal Scroll Gallery .gallery { display: flex; gap: 1rem; overflow-x: auto; scrollbar-width: thin; /* macOS momentum scroll */ -webkit-overflow-scrolling: touch; /* Snap points */ scroll-snap-type: x mandatory; scroll-padding: 1rem; } .gallery-item { scroll-snap-align: start; flex: 0 0 300px; } /* Fade edges efekti */ .gallery-wrapper { position: relative; } .gallery-wrapper::before, .gallery-wrapper::after { content: ''; position: absolute; top: 0; bottom: 20px; /* Scrollbar yüksekliği */ width: 50px; pointer-events: none; z-index: 1; } .gallery-wrapper::before { left: 0; background: linear-gradient(to right, white, transparent); } .gallery-wrapper::after { right: 0; background: linear-gradient(to left, white, transparent); } /* ÖZELLEŞTIR: Branded deneyim */ .app-container { scrollbar-color: var(--brand-primary) var(--bg-secondary); } /* ÖZELLEŞTIRME: Dark theme */ @media (prefers-color-scheme: dark) { .content { scrollbar-color: #444 #1a1a1a; } } /* VARSAYILAN BIRAK: Standard içerik */ article { overflow: auto; /* İşletim sistemi scrollbar'ı en iyi */ } Özet: Scrollbar ve Modern CSS Kritik Noktalar: Viewport Hesaplamaları: 100vw scrollbar genişliğini içerir, layout kaymasına neden olabilir scrollbar-gutter: Modern çözüm, scrollbar için alan rezerve eder Özelleştirme: Firefox (scrollbar-width, scrollbar-color) ve Webkit (::-webkit-scrollbar-*) farklı yaklaşımlar Accessibility: Scrollbar gizlerken scroll işlevselliğini koruyun Performance: will-change ve contain ile optimize edin Modern Tasarım: Minimal, hover-revealed, overlay scrollbar trendleri Scrollbar, layout sisteminin kritik ama sık göz ardı edilen bir parçasıdır. Modern CSS özellikleri (scrollbar-gutter, dvw, container queries) bu zorlukları ele almak için geliştirilmiştir.
  2. Metin okunabilirliği, kullanıcıların metni ne kadar kolay okuyabildiği ve anladığıyla ilgilidir. Bu, tipografi, spacing, kontrast ve layout kararlarının birleşimidir. 1. Temel Okunabilirlik Faktörleri a) Satır Uzunluğu (Line Length / Measure) Optimal: 45-75 karakter (İngilizce için), 50-80 karakter (Türkçe için) /* Kötü - çok geniş satırlar */ .article { max-width: 100%; /* 120+ karakter - gözler satır sonunu bulamaz */ } /* İyi - optimal satır uzunluğu */ .article { max-width: 65ch; /* ch birimi: karakter genişliği */ } /* Responsive optimal uzunluk */ .article { max-width: clamp(45ch, 90%, 75ch); } CSS Özellikleri: max-width ile satır uzunluğu kontrolü ch birimi (karakter genişliği) - tipografik ölçüm clamp() ile esnek sınırlar b) Satır Yüksekliği (Line Height / Leading) Optimal: 1.4-1.8 arası (metin boyutuna göre değişir) /* Kötü - çok sıkışık */ .text-cramped { line-height: 1; /* Satırlar birbirine yapışır */ } /* Kötü - çok gevşek */ .text-loose { line-height: 2.5; /* Satırlar arasında kopukluk */ } /* İyi - dengeli */ .paragraph { line-height: 1.6; } /* Boyut bazlı ayarlama */ .heading { font-size: 3rem; line-height: 1.2; /* Büyük metinler daha az line-height */ } .body-text { font-size: 1rem; line-height: 1.6; /* Küçük metinler daha fazla */ } /* Modern: lh birimi ile */ .paragraph { line-height: 1.5; margin-block-end: 1lh; /* 1 satır yüksekliği kadar boşluk */ } CSS Özellikleri: line-height - birimsize (1.5) veya birimli (1.5rem) lh birimi - satır yüksekliğine göre spacing leading-trim (gelecek özellik) - tipografik hassasiyet c) Font Boyutu (Font Size) Optimal: 16px-18px body text için /* Kötü - sabit piksel */ body { font-size: 14px; /* Kullanıcı tercihleri göz ardı */ } /* İyi - göreceli birim */ body { font-size: 1rem; /* Tarayıcı ayarlarına saygı */ } /* Daha iyi - responsive */ body { font-size: clamp(1rem, 0.9rem + 0.5vw, 1.125rem); /* Küçük ekran: 16px, büyüdükçe 18px'e kadar */ } /* Hiyerarşi ile */ :root { --font-size-sm: 0.875rem; /* 14px */ --font-size-base: 1rem; /* 16px */ --font-size-lg: 1.125rem; /* 18px */ --font-size-xl: 1.25rem; /* 20px */ } .small-text { font-size: var(--font-size-sm); } .body-text { font-size: var(--font-size-base); } CSS Özellikleri: font-size - rem, em, clamp() font-size-adjust - farklı fontlar arasında tutarlılık 2. Tipografi ve Font Özellikleri a) Font Seçimi ve Okunabilirlik /* Sistem fontları - hızlı ve okunabilir */ body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; } /* Okuma için serif */ .article-content { font-family: Georgia, "Times New Roman", serif; font-size: 1.125rem; line-height: 1.7; } /* Kod için monospace */ code { font-family: "SF Mono", Monaco, "Cascadia Code", "Courier New", monospace; font-size: 0.9em; /* Parent'a göre biraz küçük */ } b) Font Weight (Kalınlık) /* Okunabilirlik için optimal ağırlıklar */ body { font-weight: 400; /* Normal - body text için */ } .heading { font-weight: 700; /* Bold - başlıklar için */ } .lead-text { font-weight: 500; /* Medium - vurgu için */ } /* Variable fonts ile hassas kontrol */ @supports (font-variation-settings: normal) { .text { font-variation-settings: "wght" 450; /* 400-500 arası hassas ayar */ } } /* İnce fontlar kontrast gerektirir */ .thin-text { font-weight: 300; font-size: 1.125rem; /* Daha büyük boyut */ color: #000; /* Daha yüksek kontrast */ } CSS Özellikleri: font-weight - 100-900 arası değerler font-variation-settings - variable fonts için c) Font Optical Sizing /* Farklı boyutlarda optimal form */ .text { font-optical-sizing: auto; /* Font boyuta göre otomatik optimize olur */ } /* Büyük başlıklarda display variant */ .hero-title { font-size: 4rem; font-optical-sizing: auto; /* Büyük boyut için optimize edilmiş formlar */ } 3. Karakter ve Kelime Spacing a) Letter Spacing (Karakter Aralığı) /* Genellikle varsayılan en iyisidir */ .body-text { letter-spacing: normal; } /* Büyük başlıklarda sıkıştırma */ .display-heading { font-size: 5rem; letter-spacing: -0.02em; /* Negatif tracking */ } /* Küçük büyük harfler için açma */ .small-caps { font-variant: small-caps; letter-spacing: 0.05em; } .uppercase-label { text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.875rem; } Kural: Büyük fontlar → negatif letter-spacing Küçük fontlar / ALL CAPS → pozitif letter-spacing b) Word Spacing /* Nadiren değiştirilmeli */ .text { word-spacing: normal; } /* Çok dar yazılarda */ .narrow-column { max-width: 35ch; word-spacing: 0.1em; /* Biraz daha fazla boşluk */ } 4. Renk ve Kontrast a) Renk Kontrastı (WCAG Standartları) WCAG AA: Minimum 4.5:1 (normal metin), 3:1 (büyük metin) WCAG AAA: Minimum 7:1 (normal metin), 4.5:1 (büyük metin) /* Kötü kontrast - okunaksız */ .low-contrast { color: #999; background: #fff; /* Kontrast: 2.8:1 - yetersiz */ } /* İyi kontrast */ .good-contrast { color: #333; background: #fff; /* Kontrast: 12.6:1 - mükemmel */ } /* Karanlık mod için */ @media (prefers-color-scheme: dark) { body { color: #e0e0e0; background: #121212; /* Kontrast: 13.9:1 */ } } /* Modern: color-contrast() fonksiyonu (gelecek) */ .text { color: color-contrast( var(--background) vs #000, #333, #666 ); /* En iyi kontrast otomatik seçilir */ } CSS Özellikleri: color ve background-color color-contrast() (gelecek özellik) prefers-contrast media query b) Alt Metin Renkleri /* Link renkleri - yeterli kontrast */ a { color: #0066cc; /* Ana metinden ayırt edilebilir */ } a:visited { color: #551a8b; /* Ziyaret edilmiş linkler farklı */ } /* Disabled metin */ .disabled-text { color: #767676; /* Minimum 4.5:1 kontrast korunmalı */ } /* Placeholder metinler */ input::placeholder { color: #757575; opacity: 1; /* Varsayılan opacity kaldırılmalı */ } 5. Hizalama ve Metin Düzeni a) Text Alignment /* Batı dilleri için soldan hizalama en okunabilir */ .paragraph { text-align: start; /* Dil yönünü otomatik dikkate alır */ } /* Justify - dikkatli kullanılmalı */ .article { text-align: justify; hyphens: auto; /* Kelime bölme ile birlikte */ /* Yoksa kelimeler arası büyük boşluklar */ } /* Ortalama - sadece kısa metinler için */ .heading { text-align: center; max-width: 30ch; /* Çok uzun satırlar ortalanmamalı */ } Modern Özellikler: /* Mantıksal hizalama */ .text { text-align: start; /* left yerine */ text-align: end; /* right yerine */ /* RTL dillerde otomatik ters çevrilir */ } b) Hyphens (Kelime Bölme) /* Dar sütunlarda yararlı */ .narrow-column { max-width: 40ch; hyphens: auto; /* Kelimeler uygun şekilde bölünür */ } /* Türkçe için */ .turkish-text { hyphens: auto; lang: tr; /* HTML'de lang="tr" olmalı */ } /* Uzun kelimelerin kontrolü */ .text { overflow-wrap: break-word; word-break: break-word; hyphens: auto; } c) Text Wrapping /* Uzun URL'ler ve kelimeler */ .url-text { word-break: break-all; /* Her karakterden bölebilir */ /* veya */ overflow-wrap: anywhere; /* Boşluk yoksa böler */ } /* Başlıklar - widows/orphans önleme */ .heading { text-wrap: balance; /* Satırlar dengeli uzunlukta */ } /* Paragraflar */ .paragraph { text-wrap: pretty; /* Orphan'ları önler */ } 6. Paragraph Spacing a) Paragraph Margins /* Paragraflar arası boşluk */ .paragraph { margin-block-end: 1em; /* Font boyutuna göre */ /* veya */ margin-block-end: 1lh; /* Satır yüksekliğine göre */ } /* İlk paragraf girintisi (opsiyonel) */ .paragraph + .paragraph { text-indent: 1.5em; margin-block-start: 0; } /* Responsive spacing */ .article { --paragraph-spacing: clamp(1rem, 0.5rem + 1vw, 1.5rem); } .paragraph { margin-block-end: var(--paragraph-spacing); } b) Drop Caps (Baş Harf Süsleme) .paragraph::first-letter { initial-letter: 3; /* 3 satır yüksekliğinde */ font-weight: 700; margin-inline-end: 0.5em; color: var(--accent-color); } 7. Başlık Hiyerarşisi ve Okunabilirlik /* Type scale - harmonik oran */ :root { --ratio: 1.25; /* Major third */ --font-size-base: 1rem; --font-size-h6: var(--font-size-base); --font-size-h5: calc(var(--font-size-h6) * var(--ratio)); --font-size-h4: calc(var(--font-size-h5) * var(--ratio)); --font-size-h3: calc(var(--font-size-h4) * var(--ratio)); --font-size-h2: calc(var(--font-size-h3) * var(--ratio)); --font-size-h1: calc(var(--font-size-h2) * var(--ratio)); } h1, h2, h3, h4, h5, h6 { line-height: 1.2; font-weight: 700; margin-block-end: 0.5em; } h1 { font-size: var(--font-size-h1); } h2 { font-size: var(--font-size-h2); } h3 { font-size: var(--font-size-h3); } /* ... */ /* Başlıktan sonra paragraf spacing */ h1 + p, h2 + p, h3 + p { margin-block-start: 0.75em; } 8. Accessibility ve Okunabilirlik a) Kullanıcı Tercihleri /* Reduced motion */ @media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } /* Contrast tercihi */ @media (prefers-contrast: high) { body { color: #000; background: #fff; } } /* Font boyutu artırma desteği */ html { font-size: 100%; /* Tarayıcı varsayılanına saygı */ } body { font-size: 1rem; /* Göreceli birim kullan */ } b) Focus States /* Klavye navigasyonu için görünür focus */ :focus-visible { outline: 3px solid var(--focus-color); outline-offset: 2px; } /* Link focus */ a:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; text-decoration: none; } 9. Responsive Typography a) Fluid Typography /* Viewport bazlı scaling */ body { font-size: clamp(1rem, 0.875rem + 0.5vw, 1.25rem); /* Küçük: 16px, Orta: ~18px, Büyük: 20px */ } h1 { font-size: clamp(2rem, 1.5rem + 2vw, 4rem); line-height: 1.1; } /* Container query ile */ @container (min-width: 600px) { .card-title { font-size: 1.5rem; } } b) Responsive Line Length .article { /* Ekran genişliğine göre ama maksimum karakter */ width: min(90%, 70ch); margin-inline: auto; } /* Container içinde */ .sidebar-article { max-width: 55ch; /* Dar alanlarda daha kısa satır */ } 10. Advanced CSS Features a) CSS Subgrid ile Hizalama .article-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 2rem; } .article-card { display: grid; grid-template-rows: subgrid; grid-row: span 3; } /* Tüm başlıklar ve metinler hizalı */ b) Text Decoration /* Okunabilir link altı çizgileri */ a { text-decoration: underline; text-decoration-thickness: 0.1em; text-decoration-color: var(--link-color); text-underline-offset: 0.2em; } a:hover { text-decoration-thickness: 0.15em; } 11. Okunabilirlik Kontrol Listesi Optimal Ayarlar: .readable-text { /* Font */ font-family: system-ui, sans-serif; font-size: clamp(1rem, 0.9rem + 0.5vw, 1.125rem); font-weight: 400; /* Spacing */ line-height: 1.6; letter-spacing: normal; max-width: 70ch; /* Layout */ margin-block-end: 1lh; text-align: start; text-wrap: pretty; /* Renk */ color: #333; background: #fff; /* Responsive */ hyphens: auto; overflow-wrap: break-word; } Özet: Metin Okunabilirliği Prensipleri Satır Uzunluğu: 45-75 karakter (max-width: 65ch) Satır Yüksekliği: 1.5-1.8 arası (line-height) Font Boyutu: Minimum 16px (font-size: 1rem) Kontrast: Minimum 4.5:1 (WCAG AA) Hizalama: Sol hizalama en okunabilir Spacing: Yeterli paragraph ve heading spacing Responsive: Fluid typography ve optimal line length Accessibility: Kullanıcı tercihlerine saygı Modern CSS, bu okunabilirlik faktörlerini kontrol etmek için güçlü araçlar sunar: clamp(), ch birimi, lh birimi, mantıksal özellikler, text-wrap, container queries ve daha fazlası. Bu özellikleri doğru kullanmak, her ekran boyutunda ve her kullanıcı için optimal okuma deneyimi sağlar.
  3. Doğuhan ELMA

    CSS'de lh Birimi

    lh birimi, CSS'de line-height (satır yüksekliği) değerine göre hesaplanan görece yeni bir uzunluk birimidir. Bir elementin hesaplanmış satır yüksekliğini temsil eder. Temel Tanım 1lh, elementin kendi line-height değerine eşittir. Örneğin: .element { font-size: 16px; line-height: 1.5; /* 24px */ margin-bottom: 1lh; /* 24px olur */ } Nasıl Çalışır? lh birimi, kullanıldığı elementin hesaplanmış line-height değerini referans alır: .card { font-size: 18px; line-height: 1.6; /* 28.8px */ padding-top: 0.5lh; /* 14.4px */ margin-bottom: 2lh; /* 57.6px */ gap: 1lh; /* 28.8px */ } Miras ve Hesaplama lh, line-height'ın nihai hesaplanmış değerini kullanır: body { font-size: 16px; line-height: 1.5; /* 24px */ } .content { font-size: 20px; /* line-height miras alınır: 1.5 × 20px = 30px */ margin-top: 1lh; /* 30px olur */ } Modern Tasarımdaki Yeri 1. Dikey Ritim (Vertical Rhythm) lh birimi, tipografik ızgara sistemleri için mükemmeldir: .article { font-size: 18px; line-height: 1.6; /* Tüm boşluklar satır yüksekliğinin katları */ h2 { margin-top: 2lh; margin-bottom: 1lh; } p { margin-bottom: 1lh; } ul { margin: 1lh 0; padding-left: 2lh; } } Bu yaklaşım, metinler arasında tutarlı ve harmonik boşluklar oluşturur. 2. Dinamik Ölçeklendirme Font boyutu değiştiğinde, lh bazlı boşluklar otomatik uyum sağlar: .text-block { font-size: clamp(16px, 4vw, 24px); line-height: 1.5; padding: 1lh; } /* Küçük ekranlarda: 16px × 1.5 = 24px padding */ /* Büyük ekranlarda: 24px × 1.5 = 36px padding */ 3. Responsive Tasarım Farklı ekran boyutlarında orantılı boşluklar: .content { font-size: 16px; line-height: 1.5; } @media (min-width: 768px) { .content { font-size: 18px; /* line-height: 1.5 korunur ama değer 27px olur */ /* Tüm lh bazlı değerler otomatik ölçeklenir */ } } 4. Component-Based Tasarım Her komponentin kendi tipografik sistemini korur: .card { font-size: 14px; line-height: 1.4; padding: 1lh; gap: 0.5lh; } .hero { font-size: 32px; line-height: 1.2; padding: 1lh; /* card'dan farklı ama orantılı */ } Pratik Kullanım Örnekleri Örnek 1: Blog Yazısı Düzeni .blog-post { font-size: 18px; line-height: 1.6; max-width: 65ch; } .blog-post h1 { font-size: 2em; line-height: 1.2; margin-bottom: 0.5lh; } .blog-post h2 { margin-top: 2lh; margin-bottom: 1lh; } .blog-post p { margin-bottom: 1lh; } .blog-post blockquote { margin: 1.5lh 0; padding-left: 1lh; border-left: 0.2lh solid #ccc; } Örnek 2: Grid Layout .grid { display: grid; gap: 1lh; /* Satır yüksekliği kadar boşluk */ line-height: 1.5; } .grid-item { padding: 1lh; } Örnek 3: Form Elemanları .form-group { font-size: 16px; line-height: 1.5; margin-bottom: 1lh; } .form-label { display: block; margin-bottom: 0.5lh; } .form-input { height: 2lh; /* İki satır yüksekliğinde */ padding: 0 0.5lh; } Em ve Rem ile Karşılaştırma .comparison { font-size: 20px; line-height: 1.6; /* 32px */ margin-bottom: 1em; /* 20px - font-size'a göre */ padding: 1rem; /* 16px - root font-size'a göre */ gap: 1lh; /* 32px - line-height'a göre */ } em: Font boyutuna bağlı rem: Root font boyutuna bağlı lh: Satır yüksekliğine bağlı Tarayıcı Desteği lh birimi modern tarayıcılarda desteklenir: Chrome 109+ Firefox 120+ Safari 16.4+ Edge 109+ Eski tarayıcılar için fallback kullanabilirsiniz: .element { margin-bottom: 24px; /* fallback */ margin-bottom: 1lh; } Avantajları Tutarlılık: Dikey boşluklar her zaman tipografik ızgaraya uygun Bakım kolaylığı: line-height değiştiğinde tüm boşluklar otomatik uyum sağlar Okunabilirlik: Metinler arası boşluklar doğal ve orantılı Esneklik: Farklı font boyutlarında otomatik ölçeklenir Ne Zaman Kullanmalı? lh birimini şu durumlarda tercih edin: Dikey boşlukları tipografik ızgaraya bağlamak istediğinizde Satırlar arası boşluklarla uyumlu margin/padding değerleri oluşturmak istediğinizde Font boyutu değiştiğinde orantılı ölçeklenen boşluklar gerektiğinde Component tabanlı, tutarlı tipografi sistemi kurarken lh birimi, modern CSS'in getirdiği tipografi odaklı yaklaşımın güzel bir örneğidir ve özellikle içerik ağırlıklı sitelerde dikey ritmi korumak için oldukça değerlidir.
  4. Doğuhan ELMA

    CSS line-height Özelliği

    CSS'teki line-height (satır yüksekliği) özelliğinin değeri, modern web tasarımında metin okunabilirliğini ve dikey ritmi sağlamak için kritik öneme sahiptir. CSS'in en kritik tipografi özelliklerinden biridir. Duyarlı (responsive) tasarımlarda okunabilirliği artırmak temel hedeftir. line-height temel olarak, bir metin satırının yukarısındaki ve aşağısındaki görünmez boşluğu (leading) belirler. Bu boşluk, satırın kendisinin yüksekliğini oluşturur ve metin boyutuyla (font-size) ilişkilidir. Modern CSS değer birimi, Unitless (birimsiz)'dir. Adaptif ve Ölçeklenebilir bir çözüm sunar. Bu, dikey ritmin ve okuma konforunun tüm cihaz ve boyutlarda korunmasını sağlar. Değer türü Örnek Kabul edilir mi? Açıklama Unitless (birimsiz) 1.5 ✔ Oransal, en önerilen yöntem Pixel 20px ✔ Sabit uzunluk Em 1.2em ✔ Yazı boyutuna bağlı Rem 1.4rem ✔ Root font-size’a bağlı Yüzde 120% ✔ Oran olarak Normal normal ✔ Tarayıcı varsayılanı Viewport 3vh ✘ Geçersiz fr 1fr ✘ Grid’e özeldir Temel Konsept line-height, bir satırın toplam yüksekliğini belirler (font yüksekliği + üst/alt boşluk): ┌─────────────────────┐ ← Line box top │ ↑ Leading │ │ ┌─────────┐ │ │ │ Text │ │ ← Font size │ └─────────┘ │ │ ↓ Leading │ └─────────────────────┘ ← Line box bottom Leading = (line-height - font-size) / 2 Değer Tipleri ve Davranışları 1. Unitless (Oran) - ✅ EN İYİ UYGULAMA p { font-size: 16px; line-height: 1.5; /* Oransal - font-size'ın 1.5 katı */ /* = 16px * 1.5 = 24px */ } Miras davranışı: .parent { font-size: 16px; line-height: 1.5; /* ORAN miras alınır */ } .child { font-size: 32px; /* line-height: 1.5 ORANI miras alır */ /* = 32px * 1.5 = 48px ✅ DOĞRU */ } 2. Piksel (px) - ❌ KÖTÜ UYGULAMA p { font-size: 16px; line-height: 24px; /* Sabit değer */ } Miras davranışı: .parent { font-size: 16px; line-height: 24px; /* HESAPLANMIŞ DEĞER miras alınır */ } .child { font-size: 32px; /* line-height: 24px sabit değer miras alır */ /* Metin üst üste biner! ❌ SORUNLU */ } 3. Yüzde (%) - ❌ YANILTICI p { font-size: 16px; line-height: 150%; /* = 24px olarak HESAPLANIR */ } Miras davranışı: .parent { font-size: 16px; line-height: 150%; /* Parent'ta 24px olarak hesaplanır */ } .child { font-size: 32px; /* line-height: 24px (hesaplanmış değer) miras alır */ /* Yine sorunlu! ❌ */ } 4. Em Birimi - ❌ KARMAŞIK p { font-size: 16px; line-height: 1.5em; /* = 16px * 1.5 = 24px olarak HESAPLANIR */ } Miras davranışı: .parent { font-size: 16px; line-height: 1.5em; /* = 24px hesaplanır */ } .child { font-size: 32px; /* line-height: 24px miras alır ❌ */ } 5. Rem Birimi - ⚠️ ÖZELLİKLE KULLAN :root { font-size: 16px; } p { font-size: 1rem; /* 16px */ line-height: 1.5rem; /* = 24px sabit */ } h1 { font-size: 2rem; /* 32px */ /* Eğer line-height belirtilmezse, parent'tan miras alır */ /* 24px alırsa sorunlu olur */ } Detaylı Karşılaştırma /* Test senaryosu */ .container { font-size: 16px; } /* Senaryo 1: Unitless ✅ */ .container-unitless { line-height: 1.5; /* Oran */ } .container-unitless .small { font-size: 12px; /* line-height = 12px * 1.5 = 18px ✅ */ } .container-unitless .large { font-size: 32px; /* line-height = 32px * 1.5 = 48px ✅ */ } /* Senaryo 2: Piksel ❌ */ .container-px { line-height: 24px; /* Sabit */ } .container-px .small { font-size: 12px; /* line-height = 24px (geniş boşluk) ⚠️ */ } .container-px .large { font-size: 32px; /* line-height = 24px (metin üst üste biner!) ❌ */ } /* Senaryo 3: Yüzde ❌ */ .container-percent { line-height: 150%; /* 16px * 150% = 24px hesaplanır */ } .container-percent .large { font-size: 32px; /* line-height = 24px miras alır ❌ */ } /* Senaryo 4: Em ❌ */ .container-em { line-height: 1.5em; /* 16px * 1.5 = 24px hesaplanır */ } .container-em .large { font-size: 32px; /* line-height = 24px miras alır ❌ */ } Line-height Değeri Nasıl Hesaplanır? İdeal Değerler: Kısa Satırlar (Başlıklar, Navigasyon): Daha küçük değerler (örneğin, 1.2 - 1.4) kullanılabilir. Çünkü satır uzunluğu kısaldıkça gözün bir sonraki satıra geçme zorluğu azalır. Uzun Satırlar (Gövde Metni/Paragraf): Okunabilirliği artırmak için daha büyük değerler (örneğin, 1.5 - 1.6) kullanılır. Satır uzadıkça, okuyucunun kaybolmadan bir sonraki satırın başına kolayca dönmesi için daha fazla boşluğa ihtiyacı vardır. Font Tasarımı: Her yazı tipi, büyük ve küçük harflerinin boyutunu ve tasarımını (x-yüksekliği) farklı şekilde yönetir. Kullanılan fonta göre line-height değeri değişebilir. X-yüksekliği büyük olan fontlar daha kolay okunur. X-yüksekliği azaldıkça line-height değeri artar. Leading (Satır Aralığı) .text { font-size: 16px; line-height: 1.5; /* = 24px */ } /* Leading hesaplama: Leading = line-height - font-size Leading = 24px - 16px = 8px Üst boşluk = 8px / 2 = 4px Alt boşluk = 8px / 2 = 4px */ Normal Değeri p { line-height: normal; /* Tarayıcı varsayılanı */ /* Çoğu tarayıcıda ~1.2 */ /* Font'a göre değişebilir */ } Dikkat: normal değeri font'a bağlı olarak değişir, tahmin edilemez. Daima açık değer belirt. Tipografi için İdeal Değerler Genel Kurallar /* Body metni - Paragraflar */ body { line-height: 1.6; /* Optimal okunabilirlik */ /* 1.5 - 1.8 arası genelde iyi */ } /* Başlıklar */ h1, h2, h3, h4, h5, h6 { line-height: 1.2; /* Sıkı - başlıklar tek/iki satırlık */ /* 1.1 - 1.3 arası */ } /* Küçük metinler */ .small-text { font-size: 0.875rem; /* 14px */ line-height: 1.4; } /* Büyük display metinler */ .display { font-size: 4rem; line-height: 1; /* Çok sıkı veya 1.1 */ } /* Kod blokları */ code, pre { line-height: 1.6; /* Kod okunabilirliği için */ } /* Butonlar - Tek satır */ .button { line-height: 1; /* Dikey ortalama için */ padding: 0.75em 1.5em; /* Em ile oransal padding */ } /* Liste elemanları */ li { line-height: 1.8; /* Listeler için daha geniş */ } /* İnce/uzun yazı kolonları */ .narrow-column { max-width: 40ch; line-height: 1.8; /* Dar kolonlarda daha geniş */ } /* Geniş yazı kolonları */ .wide-column { max-width: 80ch; line-height: 1.5; /* Geniş kolonlarda daha sıkı */ } Bilimsel Temeller Okunabilirlik araştırmaları: Optimal: 45-75 karakter genişliğinde satırlar için line-height: 1.5-1.6 Dar kolonlar (<45 karakter): line-height: 1.7-1.8 Geniş kolonlar (>75 karakter): line-height: 1.4-1.5 Başlıklar: line-height: 1.1-1.3 lh Birimi (Yeni) /* Line-height'a göre oransal birim */ .text-box { line-height: 1.5; /* = 24px (16px font için) */ /* Padding line-height'ın yarısı */ padding-block: 0.5lh; /* = 12px */ /* Margin line-height kadar */ margin-bottom: 1lh; /* = 24px */ } /* Dikey ritim için mükemmel */ .rhythm-element { line-height: 1.6; margin-bottom: 1lh; /* Her zaman line-height kadar */ }
  5. CSS'te bazı özellikler birim gerektirmeyen saf sayı değerleri kabul eder. Bu "unitless numbers" kavramı, CSS'in temel mekaniklerinden biridir. Özellik Unitless kabul eder mi? Örnek Açıklama line-height ✔ line-height: 1.4; Font yüksekliği ile çarpılan oran. z-index ✔ z-index: 10; Katman sırası. opacity ✔ opacity: 0.6; 0–1 arasında saydamlık oranı. font-weight ✔ font-weight: 700; 100–900 arası kalınlık. flex-grow ✔ flex-grow: 2; Elemanın büyüme oranı. flex-shrink ✔ flex-shrink: 0; Elemanın küçülme oranı. flex (kısa kullanım) ✔ (ilk 2 değer) flex: 1 0 auto; İlk iki değer (grow/shrink) unitless’tır. animation-iteration-count ✔ animation-iteration-count: 3; Tekrar sayısı. grid-row / grid-column (span) ✔ grid-column: span 3; Kaç hücre genişleyeceğini belirleyen unitless sayı. order ✔ order: 2; Flex/Grid sıralaması için saf sayı. line-clamp ✔ line-clamp: 3; Kaç satır gösterileceği. orphans ✔ orphans: 2; Sayfa bölünmesinde minimum satır. widows ✔ widows: 2; Sayfa bölünmesinde maksimum satır. Unitless Numbers Kullanan CSS Özellikleri 1. line-height (En Önemli Kullanım) /* ❌ Birimli - KÖTÜ UYGULAMA */ p { font-size: 16px; line-height: 24px; /* Sabit değer */ } /* ❌ Yüzde - Şaşırtıcı davranış */ p { font-size: 16px; line-height: 150%; /* = 24px olarak hesaplanır ve KALSALAŞıR */ } /* ✅ Unitless - EN İYİ UYGULAMA */ p { font-size: 16px; line-height: 1.5; /* Font-size'ın 1.5 katı = 24px */ } Line-height'ta Unitless Neden Kritik? /* Miras davranışını görelim */ .parent { font-size: 16px; line-height: 24px; /* Sabit değer */ } .child { font-size: 32px; /* line-height: 24px kalır - SORUN! */ /* Metin üst üste biner */ } /* Yüzde ile */ .parent { font-size: 16px; line-height: 150%; /* = 24px hesaplanır ve bu değer miras alınır */ } .child { font-size: 32px; /* line-height: 24px (parent'tan miras) - SORUN! */ } /* ✅ Unitless ile - ÇÖZÜM */ .parent { font-size: 16px; line-height: 1.5; /* Oran miras alınır, değer değil */ } .child { font-size: 32px; /* line-height: 1.5 oranı miras alınır */ /* = 32px * 1.5 = 48px - DOĞRU! */ } Kural: line-height için DAIMA unitless kullan! Pratik Line-height Değerleri /* Genel kurallar */ body { line-height: 1.6; /* Paragraf metinleri için ideal */ } h1, h2, h3, h4, h5, h6 { line-height: 1.2; /* Başlıklar için sıkı */ } .small-text { line-height: 1.4; /* Küçük metinler için */ } .code { line-height: 1.6; /* Kod blokları için */ } .button { line-height: 1; /* Tek satır butonlar için */ } .loose-text { line-height: 1.8; /* Geniş satır aralığı */ } 2. opacity (Şeffaflık) .element { opacity: 0; /* Tamamen şeffaf */ opacity: 0.5; /* %50 şeffaf */ opacity: 1; /* Tamamen opak */ } /* ❌ Birim kullanılamaz */ opacity: 50%; /* Geçersiz (bazı tarayıcılar destekler ama standart değil) */ opacity: 0.5px; /* Geçersiz */ /* Pratik kullanım */ .disabled { opacity: 0.5; cursor: not-allowed; } .hover-effect { opacity: 1; transition: opacity 0.3s; } .hover-effect:hover { opacity: 0.8; } .fade-in { opacity: 0; animation: fadeIn 0.5s forwards; } @keyframes fadeIn { to { opacity: 1; } } 3. z-index (Katman Sırası) .element { position: relative; z-index: 10; /* Unitless integer */ } /* ❌ Birim kullanılamaz */ z-index: 10px; /* Geçersiz */ z-index: 1.5; /* Çalışır ama tam sayı olmalı */ 4. flex-grow, flex-shrink, flex-basis (flex'te 0 hariç) /* flex-grow - Unitless */ .item { flex-grow: 1; /* Boş alanı eşit paylaş */ flex-grow: 2; /* 2 kat daha fazla alan al */ } /* flex-shrink - Unitless */ .item { flex-shrink: 1; /* Normal küçülme */ flex-shrink: 0; /* Hiç küçülme */ } /* flex kısaltması */ .item { flex: 1; /* flex: 1 1 0 anlamına gelir */ /* grow shrink basis */ } /* Pratik flex kullanımı */ .container { display: flex; } .sidebar { flex: 0 0 250px; /* Büyümez, küçülmez, 250px sabit */ } .content { flex: 1; /* Kalan alanı kaplar */ } .priority-item { flex-grow: 2; /* Diğerlerinden 2x daha fazla büyür */ } 5. order (Flex/Grid Sırası) .flex-item { order: 0; /* Varsayılan */ order: 1; /* Sona gider */ order: -1; /* Başa gider */ } /* ❌ Birim kullanılamaz */ order: 1px; /* Geçersiz */ /* Responsive sıralama */ .mobile-first { order: -1; /* Mobilde en üstte */ } @media (min-width: 768px) { .mobile-first { order: 0; /* Desktop'ta normal sırada */ } } 6. font-weight (Yazı Kalınlığı) .element { font-weight: 400; /* Normal - unitless */ font-weight: 700; /* Bold - unitless */ } /* İsimli değerler de kullanılabilir */ font-weight: normal; /* = 400 */ font-weight: bold; /* = 700 */ font-weight: lighter; /* Parent'tan daha ince */ font-weight: bolder; /* Parent'tan daha kalın */ /* Variable fonts ile */ @font-face { font-family: 'Inter'; src: url('inter-variable.woff2'); font-weight: 100 900; /* Desteklenen aralık */ } .heading { font-weight: 650; /* Özel değer - variable font gerekir */ } 7. column-count (Çok Kolonlu Düzen) .article { column-count: 3; /* 3 kolon - unitless */ } /* ❌ Birim kullanılamaz */ column-count: 3px; /* Geçersiz */ /* Responsive kolonlar */ .masonry { column-count: 1; } @media (min-width: 768px) { .masonry { column-count: 2; } } @media (min-width: 1024px) { .masonry { column-count: 3; } } 8. Animation ve Transform'da Unitless /* animation-iteration-count */ .element { animation: spin 2s infinite; /* infinite = unitless */ animation-iteration-count: 3; /* 3 kez - unitless */ } /* ❌ Birim kullanılamaz */ animation-iteration-count: 3px; /* Geçersiz */ /* transform: scale() */ .element { transform: scale(1.5); /* 1.5 katı - unitless */ transform: scale(2); /* 2 katı */ transform: scale(0.5); /* Yarısı */ /* İki eksende farklı */ transform: scale(2, 1.5); /* X: 2x, Y: 1.5x */ } /* transform: rotate() için derece GEREKIR */ transform: rotate(45deg); /* ✅ Doğru */ transform: rotate(45); /* ❌ Geçersiz */ Unitless vs Birimli - Karşılaştırma Line-height Detaylı Karşılaştırma /* Senaryo 1: Sabit değer (px) */ .parent-px { font-size: 16px; line-height: 24px; } .child-px { font-size: 20px; /* line-height: 24px miras alınır */ /* 20px font için 24px satır yüksekliği = sıkışık */ } /* Senaryo 2: Yüzde */ .parent-percent { font-size: 16px; line-height: 150%; /* = 24px olarak HESAPLANIR */ } .child-percent { font-size: 20px; /* line-height: 24px (hesaplanmış değer) miras alınır */ /* Yine sorunlu! */ } /* Senaryo 3: Em birimi */ .parent-em { font-size: 16px; line-height: 1.5em; /* = 24px olarak HESAPLANIR */ } .child-em { font-size: 20px; /* line-height: 24px miras alınır */ /* Aynı sorun! */ } /* Senaryo 4: Unitless ✅ */ .parent-unitless { font-size: 16px; line-height: 1.5; /* ORAN miras alınır */ } .child-unitless { font-size: 20px; /* line-height: 1.5 ORANI miras alınır */ /* = 20px * 1.5 = 30px - DOĞRU! */ } Unitless Numbers Kullanırken Dikkat Edilmesi Gerekenler 1. Line-height ile Calc Kullanımı /* ⚠️ Dikkatli ol */ .element { font-size: 16px; line-height: calc(1.5 + 0.2); /* = 1.7 - Unitless kalır ✅ */ line-height: calc(1.5 * 16px); /* = 24px - Birimli olur ❌ */ } /* ✅ Doğru kullanım */ .element { --line-height-base: 1.5; --line-height-adjust: 0.2; line-height: calc(var(--line-height-base) + var(--line-height-adjust)); /* Sonuç unitless kalır */ } Özet Unitless numbers CSS'in önemli bir konsepti ve belirli özellikler için zorunlu veya önerilen kullanım: Zorunlu unitless: opacity (0-1) z-index (integer) flex-grow / flex-shrink order column-count font-weight (100-900) animation-iteration-count transform: scale() aspect-ratio Şiddetle önerilen unitless: line-height (miras davranışı için kritik) Anahtar avantaj: Özellikle line-height için unitless kullanım, miras mekanizmasının doğru çalışmasını sağlar ve responsive tasarımda beklenmedik sorunları önler. Modern web tasarımında unitless numbers, temiz, maintainable ve tahmin edilebilir kod yazmak için temel taşlardan biridir!
  6. Doğuhan ELMA

    CSS calc() Fonksiyonu

    calc() fonksiyonu, CSS'te matematiksel hesaplamalar yapmamızı sağlayar. calc() CSS fonksiyonu, modern web tasarımında en çok duyarlı (responsive), esnek (flexible) ve hassas (precise) düzenler oluşturmak amacıyla kullanılır. Sabit birimler (px, pt, cm gibi) → viewport değişse bile değişmez. Örneğin calc(100px + 50px) her zaman 150px olur. Göreceli birimler (%, vw, vh, em, rem gibi) → viewport veya parent(mesela javascript ile) element boyutu değiştiğinde yeniden hesaplanır. Temel Sözdizimi .element { width: calc(100% - 50px); /* calc(değer operator değer) */ } Desteklenen operatörler: + (toplama) - (çıkarma) * (çarpma) / (bölme) Kritik Kurallar 1. Boşluk Kuralları /* ✅ DOĞRU */ width: calc(100% - 20px); width: calc(100% + 20px); /* ❌ YANLIŞ - toplama/çıkarmada boşluk ŞART */ width: calc(100%-20px); width: calc(100%+20px); /* ✅ DOĞRU - çarpma/bölmede boşluk opsiyonel */ width: calc(100% / 2); width: calc(100%/2); width: calc(2 * 50px); width: calc(2*50px); Neden? CSS parser'ı 100%-20px ifadesini tek bir identifier olarak görebilir. Boşluk, operatörü netleştirir. 2. Farklı Birimleri Karıştırma calc()'ın en güçlü özelliği farklı birimleri bir araya getirebilmesi: .element { /* Yüzde + piksel */ width: calc(100% - 40px); /* Viewport + rem */ height: calc(100vh - 3rem); /* Em + piksel */ padding: calc(2em + 10px); /* Viewport genişliği + px */ font-size: calc(16px + 1vw); /* Ch (karakter genişliği) + rem */ max-width: calc(60ch + 2rem); } 3. Bölme İşleminde Özel Durum /* ✅ DOĞRU - saf sayı ile bölme */ width: calc(100% / 3); width: calc(100px / 2); /* ❌ YANLIŞ - iki birimli değeri bölme */ width: calc(100% / 50%); /* Geçersiz */ width: calc(100px / 20px); /* Geçersiz */ /* ✅ DOĞRU - birimli / saf sayı */ width: calc(100% / 3); padding: calc(2rem / 1.5); Kural: Bölme işleminde bölen saf sayı olmalı, birim taşımamalı. 4. Çarpma İşleminde Özel Durum /* ✅ DOĞRU */ width: calc(50px * 2); width: calc(2 * 50px); width: calc(100% * 0.5); /* ❌ YANLIŞ - iki birimli değeri çarpma */ width: calc(50px * 20px); /* Geçersiz */ width: calc(100% * 50%); /* Geçersiz */ Kural: Çarpma işleminde en az bir değer saf sayı olmalı. Gerçek Dünya Kullanım Senaryoları 1. Layout ve Spacing /* Sidebar + Content Layout */ .layout { display: flex; } .sidebar { width: 250px; } .content { width: calc(100% - 250px); /* Kalan alanı doldurur */ } /* Grid ile daha iyi alternatif */ .layout-grid { display: grid; grid-template-columns: 250px calc(100% - 250px); /* veya daha iyi: */ grid-template-columns: 250px 1fr; /* flex yerine */ } /* Container padding hariç genişlik */ .container { width: 1200px; padding: 0 2rem; } .inner { /* Parent genişliği - (padding * 2) */ width: calc(100% - 4rem); max-width: calc(1200px - 4rem); } 2. Viewport Tabanlı Hesaplamalar /* Full-height minus header/footer */ .main-content { min-height: calc(100vh - 80px - 60px); /* viewport - header - footer */ } /* Full viewport with safe margins */ .hero { height: calc(100vh - 4rem); /* Mobile için güvenli alan */ } /* Dynamic viewport units (dvh) ile */ .modern-hero { height: calc(100dvh - 4rem); /* Mobil tarayıcı UI'ını dikkate alır */ } /* Sticky footer pattern */ body { min-height: 100vh; display: flex; flex-direction: column; } main { flex: 1; /* veya calc ile: */ min-height: calc(100vh - 80px); } 3. Responsive Typography /* Fluid typography - basit */ h1 { font-size: calc(1.5rem + 2vw); /* Base 1.5rem + viewport'a göre büyüme */ } /* Bounded fluid typography */ h1 { font-size: calc(1.5rem + 2vw); font-size: clamp(2rem, calc(1.5rem + 2vw), 4rem); /* Min 2rem, ideal calc(...), max 4rem */ } /* Line height calculation */ p { font-size: 1rem; line-height: calc(1em + 0.5rem); /* Em ile rem kombinasyonu - responsive line-height */ } Dinamik Spacing /* Ekran boyutuna göre artan boşluk */ .section { padding-block: calc(2rem + 5vh); /* Minimum 2rem + viewport'un %5'i */ padding-inline: calc(1rem + 3vw); /* Yanlarda responsive boşluk */ } /* Modular scale */ .heading-1 { font-size: calc(1rem * 2.5); } /* 40px */ .heading-2 { font-size: calc(1rem * 2); } /* 32px */ .heading-3 { font-size: calc(1rem * 1.5); } /* 24px */ .body { font-size: 1rem; } /* 16px */ .small { font-size: calc(1rem * 0.875); } /* 14px */ Position ve Transform /* Tam ortalama */ .centered { position: absolute; top: calc(50% - 50px); left: calc(50% - 100px); /* Daha iyi alternatif: transform */ top: 50%; left: 50%; transform: translate(-50%, -50%); } /* Offset positioning */ .tooltip { position: absolute; bottom: calc(100% + 10px); /* Element'in üstünde, 10px boşlukla */ left: calc(50% - 75px); width: 150px; } Custom Properties ile Kombinasyon :root { --header-height: 80px; --footer-height: 60px; --sidebar-width: 250px; --gap: 2rem; --container-max: 1200px; } .main-content { min-height: calc(100vh - var(--header-height) - var(--footer-height)); padding: var(--gap); } .content-area { width: calc(100% - var(--sidebar-width) - var(--gap)); } .responsive-container { width: min(var(--container-max), calc(100% - var(--gap) * 2)); margin-inline: auto; } Performans Notları /* ⚠️ Dikkat - Sürekli hesaplama */ .animated { /* Her frame'de hesaplanır */ width: calc(100% - 20px); transition: width 0.3s; } /* ✅ Daha iyi - Sabit değer */ :root { --dynamic-width: calc(100% - 20px); } .animated { width: var(--dynamic-width); transition: width 0.3s; } calc() modern tarayıcılarda çok hızlı, ancak karmaşık hesaplamalar (özellikle animasyonlarda) CPU kullanımını artırabilir. Kural: Modern layout için flex/grid kullan, calc() ince ayarlar için sakla. Yaygın Hatalar /* ❌ Parantez eksik */ width: calc 100% - 20px; /* ❌ Boşluk eksik */ width: calc(100%-20px); /* ❌ Birim eksik */ width: calc(100% - 20); /* ❌ Geçersiz bölme */ width: calc(100% / 50%); /* ❌ İç içe calc() - gereksiz */ width: calc(calc(100% - 20px) - 10px); /* ✅ Doğru - tek calc() yeterli */ width: calc(100% - 20px - 10px); width: calc(100% - 30px); Özet calc() fonksiyonu modern CSS'in en pratik araçlarından biri. Farklı birimleri birleştirerek, matematiksel hesaplamalar yaparak, responsive tasarımları kolaylaştırıyor. Özellikle: Custom properties ile güçlü Container/viewport birimler ile esnek min(), max(), clamp() ile kombine edilebilir Grid ve flexbox'ı tamamlar (yerini almaz) Performansı çok iyi Modern web'de calc() bilmeden responsive tasarım yapmak neredeyse imkansız!
  7. Modern CSS'in en güçlü araçlarından ikisi olan min() ve max() fonksiyonları, responsive tasarımda dinamik değerler oluşturmamızı sağlıyor. Temel Mantık min() fonksiyonu: Verilen değerlerden en küçüğünü seçer max() fonksiyonu: Verilen değerlerden en büyüğünü seçer /* min() - en küçük değeri kullanır */ width: min(500px, 100%); /* Ekran 500px'den küçükse 100% kullanır, büyükse 500px kullanır */ /* max() - en büyük değeri kullanır */ width: max(300px, 50%); /* 50% değeri 300px'den küçükse 300px kullanır, büyükse 50% kullanır */ Gerçek Dünya Senaryoları 1. Maksimum Genişlik Sınırlaması (min ile) .container { /* Klasik yöntem */ width: 100%; max-width: 1200px; /* Modern yöntem - tek satırda */ width: min(1200px, 100%); /* veya daha esnek */ width: min(1200px, 100% - 2rem); /* yanlarda boşluk bırakır */ } Neden min() kullanıyoruz? Çünkü container'ın 1200px'i aşmamasını istiyoruz. Ekran küçülünce min() otomatik olarak daha küçük değeri (100%) seçer. 2. Minimum Genişlik Garantisi (max ile) .button { /* Buton asla 120px'den küçük olmayacak */ width: max(120px, 30%); /* Ekran çok küçükse bile minimum 120px kalır */ } .sidebar { /* Sidebar minimum 250px, ideal 20% genişlikte */ width: max(250px, 20vw); } 3. Tipografi ve Okuma Rahatlığı .article { /* Metin satırları optimal okuma için 65 karakter civarı */ max-width: min(65ch, 90%); /* ch birimi = 0 karakterinin genişliği */ } .heading { /* Başlıklar ekranda çok uzun açılmasın */ max-width: min(20ch, 100%); } 4. Responsive Padding/Margin .section { /* Küçük ekranda 5%, büyük ekranda max 60px */ padding-inline: min(5vw, 60px); } .card { /* Minimum 1rem, maksimum ekranın %3'ü kadar boşluk */ gap: min(3vw, 2rem); } Birden Fazla Değer Kullanma Her iki fonksiyon da 2'den fazla değer kabul eder: .responsive-box { /* 3 değerden en küçüğünü seç */ width: min(600px, 80%, 90vw); /* Pratik kullanım */ padding: min(5%, 3rem, 40px); } .flexible-grid { /* Grid kolonları için */ grid-template-columns: repeat(auto-fit, minmax( max(250px, 30%), /* minimum genişlik */ 1fr )); } Calc() ile Kombinasyon En güçlü kullanım calc() ile birleştirme: .smart-container { /* Ekran genişliğinin 90%'ı ama max 1400px, ve her iki yanda 2rem boşluk garantili */ width: min(1400px, 100% - 4rem); margin-inline: auto; } .dynamic-spacing { /* Ekran büyüdükçe artan ama sınırlı boşluk */ padding: max(1rem, min(5vw, 4rem)); } Avantajları Media Query Azaltır: Çoğu durumda breakpoint'e gerek kalmaz Daha Maintainable: Tek satırda responsive davranış tanımlanır Performans: Tarayıcı runtime'da hesaplar, JavaScript gerekmez Kapsayıcı Tasarım: Farklı ekran boyutları için doğal adaptasyon Karşılaştırma: Eski vs Yeni Yöntem /* ❌ Eski yöntem - media query gerekir */ .container { width: 100%; } @media (min-width: 1200px) { .container { width: 1200px; } } /* ✅ Modern yöntem - tek satır */ .container { width: min(1200px, 100%); } Tarayıcı Desteği Modern tarayıcıların tümü bu fonksiyonları destekliyor (2020'den beri). Eski tarayıcılar için fallback: .element { width: 90%; /* Fallback */ width: min(1200px, 90%); /* Modern tarayıcılar için */ } Özet min() ve max() fonksiyonları modern CSS'in intrinsic design (içsel tasarım) felsefesinin temel taşları. Media query yazmadan, JavaScript kullanmadan, sadece CSS ile gerçekten responsive ve akıllı layoutlar oluşturmamızı sağlıyorlar. Özellikle clamp() fonksiyonu ile birlikte kullanıldığında, modern web tasarımının vazgeçilmez araçları haline geliyorlar.
  8. PHP'nin 30 yıllık evrimini derinlemesine inceleyelim. 1. Başlangıç Dönemi (1994-1997) PHP/FI (Personal Home Page / Forms Interpreter) - 1994 Rasmus Lerdorf tarafından kendi kişisel web sitesini yönetmek için C dilinde yazılan basit CGI scriptleri olarak başladı. İlk versiyonda: Basit değişken sistemi Form işleme yetenekleri Ziyaretçi sayacı gibi temel araçlar PHP/FI 2.0 - 1995-1996 SQL desteği eklendi (mSQL) Gerçek bir programlama dili haline gelmeye başladı Ancak hala çok sınırlı ve kişisel kullanıma yönelikti 2. Modern PHP'nin Temeli (1997-2000) PHP 3.0 - Haziran 1997 Zeev Suraski ve Andi Gutmans, PHP'yi tamamen yeniden yazdılar. Bu versiyon PHP'yi ciddi bir web programlama diline dönüştürdü. Önemli Yenilikler: Nesne yönelimli programlama desteği (çok basit düzeyde) Modüler genişletilebilir mimari Çok sayıda veritabanı desteği (MySQL, PostgreSQL, Oracle) ODBC desteği Üçüncü parti API'leri için destek Daha tutarlı sözdizimi Özellikler: // PHP 3'te basit class kullanımı class User { var $name; var $email; function setName($name) { $this->name = $name; } } PHP 4.0 - 22 Mayıs 2000 Zend Engine 1.0 ile geldi. Bu, PHP'nin performansını önemli ölçüde artırdı. Gelen Özellikler: Zend Engine: PHP'nin çekirdeği tamamen yeniden yazıldı Session yönetimi (built-in) Output buffering (ob_start, ob_get_contents) Gelişmiş array fonksiyonları Referanslar ve referans sayma sistemi HTTP_GET_VARS, HTTP_POST_VARS gibi süper global'ler (henüz $_GET yoktu) COM/DCOM desteği (Windows için) Java ile entegrasyon Perl Compatible Regular Expressions (PCRE) // Session kullanımı session_start(); $_SESSION['user_id'] = 123; // Output buffering ob_start(); echo "Bu buffer'da"; $content = ob_get_clean(); Sorunlar: OOP desteği hala çok zayıftı Objeler değer olarak kopyalanıyordu (referans değil) Namespace yoktu Exception handling yoktu 3. OOP Devrimi (2004-2009) PHP 5.0 - 13 Temmuz 2004 Zend Engine 2.0 ile geldi. PHP'yi modern bir OOP diline dönüştürdü. Devrim Niteliğinde Özellikler: 1. Gerçek OOP Desteği: // Visibility modifiers class User { private $password; protected $email; public $name; public function __construct($name) { $this->name = $name; } // Magic methods public function __toString() { return $this->name; } } // Inheritance class Admin extends User { public function deleteUser() { // ... } } // Interfaces interface Loggable { public function log($message); } // Abstract classes abstract class BaseController { abstract public function handle(); } 2. Exception Handling: try { throw new Exception("Bir hata oluştu"); } catch (Exception $e) { echo $e->getMessage(); } finally { // PHP 5.5'te eklendi // Cleanup } 3. Type Hinting (sadece class ve array): function processUser(User $user, array $options) { // ... } 4. Diğer Özellikler: Objeler artık referans olarak geçiliyor Iterators ve SPL (Standard PHP Library) Reflection API SimpleXML MySQLi (MySQL Improved Extension) PDO (PHP Data Objects) // PDO ile veritabanı $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'); $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([1]); PHP 5.1 - 24 Kasım 2005 PDO varsayılan olarak aktif Performans iyileştirmeleri DateTime sınıfı PHP 5.2 - 2 Kasım 2006 JSON desteği (json_encode, json_decode) Zip archive desteği Filter extension (input validation) Improved memory management // JSON kullanımı $data = ['name' => 'Ali', 'age' => 25]; $json = json_encode($data); $decoded = json_decode($json, true); PHP 5.3 - 30 Haziran 2009 Çok önemli bir versiyon. Modern PHP'nin gerçek başlangıcı. Önemli Yenilikler: 1. Namespace: namespace App\Models; class User { // ... } // Kullanım use App\Models\User; $user = new User(); 2. Late Static Binding: class Parent { public static function who() { echo static::class; // PHP 5.3'te static:: } } class Child extends Parent {} Child::who(); // "Child" yazdırır 3. Closure (Anonim Fonksiyonlar): $multiply = function($x, $y) { return $x * $y; }; echo $multiply(3, 4); // 12 // use keyword ile dış scope'tan değişken kullanma $factor = 10; $multiplier = function($number) use ($factor) { return $number * $factor; }; 4. Diğer Özellikler: goto statement (tartışmalı) Nowdoc syntax (tek tırnaklı heredoc) __DIR__ magic constant Ternary shorthand: $x ?: 'default' Phar archives (PHP Archive) PHP 5.4 - 1 Mart 2012 Gelen Özellikler: 1. Traits: trait Logger { public function log($message) { echo $message; } } class User { use Logger; } $user = new User(); $user->log("Hello"); // Trait'ten gelen method 2. Short Array Syntax: // Eski $array = array(1, 2, 3); // Yeni $array = [1, 2, 3]; $assoc = ['name' => 'Ali', 'age' => 25]; 3. Built-in Web Server: php -S localhost:8000 4. Diğer Özellikler: Array dereferencing: function()[0] Callable type hint <?= always available (short echo tag) Binary number format: 0b001101 Session upload progress Çıkarılan Özellikler: register_globals - GÜVENLİK nedeniyle magic_quotes - GÜVENLİK nedeniyle safe_mode - GÜVENLİK nedeniyle PHP 5.5 - 20 Haziran 2013 1. Generators: function getNumbers() { for ($i = 0; $i < 1000; $i++) { yield $i; // Belleği şişirmeden büyük veri setleri } } foreach (getNumbers() as $number) { echo $number; } 2. finally Block: try { // kod } catch (Exception $e) { // hata } finally { // her durumda çalışır } 3. Password Hashing API: // Güvenli şifre hash'leme $hash = password_hash("mypassword", PASSWORD_DEFAULT); $verify = password_verify("mypassword", $hash); 4. Diğer: empty() ile expressions kullanımı Array and string literal dereferencing OPcache (APC'nin yerini aldı) ::class keyword echo User::class; // "User" string'ini döner PHP 5.6 - 28 Ağustos 2014 1. Variadic Functions: function sum(...$numbers) { return array_sum($numbers); } echo sum(1, 2, 3, 4); // 10 2. Argument Unpacking: $array = [1, 2, 3]; function add($a, $b, $c) { return $a + $b + $c; } echo add(...$array); // 6 3. Constant Expressions: const ARRAY = [1, 2, 3]; const TWO = 1 + 1; 4. Diğer: Exponential operator: 2 ** 3 = 8 use function ve use const Large file uploads (>2GB) phpdbg debugger 4. Modern PHP Çağı (2015-2020) PHP 7.0 - 3 Aralık 2015 DEVASA PERFORMANS ARTIŞI - Zend Engine 3.0 Bu versiyon PHP tarihindeki en önemli sıçramalardan biri. %50-200 performans artışı ve %50 bellek kullanımı azalması. Scalar Type Declarations: function add(int $a, int $b): int { return $a + $b; } declare(strict_types=1); // Strict mode Return Type Declarations: function getUser(): ?User { // Nullable return return null; } function getData(): array { return []; } Null Coalescing Operator: // Eski $name = isset($_GET['name']) ? $_GET['name'] : 'Guest'; // Yeni $name = $_GET['name'] ?? 'Guest'; Spaceship Operator: echo 1 <=> 2; // -1 echo 2 <=> 2; // 0 echo 3 <=> 2; // 1 // Sorting'te kullanımı usort($array, function($a, $b) { return $a <=> $b; }); Anonymous Classes: $logger = new class { public function log($message) { echo $message; } }; Group Use Declarations: use App\Models\{User, Post, Comment}; Diğer Özellikler: Unicode codepoint escape syntax: \u{1F602} Uniform variable syntax Throwable interface (Exception ve Error için ortak parent) Closure::call() Çıkarılanlar: mysql extension (mysqli ve PDO kullanılmalı) ereg extension (preg kullanılmalı) $HTTP_RAW_POST_DATA ASP ve script PHP tags: <% %>, <script language="php"> PHP 7.1 - 1 Aralık 2016 Nullable Types: function process(?string $name): ?int { return $name ? strlen($name) : null; } Void Return Type: function log(string $message): void { echo $message; } Symmetric Array Destructuring: // Short list syntax [$a, $b] = [1, 2]; // Keyed arrays ['name' => $name, 'age' => $age] = $user; Class Constant Visibility: class User { private const SECRET = 'hidden'; protected const CONFIG = 'protected'; public const VERSION = '1.0'; } Multi-catch: try { // kod } catch (TypeError | ValueError $e) { // Her ikisi için de aynı handler } Iterable Type: function process(iterable $data): void { foreach ($data as $item) { // array veya Traversable kabul eder } } PHP 7.2 - 30 Kasım 2017 Object Type Hint: function process(object $obj): object { return $obj; } Abstract Method Overriding: abstract class A { abstract function test(string $s); } abstract class B extends A { // Parameter type'ı kaldırabilir (daha esnek) abstract function test($s): int; } Parameter Type Widening: Child class'larda parent'ın type hint'i kaldırılabilir. Trailing Commas: $array = [ 'first', 'second', 'third', // Son virgül artık izinli ]; Diğer: count() ile non-countable için warning Sodium extension (modern kriptografi) Argon2 password hashing Deprecated: each() function (unset) cast __autoload() function PHP 7.3 - 6 Aralık 2018 Flexible Heredoc/Nowdoc: // Daha esnek indentation function test() { return <<<'END' Bu artık daha esnek END; } Array Destructuring with Reference: $array = [1, 2]; [&$a, $b] = $array; $a = 10; // $array artık [10, 2] is_countable() Function: if (is_countable($var)) { count($var); } Trailing Commas in Function Calls: function test($a, $b, $c) {} test( 1, 2, 3, // Artık izinli ); PHP 7.4 - 28 Kasım 2019 Bu versiyon modern PHP'nin temelini attı. Typed Properties: class User { public int $id; public string $name; public ?string $email = null; private array $roles; public function __construct(int $id) { $this->id = $id; } } Arrow Functions: // Eski $multiply = function($x) use ($factor) { return $x * $factor; }; // Yeni (otomatik use) $multiply = fn($x) => $x * $factor; // Array fonksiyonlarında $numbers = array_map(fn($n) => $n * 2, [1, 2, 3]); Null Coalescing Assignment: // Eski $data['key'] = $data['key'] ?? 'default'; // Yeni $data['key'] ??= 'default'; Array Spread Operator: $array1 = [1, 2, 3]; $array2 = [4, 5]; $result = [...$array1, ...$array2]; // [1, 2, 3, 4, 5] // Associative arrays (numeric keys için) $array = ['a' => 1, ...['b' => 2]]; Numeric Literal Separator: $number = 1_000_000; // Okunabilirlik için $hex = 0xFF_FF_FF; Weak References: $obj = new stdClass; $weakRef = WeakReference::create($obj); Covariant Returns & Contravariant Parameters: class Animal {} class Dog extends Animal {} class AnimalShelter { public function get(Dog $dog): Animal { return new Animal(); } } class DogShelter extends AnimalShelter { // Covariant return: daha spesifik dönebilir public function get(Dog $dog): Dog { return new Dog(); } } Preloading: Opcache'e dosyaları önceden yükleme - ciddi performans artışı. Deprecated: Nested ternary without parentheses array_key_exists() ile objects 5. Modern PHP ve Tür Sistemi (2020-2024) PHP 8.0 - 26 Kasım 2020 BÜYÜK YENİLİKLER DOLU VERSİYON JIT (Just-In-Time) Compiler: Belirli senaryolarda %30-40 performans artışı. Union Types: function process(int|float $number): int|float { return $number * 2; } class Number { private int|float $value; } Named Arguments: function createUser( string $name, string $email, bool $active = true, int $age = 18 ) {} // İstediğin parametreyi gönder createUser( email: 'ali@example.com', name: 'Ali', age: 25 ); Attributes (Annotations): #[Route('/users', methods: ['GET'])] #[Authenticated] class UserController { #[Cache(ttl: 3600)] public function index(): array { return []; } } // Reflection ile okuma $attributes = (new ReflectionClass(UserController::class)) ->getAttributes(Route::class); Match Expression: // Eski switch switch ($status) { case 'draft': $message = 'Taslak'; break; case 'published': $message = 'Yayında'; break; default: $message = 'Bilinmeyen'; } // Yeni match (daha güvenli, return eder) $message = match($status) { 'draft' => 'Taslak', 'published' => 'Yayında', default => 'Bilinmeyen', }; // Multiple conditions $result = match($value) { 1, 2, 3 => 'Küçük', 4, 5, 6 => 'Orta', default => 'Büyük', }; Constructor Property Promotion: // Eski class User { private string $name; private string $email; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } } // Yeni class User { public function __construct( private string $name, private string $email, ) {} } Nullsafe Operator: // Eski $country = null; if ($user !== null) { $address = $user->getAddress(); if ($address !== null) { $country = $address->country; } } // Yeni $country = $user?->getAddress()?->country; Mixed Type: function process(mixed $value): mixed { // Her şeyi kabul eder return $value; } Static Return Type: class Model { public static function create(): static { return new static(); } } Throw Expression: $value = $input ?? throw new Exception('Input required'); $callback = fn() => throw new Exception('Not implemented'); Weak Maps: $map = new WeakMap(); $obj = new stdClass; $map[$obj] = 'data'; // $obj silindiğinde map'ten de silinir Diğer: str_contains(), str_starts_with(), str_ends_with() get_debug_type() function ::class on objects Çıkarılanlar/Deprecated: Birçok eski, güvenli olmayan özellik PHP 8.1 - 25 Kasım 2021 Enums (Enumerations): // Pure enum enum Status { case Draft; case Published; case Archived; } $status = Status::Published; // Backed enum (değer içerir) enum Status: string { case Draft = 'draft'; case Published = 'published'; case Archived = 'archived'; } // Methods ve daha fazlası enum Status: string { case Draft = 'draft'; case Published = 'published'; public function label(): string { return match($this) { self::Draft => 'Taslak', self::Published => 'Yayında', }; } } $status = Status::from('draft'); // String'den enum Readonly Properties: class User { public function __construct( public readonly string $name, public readonly int $age, ) {} } $user = new User('Ali', 25); $user->name = 'Veli'; // HATA! Readonly değiştirilemez First-class Callable Syntax: // Eski $fn = Closure::fromCallable('strlen'); $fn = Closure::fromCallable([$obj, 'method']); // Yeni $fn = strlen(...); $fn = $obj->method(...); // Array functions ile array_map(strtoupper(...), $strings); Intersection Types: interface Loggable {} interface Cacheable {} function process(Loggable&Cacheable $obj) { // $obj her iki interface'i de implement etmeli } New in Initializers: class Service { public function __construct( private Logger $logger = new Logger(), ) {} } // Attribute'lerde de #[Route(new PathPrefix('/api'))] class ApiController {} Pure Intersection Types: function process((Countable&Iterator)|array $data) { // ... } Never Return Type: function redirect(string $url): never { header("Location: $url"); exit; } function throwException(): never { throw new Exception(); } Final Class Constants: class Config { final public const VERSION = '1.0'; } class ExtendedConfig extends Config { public const VERSION = '2.0'; // HATA! } Explicit Octal Notation: // Eski $octal = 0755; // Karışık // Yeni $octal = 0o755; // Açık ve net Fibers: Asenkron programlama için düşük seviye primitive: $fiber = new Fiber(function (): void { $value = Fiber::suspend('İlk değer'); echo "Devam ediyor: $value\n"; }); $fiber->start(); $fiber->resume('İkinci değer'); Diğer: Array unpacking with string keys array_is_list() function fsync(), fdatasync() Deprecated: Passing null to non-nullable internal function parameters Serializable interface PHP 8.2 - 8 Aralık 2022 Readonly Classes: readonly class User { public function __construct( public string $name, public int $age, ) {} // Tüm property'ler otomatik readonly } Disjunctive Normal Form (DNF) Types: // Karmaşık type combinations function process((Countable&ArrayAccess)|null $data) { // ... } class Repository { private (PDO&Loggable)|(mysqli&Loggable)|null $connection; } True Type: function isValid(): true { // Sadece true dönebilir, false dönemez return true; } Constants in Traits: trait HasVersion { public const VERSION = '1.0'; public function getVersion(): string { return self::VERSION; } } Deprecated Dynamic Properties: // Artık deprecated $obj = new stdClass; $obj->dynamicProperty = 'value'; // Deprecated warning // İzin vermek için #[AllowDynamicProperties] class MyClass {} Diğer: Random Extension (modern rastgele sayı üretimi) mysqli_execute_query() function curl_upkeep() Sensitive parameter redaction Deprecated: Dynamic properties (yukarıda belirtildi) utf8_encode() ve utf8_decode() ${var} string interpolation PHP 8.3 - 23 Kasım 2023 Typed Class Constants: class Config { public const string VERSION = '1.0'; public const int MAX_USERS = 100; private const array SETTINGS = []; } Override Attribute: class Parent { public function test(): void {} } class Child extends Parent { #[Override] // Parent'ta yoksa hata verir public function test(): void {} } Dynamic Class Constant Fetch: class Config { const string DEFAULT = 'value'; } $name = 'DEFAULT'; echo Config::{$name}; // Dynamic Anonymous Readonly Classes: $user = new readonly class('Ali', 25) { public function __construct( public string $name, public int $age, ) {} }; json_validate() Function: // JSON parse etmeden validation if (json_validate($string)) { $data = json_decode($string); } Negative Array Indices: $array = ['a', 'b', 'c']; $array[-1] = 'd'; // Son eleman Diğer: mb_str_pad() function stream_context_set_options() improvements Randomizer additions Command line linter supports multiple files Deprecated: Implicitly nullable parameter declarations MT_RAND_PHP mode PHP 8.4 - 21 Kasım 2024 (En Güncel) Property Hooks: class User { // Virtual property - backing field yok public string $fullName { get => $this->firstName . ' ' . $this->lastName; } // Lazy loading private array $data { get => $this->data ??= $this->loadData(); } // Validation public int $age { set(int $value) { if ($value < 0) { throw new ValueError(); } $this->age = $value; } } } Asymmetric Visibility: class User { // Public okunabilir, private yazılabilir public private(set) string $name; // Protected set public protected(set) int $age; public function __construct(string $name) { $this->name = $name; // Sadece sınıf içinde } } $user = new User('Ali'); echo $user->name; // OK $user->name = 'Veli'; // HATA! new Without Parentheses: // Eski $request = (new Request())->withMethod('POST'); // Yeni $request = new Request()->withMethod('POST'); HTML5 Support in DOM: $dom = DOM\HTMLDocument::createFromString($html, LIBXML_NOERROR); Array Find Functions: $array = [1, 2, 3, 4, 5]; // İlk eşleşeni bul $first = array_find($array, fn($n) => $n > 2); // 3 // İlk key'i bul $key = array_find_key($array, fn($n) => $n > 2); // 2 // any/all $hasEven = array_any($array, fn($n) => $n % 2 === 0); // true $allEven = array_all($array, fn($n) => $n % 2 === 0); // false #[Deprecated] Attribute: class OldClass { #[Deprecated( message: "Use NewClass instead", since: "2.0" )] public function oldMethod(): void {} } Lazy Objects: // Proxy pattern için built-in destek $user = new ReflectionClass(User::class) ->newLazyProxy(function() { return new User(); }); Diğer: request_parse_body() function PDO driver-specific subclasses OpenSSL EC key support bcround(), bcfloor(), bcceil() functions Özet: PHP'nin Evrimi Önemli Dönüm Noktaları: PHP 3 (1997): Gerçek programlama dili PHP 4 (2000): Zend Engine, session, performance PHP 5 (2004): Gerçek OOP PHP 5.3 (2009): Namespace, closure - Modern PHP başlangıcı PHP 7 (2015): Devasa performans artışı, scalar types PHP 8 (2020): JIT, union types, attributes PHP 8.1 (2021): Enums, readonly PHP 8.4 (2024): Property hooks, asymmetric visibility Genel Trendler: Performans: Her versiyonda sürekli iyileşme Tür Güvenliği: Gitgide güçlenen type system Modern OOP: C#/Java benzeri özelliklere yakınsama Güvenlik: Tehlikeli özelliklerin kaldırılması Developer Experience: Daha az kod, daha çok ifade gücü PHP artık eski "kötü" imajından çok uzak, modern, güvenli ve performanslı bir dil haline gelmiş durumda.
  9. Doğuhan ELMA

    CSS'de PX (Pixel) Birimi

    Pixel, CSS'in en eski ve en tartışmalı birimidir. "Absolute unit" olarak sınıflandırılsa da, aslında durum biraz daha karmaşık. Detaylı açıklayayım. 1. PX Nedir? (Teknik Gerçek) CSS Pixel ≠ Fiziksel Pixel CSS Pixel (Reference Pixel) ↓ Device Independent Pixel (DIP) ↓ Physical Pixel (gerçek ekran pikselleri) Önemli: 1px CSS'de her zaman aynı fiziksel boyut DEĞİLDİR! Pixel Density (DPR - Device Pixel Ratio) // Tarayıcı konsolunda console.log(window.devicePixelRatio); // Sonuçlar: // - Normal ekran: 1 (1 CSS px = 1 fiziksel pixel) // - Retina/HiDPI: 2 (1 CSS px = 4 fiziksel pixel - 2×2) // - 4K ekran: 3 veya 4 (1 CSS px = 9 veya 16 fiziksel pixel) Örnek: .line { border: 1px solid black; } Normal ekran (DPR=1): 1 fiziksel pixel kalınlığında Retina (DPR=2): 2 fiziksel pixel kalınlığında 4K (DPR=3): 3 fiziksel pixel kalınlığında Sonuç: 1px her cihazda yaklaşık aynı görsel boyutta görünür, ama farklı sayıda fiziksel pixel kullanır. 2. PX'in Tarihi ve Evolüsyonu 1990'lar - Mutlak Kontrol Dönemi /* O zamanlar herkes 800×600 veya 1024×768 ekran kullanıyordu */ body { width: 960px; /* Sabit genişlik */ font-size: 12px; margin: 0; padding: 0; } .header { height: 80px; } .content { width: 720px; float: left; } .sidebar { width: 240px; float: right; } ✅ O dönem için avantajlar: Pixel-perfect tasarım Öngörülebilir görünüm Basit hesaplama ❌ Sorunlar: Farklı çözünürlüklerde bozulma Responsive değil Erişilebilirlik sıfır 2000'ler - Responsive Farkındalık /* Media query'ler başladı */ .container { width: 960px; } @media (max-width: 768px) { .container { width: 100%; } } 2010'lar - Relative Units Yükselişi /* REM/EM/% popüler oldu */ html { font-size: 16px; /* Base */ } body { font-size: 1rem; /* 16px */ } h1 { font-size: 2.5rem; /* 40px */ } 2020+ Modern Dönem - Hybrid Yaklaşım /* PX hala kullanılıyor, ama doğru yerlerde */ .icon { width: 24px; /* Sabit boyut - OK */ } .container { max-width: 1200px; /* Maksimum sınır - OK */ padding: 2rem; /* Spacing - relative birim */ } h1 { font-size: clamp(2rem, 3vw + 1rem, 4rem); /* Fluid - relative */ } 3. PX Ne Zaman Kullanılmali? (Modern Yaklaşım) ✅ PX KULLAN - Doğru Kullanım Alanları 1. Border Width (Çerçeve Kalınlığı) /* ✅ DOĞRU - Border için px ideal */ .card { border: 1px solid #ccc; border-bottom: 2px solid blue; } /* ❌ YANLIŞ - REM ile border garip durur */ .card { border: 0.0625rem solid #ccc; /* 1px ama karmaşık */ } Neden px? Border her zaman keskin ve net olmalı 1px altı değerler anlamsız Kullanıcı font-size değiştirince border kalınlığı değişmemeli 2. Box Shadow (Gölgeler) /* ✅ DOĞRU */ .card { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } /* ✅ Daha büyük gölge */ .modal { box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2); } /* ❌ YANLIŞ - rem ile gölge değişir */ .card { box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.1); /* Kullanıcı font büyütünce gölge de büyür - garip */ } 3. Sabit Boyutlu Elementler (Icons, Avatars) /* ✅ İkonlar her zaman sabit boyut */ .icon { width: 24px; height: 24px; } .icon-small { width: 16px; height: 16px; } .icon-medium { width: 24px; height: 24px; } .icon-large { width: 32px; height: 32px; } .icon-xl { width: 48px; height: 48px; } /* ✅ Avatar'lar */ .avatar { width: 40px; height: 40px; border-radius: 50%; } /* ✅ Logo */ .logo { width: 180px; height: auto; } Neden px? İkonlar text boyutundan bağımsız olmalı Grid sistemlerde düzenli hizalama için Tasarım sisteminde tutarlılık 4. Max-Width Constraints (Maksimum Genişlik Sınırları) /* ✅ DOĞRU - Container max-width */ .container { width: 100%; /* Responsive */ max-width: 1200px; /* Ama çok büyük ekranlarda sınırla */ margin: 0 auto; } /* ✅ Content width */ .article { max-width: 65ch; /* Karakter bazlı (ideal) */ /* VEYA */ max-width: 700px; /* Pixel bazlı (da OK) */ } /* ✅ Modal width */ .modal { width: 90%; max-width: 600px; } Neden px? Tasarım kontrolü için üst sınır Çok geniş ekranlarda okunabilirlik Layout'un bozulmasını önle 5. Media Query Breakpoints /* ✅ DOĞRU - px breakpoint'ler yaygın */ /* Mobile first */ .grid { display: grid; grid-template-columns: 1fr; gap: 1rem; } @media (min-width: 640px) { /* sm */ .grid { grid-template-columns: repeat(2, 1fr); } } @media (min-width: 768px) { /* md */ .grid { grid-template-columns: repeat(3, 1fr); } } @media (min-width: 1024px) { /* lg */ .grid { grid-template-columns: repeat(4, 1fr); } } @media (min-width: 1280px) { /* xl */ .grid { grid-template-columns: repeat(5, 1fr); } } Alternatif - EM breakpoints: /* ✅ DA DOĞRU - em/rem daha erişilebilir */ @media (min-width: 40em) { /* 640px @ 16px base */ .grid { grid-template-columns: repeat(2, 1fr); } } @media (min-width: 48em) { /* 768px @ 16px base */ .grid { grid-template-columns: repeat(3, 1fr); } } Tartışma: PX: Viewport genişliğine göre (daha yaygın) EM: Kullanıcı font-size'ına da duyarlı (daha erişilebilir) 6. Çok Küçük Spacing Değerleri /* ✅ Çok küçük değerler için px daha net */ .divider { margin: 0; padding: 0; border-top: 1px solid #e0e0e0; } .tag { padding: 4px 8px; /* 0.25rem 0.5rem yerine */ border-radius: 3px; font-size: 0.75rem; } /* Grid gap çok küçükse */ .tight-grid { display: grid; gap: 8px; /* 0.5rem = 8px, ama px daha direkt */ } ❌ PX KULLANMA - Yanlış Kullanım Alanları 1. Font-Size (En Kritik Hata!) /* ❌ YANLIŞ - Erişilebilirlik ihlali */ html { font-size: 16px; } body { font-size: 14px; } h1 { font-size: 32px; } p { font-size: 16px; } Sorun: Kullanıcı tarayıcısında "Large fonts" seçse de değişmez Zoom yapınca oran bozulabilir WCAG erişilebilirlik kriterlerini ihlal eder /* ✅ DOĞRU - REM kullan */ html { font-size: 100%; /* 16px, ama kullanıcı ayarına saygılı */ } body { font-size: 1rem; /* 16px */ } h1 { font-size: 2rem; /* 32px */ /* VEYA fluid */ font-size: clamp(1.5rem, 3vw + 1rem, 3rem); } p { font-size: 1rem; } 2. Padding ve Margin (Spacing) /* ❌ YANLIŞ - Sabit spacing */ .section { padding: 60px 20px; margin-bottom: 40px; } .button { padding: 12px 24px; margin-right: 16px; } Sorun: Font-size değişince orantısız durur Responsive değil Komponentin iç tutarlılığı bozulur /* ✅ DOĞRU - Relative spacing */ .section { padding: 3.75rem 1.25rem; /* REM - global scale */ margin-bottom: 2.5rem; } .button { padding: 0.75em 1.5em; /* EM - component scale */ margin-right: 1em; font-size: 1rem; } EM vs REM Spacing: /* REM - Global consistency */ .card { padding: 2rem; /* Her zaman aynı (root'a göre) */ margin-bottom: 1.5rem; } /* EM - Component-based scaling */ .button-small { font-size: 0.875rem; padding: 0.5em 1em; /* Font-size'a göre ölçeklenir */ } .button-large { font-size: 1.25rem; padding: 0.5em 1em; /* Aynı em değeri, ama daha büyük */ } 3. Width ve Height (Layout) /* ❌ YANLIŞ - Sabit layout */ .sidebar { width: 300px; height: 600px; } .content { width: 900px; } Sorun: Responsive değil Farklı ekranlarda bozulur İçerik taşar /* ✅ DOĞRU - Flexible layout */ .layout { display: grid; grid-template-columns: 300px 1fr; /* Sidebar sabit OK, content flex */ gap: 2rem; } /* Veya tamamen flexible */ .layout { display: grid; grid-template-columns: minmax(250px, 300px) 1fr; gap: 2rem; } /* Mobil için responsive */ @media (max-width: 768px) { .layout { grid-template-columns: 1fr; } } 4. Line-Height /* ❌ YANLIŞ - Sabit line-height */ p { font-size: 16px; line-height: 24px; } h1 { font-size: 32px; line-height: 40px; } Sorun: Font-size değişince oran bozulur Responsive değil /* ✅ DOĞRU - Unitless veya relative */ p { font-size: 1rem; line-height: 1.5; /* Unitless - en iyi */ } h1 { font-size: 2rem; line-height: 1.2; } /* Veya em */ p { font-size: 1rem; line-height: 1.5em; /* Font-size × 1.5 */ } 4. PX vs Diğer Birimler - Karşılaştırma Font-Size Karşılaştırması /* Senaryo: Kullanıcı tarayıcıda font-size'ı 20px'e çıkardı */ /* PX - Değişmez (kötü) */ body { font-size: 16px; /* Hala 16px - kullanıcı tercihi görmezden gelindi */ } /* % - Kullanıcı tercihine uyar (iyi) */ html { font-size: 100%; /* 20px olur - kullanıcı ayarına uydu */ } /* REM - Root'a göre (en iyi) */ html { font-size: 100%; /* 20px */ } body { font-size: 1rem; /* 20px - kullanıcı ayarına uydu */ } h1 { font-size: 2rem; /* 40px - orantılı ölçeklendi */ } Spacing Karşılaştırması .component { font-size: 1rem; /* 16px → 20px (kullanıcı değiştirdi) */ } /* PX - Sabit kalır */ .px-spacing { padding: 16px 24px; /* Hala 16px 24px - orantısız */ } /* REM - Global scale */ .rem-spacing { padding: 1rem 1.5rem; /* 20px 30px - global scale ile ölçeklendi */ } /* EM - Component scale */ .em-spacing { padding: 1em 1.5em; /* 20px 30px - component font-size'a göre */ } Kullanıcı font-size artırınca: PX spacing: ┌────────────────┐ │ BUTTON │ ← Text büyük, padding küçük - sıkışık └────────────────┘ EM/REM spacing: ┌─────────────────────┐ │ BUTTON │ ← Her şey orantılı büyüdü └─────────────────────┘ 5. Modern Hybrid Yaklaşım Design System Örneği /* ========================================== MODERN DESIGN SYSTEM - HYBRID APPROACH ========================================== */ :root { /* ============= Sabit Değerler (PX) ============= */ /* Breakpoints */ --breakpoint-sm: 640px; --breakpoint-md: 768px; --breakpoint-lg: 1024px; --breakpoint-xl: 1280px; --breakpoint-2xl: 1536px; /* Container max-widths */ --container-sm: 640px; --container-md: 768px; --container-lg: 1024px; --container-xl: 1280px; /* Border widths */ --border-thin: 1px; --border-medium: 2px; --border-thick: 4px; /* Icon sizes */ --icon-xs: 16px; --icon-sm: 20px; --icon-md: 24px; --icon-lg: 32px; --icon-xl: 48px; /* ============= Relative Değerler (REM) ============= */ /* Spacing scale */ --space-xs: 0.25rem; /* 4px */ --space-sm: 0.5rem; /* 8px */ --space-md: 1rem; /* 16px */ --space-lg: 1.5rem; /* 24px */ --space-xl: 2rem; /* 32px */ --space-2xl: 3rem; /* 48px */ --space-3xl: 4rem; /* 64px */ /* Font sizes - Fluid */ --font-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem); --font-sm: clamp(0.875rem, 0.85rem + 0.13vw, 1rem); --font-base: clamp(1rem, 0.95rem + 0.25vw, 1.125rem); --font-lg: clamp(1.125rem, 1.05rem + 0.38vw, 1.313rem); --font-xl: clamp(1.25rem, 1.15rem + 0.5vw, 1.563rem); --font-2xl: clamp(1.5rem, 1.35rem + 0.75vw, 1.953rem); --font-3xl: clamp(1.875rem, 1.65rem + 1.13vw, 2.441rem); --font-4xl: clamp(2.25rem, 1.95rem + 1.5vw, 3.052rem); /* Border radius */ --radius-sm: 0.25rem; /* 4px */ --radius-md: 0.5rem; /* 8px */ --radius-lg: 1rem; /* 16px */ --radius-full: 9999px; } /* ============= Global Styles ============= */ html { font-size: 100%; /* Kullanıcı tercihine saygı */ } body { font-family: system-ui, -apple-system, sans-serif; font-size: var(--font-base); line-height: 1.6; color: #1a1a1a; } /* ============= Components ============= */ /* Button - EM ile component-based scaling */ .button { font-size: 1rem; padding: 0.5em 1em; /* EM - font-size'a göre */ border: var(--border-thin) solid; border-radius: var(--radius-md); /* REM */ cursor: pointer; transition: all 0.2s; } .button-sm { font-size: 0.875rem; padding: 0.5em 1em; /* Aynı em, ama küçük */ } .button-lg { font-size: 1.125rem; padding: 0.5em 1em; /* Aynı em, ama büyük */ } /* Card - REM ile global spacing */ .card { padding: var(--space-xl); /* REM - global scale */ border: var(--border-thin) solid #e0e0e0; /* PX - border */ border-radius: var(--radius-lg); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* PX - shadow */ } /* Icon - PX ile sabit boyut */ .icon { width: var(--icon-md); /* PX - sabit */ height: var(--icon-md); display: inline-block; } /* Container - PX max-width, % width */ .container { width: 90%; /* % - responsive */ max-width: var(--container-xl); /* PX - üst sınır */ margin: 0 auto; padding: 0 var(--space-lg); /* REM - spacing */ } /* Grid - REM gap */ .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-xl); /* REM - consistent */ } /* Typography - Fluid + REM */ h1 { font-size: var(--font-4xl); /* Fluid clamp */ line-height: 1.1; /* Unitless */ margin-bottom: 0.5em; /* EM - font-size'a göre */ } h2 { font-size: var(--font-3xl); line-height: 1.2; margin-bottom: 0.5em; } p { font-size: var(--font-base); line-height: 1.6; margin-bottom: 1em; } /* ============= Utilities ============= */ /* Spacing utilities - REM */ .p-sm { padding: var(--space-sm); } .p-md { padding: var(--space-md); } .p-lg { padding: var(--space-lg); } .p-xl { padding: var(--space-xl); } .m-sm { margin: var(--space-sm); } .m-md { margin: var(--space-md); } .m-lg { margin: var(--space-lg); } .m-xl { margin: var(--space-xl); } /* Border utilities - PX */ .border { border: var(--border-thin) solid currentColor; } .border-2 { border: var(--border-medium) solid currentColor; } .border-4 { border: var(--border-thick) solid currentColor; } /* Icon sizes - PX */ .icon-sm { width: var(--icon-sm); height: var(--icon-sm); } .icon-md { width: var(--icon-md); height: var(--icon-md); } .icon-lg { width: var(--icon-lg); height: var(--icon-lg); } 6. PX Kullanımında Yaygın Hatalar Hata 1: Root Font-Size'ı PX ile Ayarlama /* ❌ EN BÜYÜK HATA */ html { font-size: 16px; } Neden kötü: Kullanıcının tarayıcı ayarlarını ezer Erişilebilirlik ihlali WCAG başarısız Bazı geliştiriciler bunu yapıyor: /* ❌ 10px base trick - YAPMA! */ html { font-size: 62.5%; /* 10px - kolay hesaplama için */ } body { font-size: 1.6rem; /* 16px */ } h1 { font-size: 3.2rem; /* 32px */ } Sorun: Tarayıcı varsayılanı 16px değilse bozulur Kullanıcı "Large fonts" seçmişse görmezden gelir Math zorlaştırma pahasına erişilebilirliği feda ediyorsun /* ✅ DOĞRU YOL */ html { font-size: 100%; /* Kullanıcı ayarına saygı */ } body { font-size: 1rem; /* 16px @ default */ } h1 { font-size: 2rem; /* 32px @ default - ama ölçeklenebilir */ } Hata 2: Her Yerde PX Kullanımı /* ❌ 2000'ler tarzı - modern değil */ .header { height: 80px; padding: 20px 40px; margin-bottom: 30px; } .nav-item { font-size: 14px; padding: 10px 15px; margin-right: 20px; } .content { font-size: 16px; line-height: 24px; padding: 40px; max-width: 800px; } Sorun: Hiçbir şey ölçeklenmiyor Responsive değil Bakımı zor /* ✅ Modern yaklaşım - mix */ .header { height: auto; /* İçeriğe göre */ padding: var(--space-lg) var(--space-xl); /* REM */ margin-bottom: var(--space-xl); /* REM */ } .nav-item { font-size: var(--font-sm); /* Fluid */ padding: 0.625em 0.9375em; /* EM - font'a göre */ margin-right: var(--space-md); /* REM */ } .content { font-size: var(--font-base); /* Fluid */ line-height: 1.5; /* Unitless */ padding: var(--space-2xl); /* REM */ max-width: 800px; /* PX - max OK */ } Hata 3: Media Query'lerde Sadece PX /* ⚠️ Yaygın ama tartışmalı */ @media (max-width: 768px) { .nav { display: block; } } Sorun: Kullanıcı font-size değiştirince layout kırılabilir 7. Özet - Modern PX Kullanım Rehberi ✅ PX Kullan: Border width - border: 1px solid Box shadow - box-shadow: 0 2px 8px Sabit boyutlu elementler - Icons, avatars, logos Max-width constraints - Container limits Media query breakpoints - (EM de OK) Transform offset - translateY(-2px) Çok küçük değerler - gap: 4px (ama REM daha iyi) ❌ PX Kullanma: Font-size - ASLA! Line-height - Unitless kullan Padding/Margin - REM veya EM kullan Width/Height (layout için) - Flexible units kullan Root font-size - % kullan (100%) ⚠️ Dikkatli Kullan: Border-radius - Küçükse PX OK, büyükse REM Gap - REM daha iyi ama PX de çalışır Min/Max values - Context'e göre 🎯 Altın Kural: "PX kullanacaksan, kendine sor: Bu değer kullanıcının font-size tercihinden etkilenmeli mi?" Evet ise → REM/EM/clamp() kullan Hayır ise → PX kullanabilirsin Modern web'de PX hala değerli bir araç, ama doğru yerde kullanılmalı. Her birim kendi amacı için optimize edilmiştir!
  10. Doğuhan ELMA

    CSS'de % (Yüzde) Birimi

    Yüzde birimi CSS'in en eski ve en esnek birimlerinden biri. CSS’in ilk günlerinden beri vardır. Ancak neye göre yüzde olduğu her property'de farklı! Detaylı açıklayayım. Responsive tasarım için idealdir. Parent boyutuna göre otomatik uyum sağlar. Tarayıcı yeniden boyutlandığında değerler otomatik güncellenir → reflow tetiklenir. 1. % Birimi Temel Mantığı % her zaman bir referans değere göre hesaplanır. .child { width: 50%; /* Neyin %50'si? */ } Cevap: Parent container'ın ilgili özelliğinin %50'si Ama dikkat: Her CSS property'de farklı referans noktası var! 2. Width ve Height için % Width - En Basit Kullanım .parent { width: 1000px; } .child { width: 50%; /* 1000px × 0.5 = 500px */ } Referans: Parent'ın width değeri Height - Karmaşık Durum /* ❌ ÇALIŞMAZ - Parent'ın height'ı auto */ .parent { /* height tanımlanmamış, içeriğe göre auto */ } .child { height: 50%; /* Neyin %50'si? Parent auto ise hesaplanamaz! */ } /* ✅ ÇALIŞIR - Parent'ın explicit height'ı var */ .parent { height: 600px; } .child { height: 50%; /* 600px × 0.5 = 300px */ } Önemli Kural: height: % çalışması için parent'ın kesin bir height'ı olmalı!. Çünkü height özelliği kalıtsal değildir. Modern Çözüm: Viewport Units /* Eski yöntem - sorunlu */ html, body { height: 100%; /* Chain oluştur */ } .container { height: 100%; } /* Modern yöntem - çok daha iyi */ .container { height: 100vh; /* Viewport height'ının %100'ü */ min-height: 100dvh; /* Dynamic viewport - mobil için */ } 3. Margin ve Padding için % Sürpriz: Her Zaman Width'e Göre Hesaplanır! .box { width: 400px; height: 600px; } .child { margin-top: 10%; /* 400px × 0.1 = 40px (width'e göre!) */ margin-left: 10%; /* 400px × 0.1 = 40px */ padding-top: 10%; /* 400px × 0.1 = 40px (height değil!) */ padding-bottom: 10%; /* 400px × 0.1 = 40px */ } Kritik: margin-top, margin-bottom, padding-top, padding-bottom bile parent'ın width'ine göre hesaplanır! Neden? Aspect Ratio Trickler İçin /* Eski aspect ratio trick (modern aspect-ratio property'den önce) */ .video-wrapper { width: 100%; padding-bottom: 56.25%; /* 16:9 aspect ratio = 9/16 = 0.5625 */ position: relative; background: black; } .video-wrapper iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } Mantık: Padding-bottom width'e göre olduğu için, genişlik değiştikçe yükseklik de orantılı değişir. Modern Alternatif: aspect-ratio /* Modern yöntem - çok daha temiz */ .video-wrapper { width: 100%; aspect-ratio: 16 / 9; background: black; } .video-wrapper iframe { width: 100%; height: 100%; } 4. Font-Size için % Referans: Parent'ın font-size'ı body { font-size: 16px; } .parent { font-size: 150%; /* 16px × 1.5 = 24px */ } .child { font-size: 50%; /* 24px × 0.5 = 12px */ } Root için % - Kullanıcı Tercihlerine Saygı /* ✅ EN İYİ PRATİK */ html { font-size: 100%; /* Tarayıcı varsayılanı (genelde 16px) */ /* Kullanıcı ayarlarını değiştirmişse ona uyar */ } body { font-size: 1rem; /* Root'un font-size'ı */ } Neden 100%? Kullanıcı tarayıcısında "Large fonts" seçmişse → 100% = 20px olur. Chrome tarayıcısnda Ayarlar > Görünüm Kullanıcı "Small fonts" seçmişse → 100% = 14px olur Erişilebilirlik için kritik! % vs REM vs EM /* % - Parent'a göre */ .parent { font-size: 16px; } .child { font-size: 150%; } /* 24px */ /* EM - Parent'a göre (aynı) */ .parent { font-size: 16px; } .child { font-size: 1.5em; } /* 24px */ /* REM - Root'a göre */ html { font-size: 16px; } .anywhere { font-size: 1.5rem; } /* Her zaman 24px */ Modern Tercih: REM (compound effect yok, öngörülebilir) 5. Position için % (Top, Right, Bottom, Left) Referans: Parent'ın İlgili Boyutu .parent { width: 400px; height: 600px; position: relative; } .child { position: absolute; top: 50%; /* Parent height'ının %50'si = 300px */ left: 25%; /* Parent width'ının %25'i = 100px */ width: 50%; /* Parent width'ının %50'si = 200px */ height: 30%; /* Parent height'ının %30'u = 180px */ } Merkezleme Trick (Transform ile) /* Klasik absolute merkezleme */ .centered { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); /* top/left: Parent'a göre %50 transform: Kendi boyutuna göre %-50 */ } Dikkat: transform: translate() içindeki % elementin kendi boyutuna göre! .box { width: 200px; height: 100px; transform: translateX(50%); /* 200px × 0.5 = 100px sağa */ transform: translateY(-50%); /* 100px × 0.5 = 50px yukarı */ } 6. Background-Position için % Sürpriz Davranış! .box { width: 400px; height: 300px; background-image: url('image.jpg'); /* 800×600px */ background-size: contain; background-position: 50% 50%; } % Hesaplaması: X pozisyonu = (container width - image width) × % Y pozisyonu = (container height - image height) × % /* Örnekler */ background-position: 0% 0%; /* Sol üst */ background-position: 100% 100%; /* Sağ alt */ background-position: 50% 50%; /* Tam orta */ /* 0% ve 100% özel durumlar */ background-position: 0% 0%; /* Resmin sol üstü, container'ın sol üstünde */ background-position: 100% 100%; /* Resmin sağ altı, container'ın sağ altında */ Background-Size için % .box { width: 400px; height: 300px; background-size: 50% 50%; /* Genişlik: 400px × 0.5 = 200px Yükseklik: 300px × 0.5 = 150px */ } /* Tek değer - orantılı */ background-size: 50%; /* Genişlik %50, yükseklik auto (orantılı) */ /* Modern alternatif */ background-size: cover; /* Tüm alanı kapla */ background-size: contain; /* İçine sığdır */ 7. Modern Web Tasarımda % Kullanım Alanları 1. Fluid Layouts (Akışkan Düzenler) /* ✅ Responsive Container */ .container { width: 90%; /* Ekranın %90'ı */ max-width: 1200px; /* Ama maximum 1200px */ margin: 0 auto; /* Ortala */ } /* ✅ Fluid Grid */ .grid { display: grid; grid-template-columns: 30% 70%; /* Sol sidebar, sağ content */ gap: 2%; } /* ❌ Artık bunu yapma - modern alternatif var */ .old-grid { float: left; width: 25%; margin-right: 5%; } Modern Alternatif - Flexbox/Grid: /* Flexbox ile daha iyi */ .flex-container { display: flex; gap: 2rem; } .sidebar { flex: 0 0 300px; /* Sabit genişlik */ } .content { flex: 1; /* Kalan alanı al */ } /* Grid ile en iyi */ .grid-container { display: grid; grid-template-columns: 300px 1fr; /* Sabit + esnek */ gap: 2rem; } 2. Responsive Images /* ✅ Temel responsive image */ img { max-width: 100%; /* Parent'tan taşma */ height: auto; /* Oranı koru */ } /* ✅ Fluid image container */ .image-wrapper { width: 100%; max-width: 600px; } .image-wrapper img { width: 100%; height: auto; } 3. Aspect Ratio Boxes (Eski Yöntem) /* ❌ Eski yöntem - padding trick */ .aspect-box { width: 100%; padding-bottom: 75%; /* 4:3 aspect ratio */ position: relative; background: #f0f0f0; } .aspect-box-content { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } /* ✅ Modern yöntem - aspect-ratio property */ .aspect-box-modern { width: 100%; aspect-ratio: 4 / 3; background: #f0f0f0; } 4. Typography - Line Height /* ✅ Line-height için % kullanımı */ p { font-size: 1rem; /* 16px */ line-height: 150%; /* 16px × 1.5 = 24px */ } /* ❌ Ama unitless daha iyi! */ p { font-size: 1rem; line-height: 1.5; /* Daha esnek, compound effect yok */ } Fark: /* % ile */ .parent { font-size: 16px; line-height: 150%; /* 24px hesaplanır ve sabitleşir */ } .child { font-size: 20px; /* line-height hala 24px - küçük kalır! */ } /* Unitless ile */ .parent { font-size: 16px; line-height: 1.5; /* Oran olarak kalır */ } .child { font-size: 20px; line-height: 1.5; /* 20px × 1.5 = 30px - orantılı! */ } 5. Opacity ve Colors /* % modern CSS'te bazı yerlerde kullanılıyor */ .element { opacity: 50%; /* 0.5 ile aynı */ background: rgb(255 0 0 / 50%); /* Alpha %50 */ } /* Ama geleneksel 0-1 arası daha yaygın */ .element { opacity: 0.5; background: rgba(255, 0, 0, 0.5); } 8. % vs Diğer Birimler - Ne Zaman Hangisi? Width/Height İçin /* % - Parent'a göre responsive */ .sidebar { width: 25%; /* Parent değişince değişir */ } /* vw/vh - Viewport'a göre */ .hero { height: 100vh; /* Her zaman viewport height'ı */ } /* px - Sabit boyut */ .icon { width: 24px; /* Her zaman aynı */ } /* fr (Grid için) - Kalan alanı böl */ .grid { grid-template-columns: 200px 1fr 2fr; /* 200px sabit, kalan alan 1:2 oranında bölünür */ } Font-Size İçin /* % - Parent'a göre (eski) */ html { font-size: 100%; } h1 { font-size: 200%; } /* REM - Root'a göre (modern tercih) */ html { font-size: 100%; } h1 { font-size: 2rem; } /* EM - Parent'a göre (spacing için iyi) */ .button { font-size: 1rem; padding: 0.5em 1em; /* Font-size değişince padding da değişir */ } /* clamp() - Fluid (en modern) */ h1 { font-size: clamp(1.5rem, 2vw + 1rem, 3rem); } Spacing İçin /* REM - Consistent spacing */ .section { padding: 2rem; /* Root font-size'a göre */ } /* EM - Component-based spacing */ .button { padding: 0.5em 1em; /* Butonun font-size'ına göre */ } /* % - Container'a göre (nadiren) */ .centered { margin: 0 10%; /* Sol/sağ %10 margin */ } /* vh/vw - Viewport'a göre */ .hero { padding: 10vh 5vw; /* Viewport boyutuna göre */ } 9. Modern Web'de % Best Practices ✅ KULLAN /* 1. Root font-size için */ html { font-size: 100%; /* Kullanıcı tercihlerine saygı */ } /* 2. Fluid container genişlikleri */ .container { width: 90%; max-width: 1400px; } /* 3. Responsive images */ img { max-width: 100%; height: auto; } /* 4. Grid column'ları (basit durumlar) */ .two-column { display: grid; grid-template-columns: 60% 40%; } /* 5. Transform translate */ .centered { transform: translate(-50%, -50%); } ⚠️ DİKKATLİ KULLAN /* 1. Height için (parent'ın height'ı kesin olmalı) */ .child { height: 80%; /* Parent'ın height'ı explicit mi? */ } /* 2. Padding/margin için (width'e göre hesaplandığını unutma) */ .box { padding-top: 10%; /* Height değil, width'e göre! */ } /* 3. Font-size için (REM daha iyi) */ .text { font-size: 125%; /* REM daha öngörülebilir */ } ❌ KULLANMA /* 1. Complex layouts (Flexbox/Grid daha iyi) */ .old-layout { float: left; width: 33.33%; margin-right: 2%; } /* Bunun yerine Grid kullan */ /* 2. Aspect ratios (modern property var) */ .old-ratio { padding-bottom: 56.25%; } /* Bunun yerine aspect-ratio kullan */ /* 3. Type scale (REM + clamp daha iyi) */ h1 { font-size: 250%; } /* Bunun yerine fluid typography */ 10. Gerçek Dünya Örnekleri Örnek 1: Modern Card Component /* ❌ Eski yöntem - % her yerde */ .card { width: 30%; margin: 1.5%; padding: 3%; float: left; } /* ✅ Modern yöntem - doğru birimleri kullan */ .card-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 2rem; padding: 2rem; } .card { padding: 1.5rem; /* % yerine rem/em - daha tutarlı */ } Örnek 2: Responsive Hero Section /* ✅ Modern yaklaşım - birimi amacına göre kullan */ .hero { /* Viewport units - tam ekran */ min-height: 100vh; min-height: 100dvh; /* Dynamic viewport - mobil için */ /* % - responsive spacing */ padding: 5vh 5%; /* max-width ile sınırla */ max-width: 1400px; margin: 0 auto; } .hero-title { /* Fluid typography - % değil */ font-size: clamp(2rem, 5vw + 1rem, 5rem); /* Unitless line-height */ line-height: 1.2; /* EM - font-size'a göre margin */ margin-bottom: 0.5em; } .hero-content { /* % - parent'a göre width */ width: 90%; max-width: 700px; margin: 0 auto; } Örnek 3: Responsive Image Gallery /* ✅ Modern grid + % kombinasyonu */ .gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 1rem; padding: 2rem; } .gallery-item { /* aspect-ratio modern, padding-bottom trick değil */ aspect-ratio: 1 / 1; overflow: hidden; } .gallery-item img { /* % - responsive image */ width: 100%; height: 100%; object-fit: cover; /* Hover effect - transform scale */ transition: transform 0.3s ease; } .gallery-item:hover img { transform: scale(1.1); /* %110 boyut */ } Modern Web'de % Felsefesi: Root font-size: 100% kullan (erişilebilirlik) Container width: % + max-width kombinasyonu Images: max-width: 100% responsive için Layouts: Flexbox/Grid tercih et (% yerine) Spacing: REM/EM kullan (% yerine) Typography: REM + clamp() (% yerine) % hala güçlü bir araç, ama artık "her şey için %" dönemi bitti. Her birimi amacına göre kullanmak modern yaklaşım! Hata : Height Yüzdesi Çalışmıyor /* ÇALIŞMAZ */ html, body { /* height: auto (default) *//* içerik kadar yükseklik */ } .full-height { height: 100%; /* Çalışmaz */ } /* ÇALIŞIR */ html, body { height: 100%; /* Burda parent(viewport) yükseklik(vh) devreye girer.*/ } .full-height { height: 100%; /* Şimdi çalışır. chain oluşacağı için tercih edilmez. */ } html elementinin parent’ı yoktur, ama rendering açısından tarayıcı onu viewport ile ilişkilendirir. Bu yüzden html { height: 100%; } → viewport yüksekliği(vh) kadar olur. Ardından body { height: 100%; } → html elementinin yüksekliği kadar olur → yani yine viewport yüksekliği. Eğer html’in height değeri tanımlı değilse, body { height: 100%; } işe yaramaz çünkü % birimi parent’a bağlıdır. Not: height olarak vh birimini kullanmak netlik sağlar ve belirsizliği giderir. width: 100%: % parent elementin iç genişliği → scrollbar hariçtir.
  11. Doğuhan ELMA

    font-size Özelliği - CSS

    font-size, CSS’te bir metnin yazı tipi boyutunu belirleyen özelliktir. Yani sayfadaki bir yazının ne kadar büyük veya küçük görüneceğini kontrol edersin. Modern web geliştirmede font-size konusu ciddi bir evrim geçirdi. Detaylı açıklayayım. 1. Birimler ve Temel Kavramlar Absolute (Mutlak) Birimler /* PX - Pixel */ p { font-size: 16px; } ❌ Tarayıcı ayarlarına duyarlı değil ❌ Kullanıcı font tercihlerini görmezden gelir ✅ Kesin kontrol sağlar ⚠️ Erişilebilirlik sorunu /* PT, CM, MM - Baskı birimleri */ p { font-size: 12pt; } /* Sadece print için uygun */ Relative (Göreceli) Birimler /* EM - Parent'a göre */ .parent { font-size: 16px; } .child { font-size: 1.5em; } /* 16px × 1.5 = 24px */ .grandchild { font-size: 1.5em; } /* 24px × 1.5 = 36px - COMPOUND EFFECT! */ EM'in Tehlikesi - Cascading Problem: .article { font-size: 1.2em; } .article p { font-size: 1.1em; } .article p strong { font-size: 1.2em; } /* İç içe geçince: 1.2 × 1.1 × 1.2 = 1.584em - Kontrol kaybı! */ /* REM - Root'a göre (html elementi) */ html { font-size: 16px; } /* Base size */ h1 { font-size: 2rem; } /* Her zaman 32px */ p { font-size: 1rem; } /* Her zaman 16px */ ✅ **REM avantajları:** - Compound effect yok - Öngörülebilir - Kullanıcı font tercihleri çalışır - Tek bir yerden (root) tüm siteyi ölçeklendirebilirsin 2. Tarayıcının Varsayılan Yaklaşımı Tarayıcı Font-Size Hiyerarşisi 1. User Agent Stylesheet (Tarayıcı varsayılanı) └─ html { font-size: 16px; } 2. User Settings (Kullanıcı ayarları) └─ Tarayıcı ayarlarından font boyutu değiştirme 3. Author Stylesheet (Senin CSS'in) └─ Senin yazdığın kurallar Tarayıcı Varsayılan Font Boyutları /* Çoğu tarayıcının varsayılanı */ html { font-size: 16px; } h1 { font-size: 2em; } /* 32px */ h2 { font-size: 1.5em; } /* 24px */ h3 { font-size: 1.17em; } /* ~18.72px */ h4 { font-size: 1em; } /* 16px */ h5 { font-size: 0.83em; } /* ~13.28px */ h6 { font-size: 0.67em; } /* ~10.72px */ p { font-size: 1em; } /* 16px */ small { font-size: 0.875em; } /* 14px */ 3. Eski (Geleneksel) Yaklaşım 2000'ler - Pixel Tabanlı /* Eskiden herkes bunu yapardı */ body { font-size: 14px; } h1 { font-size: 28px; } p { font-size: 14px; } small { font-size: 12px; } ❌ Sorunlar: Sabit boyutlar Responsive değil Erişilebilirlik kötü Kullanıcı tercihleri çalışmaz 2010'lar - Em Tabanlı (İlk Responsive Dönem) body { font-size: 100%; } /* 16px */ h1 { font-size: 2em; } p { font-size: 1em; } @media (max-width: 768px) { body { font-size: 87.5%; } /* 14px */ } ⚠️ Sorun: Compound effect ve karmaşık hesaplamalar 4. Modern Yaklaşım (2020+) A) REM Tabanlı Sistem (En Yaygın) /* 1. Root'u % olarak ayarla (kullanıcı tercihlerine saygı) */ html { font-size: 100%; /* 16px, ama kullanıcı değiştirirse ona uyar */ } /* 2. Her şeyi REM ile tanımla */ :root { --font-xs: 0.75rem; /* 12px */ --font-sm: 0.875rem; /* 14px */ --font-base: 1rem; /* 16px */ --font-lg: 1.125rem; /* 18px */ --font-xl: 1.25rem; /* 20px */ --font-2xl: 1.5rem; /* 24px */ --font-3xl: 1.875rem; /* 30px */ --font-4xl: 2.25rem; /* 36px */ } body { font-size: var(--font-base); } h1 { font-size: var(--font-4xl); } h2 { font-size: var(--font-3xl); } p { font-size: var(--font-base); } small { font-size: var(--font-sm); } B) Fluid Typography (Akışkan Tipografi) Eski yöntem - Media Query'ler: h1 { font-size: 1.5rem; /* Mobile */ } @media (min-width: 768px) { h1 { font-size: 2rem; } /* Tablet */ } @media (min-width: 1024px) { h1 { font-size: 2.5rem; } /* Desktop */ } Modern yöntem - Clamp(): h1 { /* min: 1.5rem, ideal: viewport'a göre ölçeklen, max: 3rem */ font-size: clamp(1.5rem, 2vw + 1rem, 3rem); } /* Viewport genişliği arttıkça smooth geçiş */ C) Viewport Birimleri + Clamp (En Modern) :root { /* Fluid type scale */ --font-base: clamp(1rem, 0.5vw + 0.875rem, 1.125rem); --font-h1: clamp(2rem, 4vw + 1rem, 4rem); --font-h2: clamp(1.5rem, 3vw + 0.75rem, 3rem); --font-h3: clamp(1.25rem, 2vw + 0.5rem, 2rem); } body { font-size: var(--font-base); } h1 { font-size: var(--font-h1); } h2 { font-size: var(--font-h2); } h3 { font-size: var(--font-h3); } Clamp Formülü Açıklaması: font-size: clamp( 1rem, /* Minimum: Mobile'da bu */ 0.5vw + 0.875rem, /* İdeal: Viewport'a göre büyü */ 1.125rem /* Maximum: Çok büyük ekranlarda bu */ ); D) Container Query ile Font-Size (2024+) .card-container { container-type: inline-size; container-name: card; } .card h2 { font-size: 1rem; } /* Container 400px'den büyükse */ @container card (min-width: 400px) { .card h2 { font-size: 1.5rem; } } /* Container 600px'den büyükse */ @container card (min-width: 600px) { .card h2 { font-size: 2rem; } } 5. Responsive Font-Size Stratejileri Strateji 1: Type Scale (Modular Scale) :root { /* 1.25 ratio (Major Third) */ --ratio: 1.25; --font-xs: calc(1rem / var(--ratio) / var(--ratio)); /* 0.64rem */ --font-sm: calc(1rem / var(--ratio)); /* 0.8rem */ --font-base: 1rem; /* 1rem */ --font-lg: calc(1rem * var(--ratio)); /* 1.25rem */ --font-xl: calc(1rem * var(--ratio) * var(--ratio)); /* 1.563rem */ --font-2xl: calc(1rem * var(--ratio) * var(--ratio) * var(--ratio)); /* 1.953rem */ } /* Responsive ratio */ @media (min-width: 768px) { :root { --ratio: 1.333; /* Perfect Fourth - Tablet'te daha aggressive */ } } @media (min-width: 1024px) { :root { --ratio: 1.5; /* Perfect Fifth - Desktop'ta daha da aggressive */ } } Strateji 2: Utopia Fluid Type (Matematiksel Yaklaşım) :root { /* Minimum viewport: 320px */ /* Maximum viewport: 1240px */ --font-base: clamp( 1rem, /* 16px at 320px */ 0.913rem + 0.43vw, /* Fluid between */ 1.125rem /* 18px at 1240px */ ); --font-h1: clamp( 2rem, /* 32px at 320px */ 1.217rem + 3.91vw, /* Fluid between */ 4rem /* 64px at 1240px */ ); } Strateji 3: Step-Based System (Tailwind Tarzı) :root { /* Base boyut responsive */ --font-base: clamp(1rem, 0.95rem + 0.25vw, 1.125rem); /* Her step base'e göre */ --step--2: calc(var(--font-base) * 0.64); /* ~10-11px */ --step--1: calc(var(--font-base) * 0.8); /* ~13-14px */ --step-0: var(--font-base); /* 16-18px */ --step-1: calc(var(--font-base) * 1.25); /* 20-22px */ --step-2: calc(var(--font-base) * 1.563); /* 25-28px */ --step-3: calc(var(--font-base) * 1.953); /* 31-35px */ --step-4: calc(var(--font-base) * 2.441); /* 39-44px */ --step-5: calc(var(--font-base) * 3.052); /* 49-55px */ } /* Kullanım */ body { font-size: var(--step-0); } small { font-size: var(--step--1); } h4 { font-size: var(--step-2); } h3 { font-size: var(--step-3); } h2 { font-size: var(--step-4); } h1 { font-size: var(--step-5); } 6. Best Practices (2024) ✅ YAPILMASI GEREKENLER /* 1. Root'u asla px ile set etme */ html { font-size: 100%; /* DOĞRU */ /* font-size: 16px; - YANLIŞ */ } /* 2. REM kullan, px kullanma */ p { font-size: 1rem; /* DOĞRU */ /* font-size: 16px; - YANLIŞ */ } /* 3. Clamp ile smooth scaling */ h1 { font-size: clamp(1.5rem, 2vw + 1rem, 3rem); /* DOĞRU */ } /* 4. CSS Variables ile yönet */ :root { --font-body: clamp(1rem, 0.5vw + 0.875rem, 1.125rem); } body { font-size: var(--font-body); /* DOĞRU */ } /* 5. Line-height'ı da responsive yap */ p { font-size: clamp(1rem, 0.5vw + 0.875rem, 1.125rem); line-height: 1.6; /* Unitless - font-size'a göre ölçeklenir */ } ❌ YAPILMAMASI GEREKENLER /* 1. Root'u px ile ayarlama */ html { font-size: 16px; /* YANLIŞ - Kullanıcı tercihlerini ezer */ } /* 2. Her yerde px kullanma */ p { font-size: 14px; /* YANLIŞ */ padding: 10px; /* YANLIŞ */ margin: 20px; /* YANLIŞ */ } /* 3. Em'i font-size için kullanma (compound effect) */ .nested { font-size: 1.2em; /* RİSKLİ - İç içe geçince sorun */ } /* 4. Çok fazla breakpoint */ h1 { font-size: 1.5rem; } @media (min-width: 480px) { h1 { font-size: 1.75rem; } } @media (min-width: 768px) { h1 { font-size: 2rem; } } @media (min-width: 1024px) { h1 { font-size: 2.5rem; } } @media (min-width: 1280px) { h1 { font-size: 3rem; } } /* Bunun yerine clamp() kullan! */ 7. Gerçek Dünya Örneği Production-Ready Font System /* ============================================ MODERN FLUID TYPE SYSTEM ============================================ */ /* 1. Root ayarları */ html { font-size: 100%; /* 16px, ama kullanıcıya saygılı */ /* Smooth scroll için bonus */ scroll-behavior: smooth; } /* 2. CSS Custom Properties */ :root { /* Base fluid size */ --fluid-base: clamp(1rem, 0.913rem + 0.43vw, 1.125rem); /* Type scale - fluid */ --fluid-xs: clamp(0.75rem, 0.69rem + 0.29vw, 0.875rem); --fluid-sm: clamp(0.875rem, 0.826rem + 0.25vw, 1rem); --fluid-lg: clamp(1.125rem, 1.038rem + 0.43vw, 1.313rem); --fluid-xl: clamp(1.25rem, 1.109rem + 0.7vw, 1.563rem); --fluid-2xl: clamp(1.5rem, 1.283rem + 1.09vw, 1.953rem); --fluid-3xl: clamp(1.875rem, 1.543rem + 1.66vw, 2.441rem); --fluid-4xl: clamp(2.25rem, 1.826rem + 2.12vw, 3.052rem); --fluid-5xl: clamp(2.75rem, 2.174rem + 2.88vw, 3.815rem); } /* 3. Global typography */ body { font-family: system-ui, -apple-system, sans-serif; font-size: var(--fluid-base); line-height: 1.6; color: #1a1a1a; } /* 4. Headings */ h1, h2, h3, h4, h5, h6 { line-height: 1.2; font-weight: 700; margin-top: 0; margin-bottom: 0.5em; } h1 { font-size: var(--fluid-5xl); } h2 { font-size: var(--fluid-4xl); } h3 { font-size: var(--fluid-3xl); } h4 { font-size: var(--fluid-2xl); } h5 { font-size: var(--fluid-xl); } h6 { font-size: var(--fluid-lg); } /* 5. Body text elements */ p { font-size: var(--fluid-base); margin-bottom: 1em; } small { font-size: var(--fluid-sm); } /* 6. Utility classes */ .text-xs { font-size: var(--fluid-xs); } .text-sm { font-size: var(--fluid-sm); } .text-base { font-size: var(--fluid-base); } .text-lg { font-size: var(--fluid-lg); } .text-xl { font-size: var(--fluid-xl); } .text-2xl { font-size: var(--fluid-2xl); } .text-3xl { font-size: var(--fluid-3xl); } .text-4xl { font-size: var(--fluid-4xl); } .text-5xl { font-size: var(--fluid-5xl); } /* 7. Print styles */ @media print { html { font-size: 12pt; } h1 { font-size: 24pt; } h2 { font-size: 20pt; } h3 { font-size: 18pt; } p { font-size: 12pt; } } /* 8. Reduced motion için */ @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } } 8. Özet - Modern Yaklaşım Checklist ✅ Root'u % olarak ayarla → Kullanıcı tercihlerine saygı ✅ REM kullan → Öngörülebilir, compound effect yok ✅ Clamp() ile fluid typography → Smooth responsive geçişler ✅ CSS Variables ile merkezi yönetim → Kolay bakım ✅ Type scale sistemi → Tutarlı hiyerarşi ✅ Line-height unitless → Font-size ile ölçeklensin ✅ Container queries → Component-bazlı responsive ❌ PX kullanma (root ve font-size için) ❌ EM ile font-size (spacing için kullanabilirsin) ❌ Çok fazla breakpoint (clamp kullan) ❌ Sabit değerler (fluid olsun) Modern web'de font-size artık sadece "boyut" değil, erişilebilirlik, responsive tasarım ve kullanıcı deneyiminin kesişim noktası!
  12. Doğuhan ELMA

    clamp() Function - CSS

    clamp() fonksiyonu, modern CSS'in en güçlü ve kullanışlı araçlarından biri. Responsive tasarımda "fluid but constrained" (akışkan ama sınırlı) değerler oluşturmanıza olanak tanır. clamp() Nedir? clamp() üç parametre alır ve ortadaki değeri, minimum ve maksimum sınırlar arasında tutar: clamp(MIN, PREFERRED, MAX) Mantık: Eğer PREFERRED < MIN ise → MIN kullanılır Eğer PREFERRED > MAX ise → MAX kullanılır Eğer MIN ≤ PREFERRED ≤ MAX ise → PREFERRED kullanılır /* Basit örnek */ font-size: clamp(16px, 4vw, 32px); /* Anlamı: - Minimum 16px - Tercih edilen: viewport genişliğinin %4'ü - Maksimum 32px */ clamp() vs min() vs max() CSS'de üç benzer fonksiyon var, farkları anlamak önemli: /* max() - En büyük değeri seç */ width: max(300px, 50%); /* 300px veya %50'den hangisi büyükse onu kullan */ /* min() - En küçük değeri seç */ width: min(500px, 100%); /* 500px veya %100'den hangisi küçükse onu kullan */ /* clamp() - Aralıkta tut */ width: clamp(300px, 50%, 500px); /* %50 kullan, ama 300px'den küçük olmasın, 500px'den büyük olmasın */ Pratik Karşılaştırma: .container { /* Sadece max() */ width: max(320px, 50vw); /* Problem: Üst sınır yok, çok büyüyebilir */ /* Sadece min() */ width: min(1200px, 90vw); /* Problem: Alt sınır yok, çok küçülebilir */ /* clamp() - En güvenli */ width: clamp(320px, 90vw, 1200px); /* Perfect: Hem alt hem üst sınır var */ } Modern Web'de clamp() Kullanım Alanları 1. Fluid Typography (En Popüler Kullanım) Eski yöntem vs Modern yöntem: /* ❌ ESKİ YÖNTEM - Media Query Cehenemi */ h1 { font-size: 24px; } @media (min-width: 640px) { h1 { font-size: 32px; } } @media (min-width: 768px) { h1 { font-size: 40px; } } @media (min-width: 1024px) { h1 { font-size: 48px; } } @media (min-width: 1280px) { h1 { font-size: 56px; } } /* ✅ MODERN YÖNTEM - Tek Satır */ h1 { font-size: clamp(24px, 5vw + 1rem, 56px); } Gerçek Dünya Tipografi Sistemi: /* Typography Scale with clamp() */ :root { /* Base */ --text-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem); --text-sm: clamp(0.875rem, 0.825rem + 0.25vw, 1rem); --text-base: clamp(1rem, 0.95rem + 0.25vw, 1.125rem); --text-lg: clamp(1.125rem, 1.05rem + 0.375vw, 1.25rem); --text-xl: clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem); /* Headings */ --text-2xl: clamp(1.5rem, 1.3rem + 1vw, 2rem); --text-3xl: clamp(1.875rem, 1.5rem + 1.875vw, 2.5rem); --text-4xl: clamp(2.25rem, 1.75rem + 2.5vw, 3rem); --text-5xl: clamp(3rem, 2rem + 5vw, 4rem); --text-6xl: clamp(3.75rem, 2.5rem + 6.25vw, 5rem); } body { font-size: var(--text-base); } h1 { font-size: var(--text-5xl); } h2 { font-size: var(--text-4xl); } h3 { font-size: var(--text-3xl); } h4 { font-size: var(--text-2xl); } h5 { font-size: var(--text-xl); } h6 { font-size: var(--text-lg); } 2. Responsive Spacing (Padding, Margin, Gap) /* Section spacing */ .section { padding-block: clamp(2rem, 5vw, 8rem); padding-inline: clamp(1rem, 5vw, 4rem); } /* Container padding */ .container { padding: clamp(1rem, 2vw + 0.5rem, 3rem); gap: clamp(1rem, 3vw, 2rem); } /* Grid gap */ .grid { display: grid; gap: clamp(1rem, 2vw, 3rem); grid-template-columns: repeat(auto-fit, minmax(clamp(250px, 30vw, 350px), 1fr)); } Gerçek Dünya Spacing Sistemi: :root { /* Spacing Scale */ --space-3xs: clamp(0.25rem, 0.23rem + 0.11vw, 0.3125rem); --space-2xs: clamp(0.5rem, 0.48rem + 0.11vw, 0.5625rem); --space-xs: clamp(0.75rem, 0.7rem + 0.22vw, 0.875rem); --space-s: clamp(1rem, 0.96rem + 0.22vw, 1.125rem); --space-m: clamp(1.5rem, 1.43rem + 0.33vw, 1.6875rem); --space-l: clamp(2rem, 1.91rem + 0.43vw, 2.25rem); --space-xl: clamp(3rem, 2.87rem + 0.65vw, 3.375rem); --space-2xl: clamp(4rem, 3.83rem + 0.87vw, 4.5rem); --space-3xl: clamp(6rem, 5.74rem + 1.3vw, 6.75rem); /* One-up pairs */ --space-3xs-2xs: clamp(0.25rem, 0.12rem + 0.65vw, 0.5625rem); --space-2xs-xs: clamp(0.5rem, 0.37rem + 0.65vw, 0.875rem); --space-xs-s: clamp(0.75rem, 0.59rem + 0.76vw, 1.125rem); --space-s-m: clamp(1rem, 0.74rem + 1.3vw, 1.6875rem); --space-m-l: clamp(1.5rem, 1.17rem + 1.63vw, 2.25rem); --space-l-xl: clamp(2rem, 1.48rem + 2.61vw, 3.375rem); --space-xl-2xl: clamp(3rem, 2.35rem + 3.26vw, 4.5rem); --space-2xl-3xl: clamp(4rem, 2.96rem + 5.22vw, 6.75rem); } 3. Responsive Width/Height /* Container genişlikleri */ .container-sm { width: clamp(320px, 90vw, 640px); margin-inline: auto; } .container-md { width: clamp(320px, 90vw, 768px); margin-inline: auto; } .container-lg { width: clamp(320px, 90vw, 1024px); margin-inline: auto; } .container-xl { width: clamp(320px, 90vw, 1280px); margin-inline: auto; } /* Card boyutları */ .card { width: clamp(280px, 100%, 400px); min-height: clamp(200px, 30vh, 400px); } /* Hero yükseklikleri */ .hero { min-height: clamp(400px, 70vh, 800px); } 4. Border Radius /* Responsive border radius */ .card { border-radius: clamp(0.5rem, 1vw, 1.5rem); } .button { border-radius: clamp(0.25rem, 0.5vw, 0.75rem); } /* Pill button */ .pill { border-radius: clamp(1rem, 3vw, 3rem); } 5. Icon ve Image Sizes /* Responsive icon */ .icon { width: clamp(20px, 3vw, 48px); height: clamp(20px, 3vw, 48px); } /* Logo boyutu */ .logo { height: clamp(32px, 5vw, 64px); width: auto; } /* Avatar */ .avatar { width: clamp(40px, 8vw, 80px); height: clamp(40px, 8vw, 80px); border-radius: 50%; } 6. Line Height ve Letter Spacing /* Responsive line height */ body { font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem); line-height: clamp(1.5, 1.4 + 0.2vw, 1.8); } h1 { font-size: clamp(2rem, 5vw, 4rem); line-height: clamp(1.1, 1 + 0.5vw, 1.3); letter-spacing: clamp(-0.02em, -0.01em + -0.01vw, -0.04em); } /* Tracking için */ .heading { letter-spacing: clamp(-0.05em, -0.02vw, -0.01em); } clamp() Best Practices ✅ YAPMASI GEREKENLER: /* 1. Accessibility - rem kullan */ font-size: clamp(1rem, 2vw, 2rem); /* ✅ */ font-size: clamp(16px, 2vw, 32px); /* ❌ Zoom'da sorun */ /* 2. Fallback düşün */ .element { font-size: 18px; /* Fallback */ font-size: clamp(1rem, 2vw, 2rem); /* Enhancement */ } /* 3. CSS custom properties ile */ :root { --fluid-text: clamp(1rem, 2vw, 1.5rem); } body { font-size: var(--fluid-text); } /* 4. Mantıklı aralıklar */ font-size: clamp(1rem, 2vw, 2rem); /* ✅ 2x büyüme */ font-size: clamp(1rem, 10vw, 10rem); /* ❌ 10x çok fazla */ /* 5. Viewport + static kombinasyon */ padding: clamp(1rem, 5vw + 1rem, 5rem); /* ✅ Base + fluid */ ❌ YAPILMAMASI GEREKENLER: /* 1. Çok küçük min değerler */ font-size: clamp(0.1rem, 2vw, 2rem); /* ❌ Okunamaz */ /* 2. Viewport-only preferred */ width: clamp(200px, 100vw, 1200px); /* ⚠️ Scrollbar sorunu */ width: clamp(200px, 90vw, 1200px); /* ✅ Daha güvenli */ /* 3. Negative values with vw */ margin: clamp(-2rem, -5vw, -1rem); /* ⚠️ Beklenmedik sonuçlar */ /* 4. Çok karmaşık hesaplamalar */ font-size: clamp( calc(1rem + 0.5vw), calc(2vw + 1rem + 0.5vh), calc(3rem + 1vw - 0.25rem) ); /* ❌ Debug edilemez */ /* 5. Her property için clamp */ .element { width: clamp(...); height: clamp(...); padding: clamp(...); margin: clamp(...); font-size: clamp(...); line-height: clamp(...); border-radius: clamp(...); /* ❌ Çok fazla, performans sorunu */ } Browser Support clamp() desteği çok iyi (2020'den beri): Chrome 79+ Firefox 75+ Safari 13.1+ Edge 79+ Özet clamp() modern web tasarımın vazgeçilmezi: Avantajları: Media query sayısını dramatik azaltır Gerçekten fluid responsive tasarım Accessibility dostu (doğru kullanıldığında) Kod okunabilirliği artırır Maintenance kolaylaşır Performance iyileşir (daha az media query) Dikkat Edilmesi Gerekenler: rem kullanımına dikkat (accessibility) Mantıklı min/max değerler seçin Fallback stratejisi düşünün Çok karmaşık hesaplamalardan kaçının Performance'ı göz önünde bulundurun clamp() ile artık her ekran boyutu için ayrı CSS yazmak yerine, matematiksel olarak mükemmel, fluid ve responsive tasarımlar oluşturabilirsiniz!
  13. Viewport Nedir? Viewport, tarayıcıda web sayfasının görünen alanıdır. Basitçe söylemek gerekirse, kullanıcının ekranında gördüğü sayfa bölgesidir. Dolayısıyla pencereyi küçültüp büyüttükçe bu değerler dinamik olarak yeniden hesaplanır. Viewport değişince CSS’te: vw, vh, vmin, vmax, svh, lvh, dvh gibi birimler yeniden hesaplanır. Media queries tetiklenir. Container queries yeniden değerlendirilir. Safe-area env variables güncellenebilir. Relative units (% / em / rem) dolaylı olarak etkilenir. Çıkış sebebi: Mobil cihazlar ve farklı ekran çözünürlükleri. İhtiyaç: Esnek, responsive tasarım, okunabilirlik, tam ekran bölümler. Desktop vs Mobil Viewport Desktop'ta: Viewport genellikle tarayıcı penceresinin boyutuna eşittir (vw viewport genişliğidir → scrollbar varsa, dahil edilir.). Mobil cihazlarda: Durum biraz daha karmaşıktır çünkü ekran küçüktür. Ekran boyutu, genellikle dinamik olarak değişir (adres çubuğu açılınca kapanır vs). Viewport Meta Tag'i HTML'de viewport kontrolü için <head> bölümüne şu meta tag'i eklenir: <meta name="viewport" content="width=device-width, initial-scale=1.0"> Bu Tag'in Parametreleri: width=device-width Sayfanın genişliğini cihazın ekran genişliğine eşitler Bu sayede mobil cihazlarda sayfa doğru boyutta görünür initial-scale=1.0 Sayfa ilk yüklendiğinde zoom seviyesini belirler 1.0 = %100 zoom (yakınlaştırma/uzaklaştırma yok) Diğer Parametreler: <meta name="viewport" content=" width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0, user-scalable=yes "> maximum-scale: Maksimum zoom seviyesi minimum-scale: Minimum zoom seviyesi user-scalable: Kullanıcının zoom yapıp yapamayacağı (yes/no) Neden Önemli? Viewport meta tag'i olmadan, mobil tarayıcılar sayfayı desktop genişliğinde (genellikle 980px) render eder ve küçültür. Bu durumda: Yazılar çok küçük görünür Kullanıcı sürekli zoom yapmak zorunda kalır Mobil deneyim kötü olur Viewport meta tag'i ile responsive tasarım yapabilir, her cihazda optimize görünüm sağlarsın. Modern web tasarımında viewport-relative units (görünüm alanı göreli birimleri), responsive tasarımın temel taşlarından biri. Her birimin kendine özgü kullanım senaryoları ve dikkat edilmesi gereken noktalar var. Meta viewport yoksa birimler çalışır, ama mobilde ölçümler güvenilir olmayabilir. Modern responsive tasarımda mobil uyumluluk için meta viewport mutlaka kullanılır. Temel Viewport Birimleri Birimler; Dil veya yazı yönüne göre değişmez. İçerik genişliği yada yüksekliğine göre değişmez. vw (Viewport Width): Viewport genişliğinin(yatay ekran) %1'i anlamına gelir. 100vw = Viewport'un tam genişliği 50vw = Viewport genişliğinin yarısı .hero-section { width: 100vw; /* Tam genişlik */ font-size: 5vw; /* Responsive tipografi */ } Kullanım Alanları: Full-width layoutlar Fluid tipografi Responsive spacing sistemleri Olumsuz Yönleri: Scrollbar sorunu: 100vw genişlik, vertical scrollbar'ı hesaba katmaz. Eğer sayfada scrollbar varsa, yatay scrollbar oluşur. (yaklaşık 15-17px taşma). dikey scrollbar oluşmuşsa 100vw içinde scrollbarda olur. Bu durumda, width: 100vw-20px Mobile browser bar'lar: Mobil tarayıcılarda adres çubuğu viewport hesabını karıştırabilir. Mobilde Portrait (dikey): 100vw cihazın dikey moddaki dar kenarı kadar olur. Mobilde Landscape (yatay): 100vw cihazın yatay moddaki geniş kenarı kadar olur. 👉 Yani cihazı çevirdiğinde vw değeri değişir çünkü viewport genişliği değişir. /* Scrollbar sorunu çözümü */ .full-width { width: 100%; max-width: 100vw; overflow-x: hidden; } vh (Viewport Height): Viewport yüksekliğinin %1'i. .hero { height: 100vh; /* Tam ekran yükseklik */ } Olumsuz Yönleri: Mobile browser sorunları: iOS Safari ve benzeri mobile tarayıcılarda adres çubuğu görünüp kaybolduğunda 100vh sürekli değişir, bu da layout shift'lere neden olur. Landscape mode sorunları: Yatay modda yükseklik çok düşük olabilir, içerik taşabilir. Keyboard açıldığında: Mobilde keyboard açıldığında viewport height küçülür, layout bozulabilir. /* Mobile için daha güvenli yaklaşım */ .hero { min-height: 100vh; min-height: 100dvh; /* Dynamic viewport height */ } vh ve vw birimleri pencere boyutuna göre değişir. Modern tasarımlarda dvh gibi yeni birimler kullanmak en temiz çözümdür. vmin & vmax: vmin: Viewport'un en küçük boyutunun %1'i, vmin aslında min(vw, vh) şeklinde düşünülebilir. vmax: Viewport'un en büyük boyutunun %1'i, vmax ise max(vw, vh) şeklinde düşünülebilir. Mobilde: Portrait (dikey mod) Genişlik > Yükseklik: vmin = genişlik, vmax = yükseklik Landscape (yatay mod) Genişlik > Yükseklik: vmin = yükseklik, vmax = genişlik Desktop’ta orientation değişmez ama pencereyi çok yatay veya çok dikey yaparsan küçük/büyük kenar değişir. vmin ve vmax modern tasarımda fluid (akışkan) ve responsively ölçeklenen öğeler oluşturmak için çok kritik iki birimdir. Çünkü bu iki birim ekranda hangi kenarın baskın olduğunu otomatik algılar ve ona göre boyut verir. Kullanım alanları: h1 { font-size: 8vmin; /* Hem geniş hem dar ekranda orantılı büyür */ } Avantaj: Mobilde çok büyümez, masaüstünde çok küçülmez. Tasarımı sabit piksel bağımlılığından kurtarır. .square { width: 50vmin; height: 50vmin; /* Her zaman kare kalır */ } .adaptive-text { font-size: 3vmax; /* Hem portrait hem landscape'de okunabilir */ } Neden vmin? Çünkü kısa kenara göre hesaplar → daire hiçbir ekranda ezilmez. .hero-title { font-size: 10vmax; /* Geniş monitörde büyük, telefonda daha küçük */ } Neden vmax? Uzun kenara göre hesaplar → geniş ekranda etkili, devasa başlıklar sağlar. .section { padding: 5vmin; } Mobilde “çok doldurmaz”, geniş ekranda “çok boşaltmaz”. Tamamen oranlıdır. vmin: kare/daire, fluid font, responsive spacing vmax: hero başlıkları, geniş ekran tasarımları, dramatik boyutlar Kullanım Senaryoları: Aspect ratio korumak istediğinizde Orientation-independent tasarımlar Olumsuz Yönleri: Tahmin edilebilirlik: Hangi boyutun kullanılacağını öngörmek zor olabilir. Debugging zorluğu: Davranışları anlamak ilk başta kafa karıştırıcı. Modern Viewport Birimleri (2022+) CSS Spec'e yeni eklenen, mobile browser sorunlarını çözen birimler: svh, svw (Small Viewport) UI kontrolleri görünür olduğunda viewport boyutu. Mobile'da address bar açıkken olan boyut lvh, lvw (Large Viewport) UI kontrolleri gizli olduğunda viewport boyutu. Mobile'da address bar kapalıyken olan boyut dvh, dvw (Dynamic Viewport) UI kontrollerinin durumuna göre dinamik değişen boyut. En gerçekçi boyut, ama performans maliyeti var .hero { /* Klasik yaklaşım - mobile'da sorunlu */ height: 100vh; /* Modern yaklaşım - mobile browser bar'ları hesaba katar */ height: 100dvh; /* Fallback stratejisi */ height: 100vh; height: 100dvh; /* Destekleyen tarayıcılarda geçerli olur */ } .fixed-header { /* Small viewport - UI her zaman görünür */ height: 10svh; } .content-area { /* Large viewport - maksimum alan */ min-height: 100lvh; } Browser Desteği Sorunu: Nisan 2023 itibariyle major tarayıcılarda destek var Eski tarayıcılar için fallback şart /* Progressive Enhancement */ .section { height: 600px; /* Fallback */ height: 100vh; /* Eski tarayıcılar */ height: 100dvh; /* Modern tarayıcılar */ } Genel Olumsuz Yönler ve Dikkat Edilmesi Gerekenler 1. Accessibility Sorunları /* ❌ Kötü - kullanıcı zoom yaptığında okunaksız */ body { font-size: 1.5vw; } /* ✅ İyi - minimum ve maksimum değerler */ body { font-size: clamp(16px, 1.5vw, 24px); } Viewport birimleriyle font-size kullanırken kullanıcı tarayıcıda zoom yaptığında metin boyutu değişmez (px gibi sabit kalır). Bu WCAG accessibility kurallarını ihlal eder. 2. Performans Sorunları Viewport birimleri sürekli yeniden hesaplanır: Window resize'da Scroll'da (özellikle mobile'da address bar) Orientation change'de /* Dikkatli kullanım */ .element { /* Her scroll'da repaint tetikler */ transform: translateY(calc(50vh - 50%)); } 3. Print Media Sorunları /* Print'te viewport birimleri belirsiz davranır */ @media print { .hero { height: 100vh; /* Kağıt boyutunu mu, ekran boyutunu mu alır? */ height: auto; /* Daha güvenli */ } } 4. Container Query ile Çakışma /* Viewport vs Container - hangisi kullanılmalı? */ .card { /* Viewport'a göre - tüm ekrana göre ayarlanır */ padding: 2vw; /* Container'a göre - parent'a göre ayarlanır (modern) */ padding: 2cqw; } Modern yaklaşımda container query birimleri (cqw, cqh) daha mantıklı olabilir. 5. Hesaplama Karmaşıklığı /* Karmaşık ve debug edilmesi zor */ .element { width: calc(100vw - 20px); margin-left: calc(-50vw + 50%); padding: calc(2vmin + 1rem); } Best Practices Güvenli Kullanım Örnekleri: /* 1. Fluid Typography - clamp ile */ h1 { font-size: clamp(1.5rem, 5vw, 3rem); } /* 2. Full-width sections - overflow kontrolü ile */ .full-width { width: 100%; max-width: 100vw; margin-left: calc(-50vw + 50%); margin-right: calc(-50vw + 50%); } /* 3. Hero sections - fallback ile */ .hero { min-height: 600px; /* Fallback */ min-height: 100vh; /* Standart */ min-height: 100dvh; /* Modern */ } /* 4. Responsive spacing - rem ile kombinasyon */ .section { padding: clamp(2rem, 5vw, 6rem); } /* 5. Aspect ratio control - vmin ile */ .video-container { width: 80vmin; height: 45vmin; /* 16:9 aspect ratio her durumda */ } Kaçınılması Gerekenler: /* ❌ Kesinlikle yapma */ * { font-size: 2vw; /* Accessibility felaketi */ } /* ❌ Scrollbar sorunları */ body { width: 100vw; /* Yatay scroll oluşturur */ } /* ❌ Mobile keyboard sorunu */ .modal { height: 100vh; /* Keyboard açıldığında kesilir */ } /* ❌ Aşırı karmaşık hesaplamalar */ .element { width: calc(100vw - (100vw - 100%) - 2rem); } Özet Viewport birimleri güçlü araçlar ama: Mobile browser davranışlarını iyi bilmek şart Her zaman fallback değerler kullanın Accessibility'yi göz ardı etmeyin (clamp kullanın) Modern dvh, svh, lvh birimlerini öğrenin Performans etkilerini düşünün Container query birimlerini de değerlendirin Doğru kullanıldığında viewport birimleri gerçekten responsive ve fluid tasarımlar oluşturmanıza olanak sağlar, ama tuzaklarını bilmek kritik.
  14. Heading(h1,h2,h3,h4,h5,h6) elementlerini sayfamızda kullanırken CSS'de stil uygularız. Bu uygulanan stillerin ne olduğunu bilmek için tarayıcının h1 elementine default olarak uyguladığı stilleri bilmek gerektirir. Çünkü başlangıç noktamız tarayıcı stilleridir. 1. Browser User Agent Stylesheet (Tarayıcı Varsayılan Stilleri) Chrome/WebKit Default Styles /* Chrome'un h1 için varsayılan stilleri */ h1 { display: block; font-size: 2em; margin-block-start: 0.67em; margin-block-end: 0.67em; margin-inline-start: 0px; margin-inline-end: 0px; font-weight: bold; } Tarayıcıların İç İçe h1 Mantığı /* 1 seviye iç içe (article > h1) */ :-webkit-any(article,aside,nav,section) h1 { font-size: 1.5em; margin-block-start: 0.83em; margin-block-end: 0.83em; } /* 2 seviye iç içe (article > section > h1) */ :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) h1 { font-size: 1.17em; margin-block-start: 1em; margin-block-end: 1em; } /* 3 seviye iç içe */ :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) h1 { font-size: 1em; /* Normal metin boyutu! */ margin-block-start: 1.33em; margin-block-end: 1.33em; } /* 4 seviye iç içe */ :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) h1 { font-size: 0.83em; /* h1, h5'ten küçük! */ margin-block-start: 1.67em; margin-block-end: 1.67em; } /* 5 seviye iç içe */ :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) :-webkit-any(article,aside,nav,section) h1 { font-size: 0.67em; /* h1, h6'dan küçük! */ margin-block-start: 2.33em; margin-block-end: 2.33em; } Tüm Başlık Seviyelerinin Varsayılan Boyutları h1 { font-size: 2em; margin: 0.67em 0; } /* 32px */ h2 { font-size: 1.5em; margin: 0.83em 0; } /* 24px */ h3 { font-size: 1.17em; margin: 1em 0; } /* 18.72px */ h4 { font-size: 1em; margin: 1.33em 0; } /* 16px */ h5 { font-size: 0.83em; margin: 1.67em 0; } /* 13.28px */ h6 { font-size: 0.67em; margin: 2.33em 0; } /* 10.72px */ 2. HTML5 Outline Algorithm'ın Hikayesi HTML5'in Vaat Ettiği (Ama Gerçekleşmeyen) HTML5 şunu söyledi: "Her semantic section kendi başlık hiyerarşisine sahip olabilir!" <!-- HTML5'in hayali --> <body> <h1>Site Başlığı</h1> <article> <h1>Makale Başlığı</h1> <!-- Tarayıcı bunu h2 gibi ele alsın --> <section> <h1>Bölüm Başlığı</h1> <!-- Tarayıcı bunu h3 gibi ele alsın --> </section> </article> <aside> <h1>Sidebar Başlığı</h1> <!-- Tarayıcı bunu h2 gibi ele alsın --> </aside> </body> Problem: ❌ Hiçbir tarayıcı bu algoritma tam olarak uygulamadı ❌ Ekran okuyucular bu yapıyı doğru anlamıyor ❌ SEO açısından kafa karıştırıcı ❌ W3C 2022'de resmi olarak vazgeçti Gerçekte Ne Oldu? Tarayıcılar sadece görsel olarak küçülttüler, ama semantik olarak değiştirmediler: <article> <section> <h1>Bu başlık</h1> </section> </article> <!-- Ekran okuyucular bunu şöyle görür: --> <!-- "Heading level 1: Bu başlık" --> <!-- (h2 değil, h1 olarak!) --> 3. Modern CSS Yaklaşımları ❌ Yapılmaması Gerekenler <!-- KÖTÜ: İç içe h1 kullanımı --> <article> <h1>Ana Başlık</h1> <section> <h1>Alt Başlık</h1> <!-- Tarayıcı küçültür ama semantik yanlış --> </section> </article> <!-- KÖTÜ: Sadece görsel için h1 --> <div class="hero"> <h1>Hoş Geldiniz</h1> <!-- Sayfa başlığı değilse h1 olmamalı --> </div> ✅ Modern Doğru Yaklaşım <!-- İYİ: Doğru semantik hiyerarşi --> <article> <h1>Makale Başlığı</h1> <section> <h2>Bölüm Başlığı</h2> <h3>Alt Bölüm</h3> <h4>Detay</h4> </section> </article> Modern CSS Reset/Normalize /* Modern CSS Reset Yaklaşımı */ /* 1. Tarayıcı varsayılanlarını sıfırla */ h1, h2, h3, h4, h5, h6 { margin: 0; font-size: inherit; /* Parent'tan al */ font-weight: inherit; line-height: inherit; } /* 2. Kendi design system'ini kur */ :root { /* Typographic Scale (Major Third - 1.250) */ --font-size-base: 1rem; /* 16px */ --font-size-lg: 1.25rem; /* 20px */ --font-size-xl: 1.563rem; /* 25px */ --font-size-2xl: 1.953rem; /* 31px */ --font-size-3xl: 2.441rem; /* 39px */ --font-size-4xl: 3.052rem; /* 49px */ /* Spacing Scale */ --space-xs: 0.5rem; --space-sm: 1rem; --space-md: 1.5rem; --space-lg: 2rem; --space-xl: 3rem; /* Line Heights */ --line-height-tight: 1.2; --line-height-normal: 1.5; --line-height-loose: 1.8; } /* 3. Semantic heading styles */ h1 { font-size: var(--font-size-4xl); font-weight: 700; line-height: var(--line-height-tight); margin-block-end: var(--space-lg); letter-spacing: -0.02em; /* Optik düzeltme */ } h2 { font-size: var(--font-size-3xl); font-weight: 700; line-height: var(--line-height-tight); margin-block-start: var(--space-xl); margin-block-end: var(--space-md); } h3 { font-size: var(--font-size-2xl); font-weight: 600; line-height: var(--line-height-tight); margin-block-start: var(--space-lg); margin-block-end: var(--space-sm); } h4 { font-size: var(--font-size-xl); font-weight: 600; line-height: var(--line-height-normal); margin-block-start: var(--space-md); margin-block-end: var(--space-sm); } h5 { font-size: var(--font-size-lg); font-weight: 600; line-height: var(--line-height-normal); margin-block-start: var(--space-md); margin-block-end: var(--space-xs); } h6 { font-size: var(--font-size-base); font-weight: 600; line-height: var(--line-height-normal); margin-block-start: var(--space-sm); margin-block-end: var(--space-xs); text-transform: uppercase; letter-spacing: 0.05em; } 4. Utility-First Yaklaşım (Tailwind tarzı) <!-- Semantic HTML + Utility Classes --> <article> <h1 class="text-5xl font-bold leading-tight mb-8"> Ana Başlık </h1> <h2 class="text-3xl font-semibold leading-snug mt-12 mb-6"> Alt Başlık </h2> <h3 class="text-2xl font-medium leading-normal mt-8 mb-4"> Bölüm Başlığı </h3> </article> /* Custom utility system */ .text-5xl { font-size: 3rem; } .text-3xl { font-size: 1.875rem; } .text-2xl { font-size: 1.5rem; } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } .leading-tight { line-height: 1.2; } .leading-snug { line-height: 1.375; } .leading-normal { line-height: 1.5; } 5. Component-Based Yaklaşım /* Semantic başlıklar + görsel class'lar ayırımı */ /* Semantic HTML her zaman doğru */ <article> <h1 class="display-1">Görsel Başlık</h1> <h2 class="title-large">Alt Başlık</h2> </article> <section> <h2 class="display-2">Büyük Başlık (ama h2)</h2> <h3 class="body-large">Küçük Başlık (ama h3)</h3> </section> /* CSS */ .display-1 { font-size: clamp(2.5rem, 5vw + 1rem, 4rem); font-weight: 800; line-height: 1.1; letter-spacing: -0.02em; } .display-2 { font-size: clamp(2rem, 4vw + 1rem, 3rem); font-weight: 700; line-height: 1.2; } .title-large { font-size: clamp(1.5rem, 3vw + 0.5rem, 2rem); font-weight: 600; line-height: 1.3; } .body-large { font-size: 1.25rem; font-weight: 500; line-height: 1.5; } 6. Responsive Typography /* Modern fluid typography */ h1 { /* min: 32px, max: 64px, viewport-based scaling */ font-size: clamp(2rem, 4vw + 1rem, 4rem); /* Container query ile responsive */ font-size: clamp(2rem, 8cqi, 4rem); line-height: 1.1; margin-block-end: clamp(1rem, 3vw, 2rem); } /* Breakpoint-based (geleneksel) */ h1 { font-size: 2rem; /* 32px - mobile */ } @media (min-width: 640px) { h1 { font-size: 2.5rem; /* 40px - tablet */ } } @media (min-width: 1024px) { h1 { font-size: 3rem; /* 48px - desktop */ } } @media (min-width: 1280px) { h1 { font-size: 4rem; /* 64px - large desktop */ } } 7. Modern Best Practices Özet /* Tam Modern H1 Implementasyonu */ /* 1. Reset browser defaults */ h1 { margin: 0; font-size: inherit; font-weight: inherit; } /* 2. Override nested sectioning bugs */ article h1, aside h1, nav h1, section h1 { font-size: inherit; /* Parent'tan al, tarayıcı küçültmesin */ } /* 3. Custom design system */ h1 { /* Responsive fluid sizing */ font-size: clamp(2rem, 5vw + 1rem, 4rem); /* Typography */ font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; /* Spacing with logical properties */ margin-block-end: clamp(1rem, 3vw, 2rem); /* Color with custom properties */ color: var(--color-heading, hsl(0 0% 10%)); /* Text wrapping */ text-wrap: balance; /* Modern tarayıcılarda */ max-inline-size: 20ch; /* Optimal başlık genişliği */ } /* 4. Context variants */ .hero h1 { font-size: clamp(3rem, 8vw + 1rem, 6rem); text-align: center; } .article h1 { font-size: clamp(2rem, 4vw + 1rem, 3rem); } .card h1 { font-size: 1.5rem; } /* 5. Dark mode */ @media (prefers-color-scheme: dark) { h1 { color: var(--color-heading-dark, hsl(0 0% 95%)); } } 8. Gerçek Dünya Örneği <!DOCTYPE html> <html lang="tr"> <head> <style> /* Modern H1 Implementation */ * { margin: 0; padding: 0; box-sizing: border-box; } :root { --color-text: hsl(0 0% 10%); --color-bg: hsl(0 0% 98%); --font-base: system-ui, -apple-system, sans-serif; } body { font-family: var(--font-base); color: var(--color-text); background: var(--color-bg); line-height: 1.6; padding: 2rem; } /* h1 reset - tarayıcı otomatik küçültmesini engelle */ h1 { font-size: inherit; font-weight: inherit; margin: 0; } /* Semantic yapı */ .page-title { font-size: clamp(2.5rem, 6vw + 1rem, 4.5rem); font-weight: 800; line-height: 1.1; letter-spacing: -0.03em; margin-block-end: 1.5rem; text-wrap: balance; } .section-title { font-size: clamp(1.75rem, 4vw + 0.5rem, 3rem); font-weight: 700; line-height: 1.2; margin-block-start: 3rem; margin-block-end: 1rem; } .card-title { font-size: 1.5rem; font-weight: 600; line-height: 1.3; margin-block-end: 0.5rem; } article { max-width: 70ch; } section { margin-block: 2rem; } </style> </head> <body> <article> <!-- Sayfa ana başlığı --> <h1 class="page-title">Modern H1 Kullanımı</h1> <section> <!-- Alt bölüm başlığı --> <h2 class="section-title">İlk Bölüm</h2> <p>İçerik...</p> <div class="card"> <!-- Kart başlığı --> <h3 class="card-title">Kart Başlığı</h3> <p>Kart içeriği...</p> </div> </section> </article> </body> </html> 9. Kritik Kurallar ✅ YAP: Her sayfada sadece bir h1 kullan Başlık hiyerarşisini atlamadan ilerle (h1 → h2 → h3) Semantic HTML kullan, görsel için class kullan clamp() ile fluid typography uygula Logical properties kullan (margin-block, margin-inline) ❌ YAPMA: İç içe section'larda h1 tekrarlama h1'den h3'e atlama (h2'yi atlayarak) Sadece görsel için h1 kullanma Tarayıcının otomatik küçültmesine güvenme Fixed pixel değerleri kullanma Sonuç: Tarayıcının varsayılan h1 davranışı karmaşık ve artık kullanılmıyor. Modern yaklaşım: doğru semantic HTML + custom CSS design system + fluid typography + accessibility!
  15. Relative units, bir öğenin boyutunu başka bir değere göre belirleyen birimlerdir. Sabit (absolute) birimlerden farklı olarak, responsive tasarım için çok daha uygun ve esnek çözümler sunarlar. Ana Relative Units rem (root em) Root element'in (html) font-size'ına göre hesaplanır 1rem = html'in font-size değeri (genelde 16px) En çok kullanılan ve önerilen birim html { font-size: 16px; /* 1rem = 16px */ } .container { padding: 2rem; /* 32px */ margin-bottom: 1.5rem; /* 24px */ } em Parent element'in font-size'ına göre hesaplanır İç içe kullanımlarda kümülatif etki yapar Daha spesifik durumlarda kullanılır .parent { font-size: 20px; } .child { padding: 1em; /* 20px (parent'ın font-size'ı) */ font-size: 0.8em; /* 16px */ } % (percentage) Parent element'in ilgili özelliğine göre hesaplanır Width/height için çok kullanışlı .container { width: 80%; /* Parent'ın genişliğinin %80'i */ } vw/vh (viewport units) vw: viewport width'in %1'i vh: viewport height'in %1'i 100vw = tam ekran genişliği .hero { height: 100vh; /* Tam ekran yüksekliği */ width: 100vw; /* Tam ekran genişliği */ } vmin/vmax vmin: viewport'un küçük boyutunun %1'i vmax: viewport'un büyük boyutunun %1'i ch "0" karakterinin genişliği Metin genişlikleri için kullanışlı p { max-width: 65ch; /* Okunabilir satır uzunluğu */ } Hangi Özellikte Hangisi Kullanılmalı? Font-size → rem h1 { font-size: 2.5rem; } p { font-size: 1rem; } small { font-size: 0.875rem; } ✅ Tutarlı ölçeklendirme ✅ Kullanıcı tercihlerine saygı Spacing (padding/margin) → rem .card { padding: 2rem; margin-bottom: 1.5rem; } ✅ Tutarlı aralıklar ✅ Global ölçeklendirme Width/max-width → % veya ch .container { width: 90%; /* veya */ max-width: 1200px; } p { max-width: 65ch; /* Okunabilirlik için */ } Height (full-screen) → vh .hero { height: 100vh; min-height: 500px; /* Fallback */ } Line-height → unitless number p { line-height: 1.6; /* Birim yok! */ } ✅ Font-size ile orantılı ölçeklenir Border-radius → px veya % .button { border-radius: 8px; /* Sabit yuvarlaklık */ } .circle { border-radius: 50%; /* Tam daire */ } Component içi ilişkiler → em .button { font-size: 1rem; padding: 0.5em 1em; /* Font-size'a göre */ border-radius: 0.25em; } ✅ Component kendi içinde ölçeklenebilir Örnek: /* Modern CSS Architecture */ :root { --spacing-xs: 0.5rem; --spacing-sm: 1rem; --spacing-md: 1.5rem; --spacing-lg: 2rem; --spacing-xl: 3rem; } html { font-size: 100%; /* Kullanıcı tercihlerine saygı */ } body { font-size: 1rem; line-height: 1.6; } /* Layout */ .container { width: 90%; max-width: 1200px; margin: 0 auto; padding: var(--spacing-md); } /* Typography */ h1 { font-size: 2.5rem; } h2 { font-size: 2rem; } h3 { font-size: 1.5rem; } p { font-size: 1rem; max-width: 65ch; } /* Components */ .button { font-size: 1rem; padding: 0.75em 1.5em; /* em kullanımı */ border-radius: 0.25em; } /* Full-screen */ .hero { min-height: 100vh; } Altın kural: Genel olarak rem kullan, component(button, card, navbar, modal vb..) içi ilişkiler için em, layout için % ve tam ekran için vh tercih et!
×
×
  • Create New...

Important Information