今日已更新 264 条资讯 | 累计 23847 条内容
关于我们

标签:#css

找到 57 篇相关文章

AI 资讯

CSS: Decoupling Behaviors

A press effect, shadow on rest, lifted on hover, depressed on active, is not central to buttons. It can be used on cards, image gallery photos, and other elements. The same goes for animations and other behaviors. This leaves me to question "why aren't they decoupled from the component? In my own code I create with a dedicated behaviors layer. Each interaction pattern is its own class, independent of any component. You can even stack multiple behaviors together. Let's create a simple one that adds more click affordance. Press Example Adding b-press gives any flat element a physical depth through shadow states. It lifts on hover and depresses on active, giving users a clear sense that something is clickable. Disabled elements will lose the shadow entirely so the affordance disappears with the interaction. CSS @layer behaviors { .b-press { box-shadow: var(--wisp-shadow, 0 1px 2px rgba(0, 0, 0, 0.10), 0 1px 3px rgba(0, 0, 0, 0.06) ); cursor: pointer; } .b-press:hover { box-shadow: var(--wisp-shadow-hover, 0 4px 6px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.10) ); } .b-press:active { box-shadow: var(--wisp-shadow-active, 0 1px 2px rgba(0, 0, 0, 0.16), 0 1px 1px rgba(0, 0, 0, 0.12) ); transform: translateY(1px); } .b-press:disabled, .b-press[aria-disabled="true"] { box-shadow: 0 0 0 rgba(0, 0, 0, 0); cursor: not-allowed; } } HTML <div class="o-card b-press"> ... </div> Finally When we think of OOCSS we think of visual repeating patterns, but behaviors are patterns too and deserve the same love that objects and components get. You can find the decoupled behaviors in my framework source here: https://github.com/wispcode/wisp-css/tree/main/src/behaviors

2026-06-09 原文 →
AI 资讯

CSS if(): Inline Conditionals for Smarter Styling

Originally published on danholloran.me There's a moment every CSS developer knows: you want to tweak a single property based on some condition — a viewport width, a user preference, a custom property — and instead of a clean one-liner you end up with a whole new @media block, duplicated selectors, and maybe a dash of JavaScript to handle the edge cases. It works, but it never feels right. The CSS if() function changes that. Shipping in Chrome 137, it brings inline conditional logic directly into your property declarations, letting you express branching style logic without leaving the property itself. How if() Works The syntax is a sequence of condition-value pairs, evaluated top to bottom until one matches: property : if ( condition : value ; else : fallback ); The function supports three types of conditions: style() — queries computed CSS custom property values media() — runs an inline media query supports() — feature-detects a CSS property or syntax You can chain them with else : button { padding : if ( media ( width >= 1024px ): 0.5rem 1.5rem ; else : 0.75rem 1.25rem ); } That's a responsive padding rule with zero extra @media blocks. Three Practical Uses 1. Touch-Friendly Targets with media() The pointer media feature lets you distinguish mouse users from touchscreen users. The accessible minimum tap target is 44px; mouse users can get away with smaller: .icon-button { width : if ( media ( any-pointer : fine ): 32px ; else : 44px ); height : if ( media ( any-pointer : fine ): 32px ; else : 44px ); } Previously this needed a full @media (any-pointer: coarse) block. Now it reads like what it is — a single property with two states. 2. Theme Switching with style() Custom properties are often used to carry design tokens — theme flags, component variants, status values. The style() query lets you branch on them inline: .status-badge { --status : pending ; background : if ( style ( --status : complete ): #22c55e ; style( --status : error ): #ef4444 ; else : #f59e0b );

2026-06-09 原文 →
AI 资讯

How to Install Tailwind CSS v4 in a .NET Blazor App (The Easy Way)

A step-by-step, beginner-friendly guide to stripping out Bootstrap and setting up the blazing-fast Tailwind CSS v4 compiler in your .NET Blazor Hybrid or Web app. Tailwind CSS v4 is officially here, and it is a complete game-changer! It scraps the old, bulky JavaScript configuration files ( tailwind.config.js ) and moves your theme settings directly into standard CSS. Plus, its new native compiler is faster than ever. If you are building a .NET Blazor app (whether it's Blazor WebAssembly, Server, or a MAUI Blazor Hybrid app) and want to swap out the default Bootstrap styles for utility-first Tailwind bliss, you can do it all without ever leaving your IDE. Let's get this configured step-by-step using Visual Studio 2022 ! Prerequisites Before we start, make sure you have: Node.js installed on your development machine. A Blazor project opened in Visual Studio 2022 . Step 1: Say Goodbye to Bootstrap in Solution Explorer Blazor templates ship with Bootstrap by default. Let's use Visual Studio's Solution Explorer to clean that out so our styles don't conflict. In the Solution Explorer window, expand your wwwroot folder. Expand the css subfolder. Right-click the bootstrap folder and select Delete . Now, open your main HTML entry file inside wwwroot (this will be index.html for Blazor Hybrid/WASM or App.razor inside the Components folder for Blazor Web). Locate the <head> section and delete the line linking the Bootstrap stylesheet: <link rel= "stylesheet" href= "css/bootstrap/bootstrap.min.css" /> powershell Step 2: Open the Developer PowerShell & Install Tailwind v4 Tailwind v4 splits the design library from the command-line build tool, so we need to install both. We can use Visual Studio's built-in terminal for this. In the top menu of Visual Studio 2022, go to Tools > Command Line > Developer PowerShell . A terminal window will open at the bottom of your IDE, already navigated to your project folder. Paste and run the following commands: i. Initialize a package.json fil

2026-06-08 原文 →
AI 资讯

How to Install Tailwind CSS v4 in a .NET Blazor App (The Easy Way)

A step-by-step, beginner-friendly guide to stripping out Bootstrap and setting up the blazing-fast Tailwind CSS v4 compiler in your .NET Blazor Hybrid or Web app. Tailwind CSS v4 is officially here, and it is a complete game-changer! It scraps the old, bulky JavaScript configuration files ( tailwind.config.js ) and moves your theme settings directly into standard CSS. Plus, its new native compiler is faster than ever. If you are building a .NET Blazor app (whether it's Blazor WebAssembly, Server, or a MAUI Blazor Hybrid app) and want to swap out the default Bootstrap styles for utility-first Tailwind bliss, you can do it all without ever leaving your IDE. Let's get this configured step-by-step using Visual Studio 2022 ! Prerequisites Before we start, make sure you have: Node.js installed on your development machine. A Blazor project opened in Visual Studio 2022 . Step 1: Say Goodbye to Bootstrap in Solution Explorer Blazor templates ship with Bootstrap by default. Let's use Visual Studio's Solution Explorer to clean that out so our styles don't conflict. In the Solution Explorer window, expand your wwwroot folder. Expand the css subfolder. Right-click the bootstrap folder and select Delete . Now, open your main HTML entry file inside wwwroot (this will be index.html for Blazor Hybrid/WASM or App.razor inside the Components folder for Blazor Web). Locate the <head> section and delete the line linking the Bootstrap stylesheet: <link rel= "stylesheet" href= "css/bootstrap/bootstrap.min.css" /> powershell Step 2: Open the Developer PowerShell & Install Tailwind v4 Tailwind v4 splits the design library from the command-line build tool, so we need to install both. We can use Visual Studio's built-in terminal for this. In the top menu of Visual Studio 2022, go to Tools > Command Line > Developer PowerShell . A terminal window will open at the bottom of your IDE, already navigated to your project folder. Paste and run the following commands: i. Initialize a package.json fil

2026-06-08 原文 →
AI 资讯

🚨 CSS Specificity — The Hidden Reason Your UI Breaks

Most developers learn CSS specificity once. They remember: #id > .class > div Then move on. Until one day… Everything looks correct. The CSS is present. The selector is correct. The z-index looks higher. And yet the UI is broken. That’s when CSS specificity stops being a beginner topic and becomes a production debugging problem. The Production Incident That Started This Recently, I was working on a microfrontend application. Everything worked fine initially. I opened a page, launched a modal and the UI looked correct. Then I navigated to another microfrontend. Its CSS got loaded. After returning to the original microfrontend, suddenly: ❌ Modal appeared behind page content ❌ Overlay behaved incorrectly ❌ z-index looked correct but wasn't working DevTools showed my CSS rule still existed. Yet another CSS rule was winning. The culprit? CSS Specificity. 🧠 What is CSS Specificity? CSS specificity is the algorithm browsers use to decide: Which CSS rule wins when multiple rules target the same element. Browsers don't simply apply: "The last CSS rule." That's one of the biggest misconceptions. Specificity is calculated first. Only when specificity is equal does source order become important. ⚔️ Example .modal { z-index : 9999 ; } .some-library .modal { z-index : 100 ; } HTML: <div class= "some-library" > <div class= "modal" ></div> </div> Many developers expect: .modal to win because the value is larger. But CSS doesn't compare values first. It compares selectors. 🧮 How Specificity Works Specificity is usually represented as: ID - CLASS - TYPE Specificity Table Selector Specificity * 0-0-0 div 0-0-1 .modal 0-1-0 [type="text"] 0-1-0 :hover 0-1-0 #dialog 1-0-0 Inline Style Highest MDN defines specificity as the weight browsers calculate to determine which declaration gets applied when multiple selectors match the same element. Example Calculation Selector: button .primary Contains: button → 0 -0-1 .primary → 0 -1-0 Total: 0-1-1 Another selector: #header button .primary Contai

2026-06-06 原文 →
AI 资讯

Premium micro-interactions in React 19 (without the jank)

There's a specific kind of bad animation I notice immediately: the count-up stat that stutters as it ticks, the progress bar that lags a frame behind your scroll, the "active" tab underline that snaps instead of glides. None of it is broken, exactly. It just feels cheap. And nine times out of ten, the cause is the same — the animation is being driven through React state, so every frame triggers a re-render, and the main thread can't keep up. I build motion-heavy interfaces for a living, mostly in Next.js 16 and React 19, and I've landed on a small set of patterns that stay smooth because they bypass React's render loop entirely . They lean on Motion — the library formerly known as Framer Motion. It went independent and got renamed in 2025, so the package is now motion and the import you want is motion/react , not framer-motion ( the APIs are identical, only the import path changed ). Here are three I reach for constantly, plus the reduced-motion discipline that should wrap all of them. The mental model: MotionValues over state The single idea that fixes most jank: a MotionValue is a value Motion tracks outside of React. When it changes, Motion updates the DOM directly via transform or opacity — it does not call setState , so your component doesn't re-render. That's the whole trick. A number ticking from 0 to 4,200 should touch the DOM ~60 times a second and re-render React zero times. If a value changes every frame, it should live in a MotionValue, not in useState . State is for things that change when a user does something; MotionValues are for things that change continuously. Keep that line in your head and the rest of this falls out naturally. 1. A reading-progress bar with useScroll + useSpring The bar at the top of an article that fills as you read. The naive version listens to scroll events and sets state — which is exactly the re-render trap. Motion's useScroll hands you scroll position as a MotionValue already, so there's nothing to re-render. useScroll retu

2026-06-04 原文 →
产品设计

HTML TAGS & CSS PROPERTIES

What are HTML Tags? HTML documents consist of a series of elements, and these elements are defined using HTML tags. HTML tags are essential building blocks that define the structure and content of a webpage. HTML tags are composed of an opening tag, content, and a closing tag. The opening tag marks the beginning of an element, and the closing tag marks the end. The content is the information or structure that falls between the opening and closing tags. For Example: <h1>Hello</h1> HTML Elements HTML elements are the essential components of a webpage and provide structure, organization, and meaning to content. Elements are defined by HTML tags which define how different types of content will appear in a browser window. For Example: <p> This is an element. </p> Block-Level Elements A page’s entire width is occupied by a block-level element. The document always begins with a new line. An HTML page generally has three tags i.e., <html> , <head> , and <body> tag. Example: The following is an unordered list, an example of block-level elements. List item 1 List item 2 Inline Elements A block-level element’s inner content can be formatted with an inline element by adding links and stressed strings. These elements help you to format text without disrupting the content’s flow. Example: The following code creates a hyperlink to a URL. It is an inline element because it is used within paragraphs, headings, or other text content to create hyperlinks. It does not disrupt the flow of the document by forcing new lines before or after its content. <a href="https://www.example.com"> Visit Example </a> CSS Properties CSS properties are used to decorate your web page and assign a unique behavior to your HTML element. CSS properties are the foundation of web design, used to style and control the behaviour of HTML elements. They define how elements look and interact on a webpage. Used to control layout, colors, fonts, spacing, and animations on web pages. It is essential for making web pa

2026-06-03 原文 →
开发者

@custom-media

The CSS @custom-media at-rule allows creating aliases for media queries. @custom-media originally handwritten and published with love on CSS-Tricks . You should really get the newsletter as well.

2026-06-03 原文 →
AI 资讯

@function

The @function at-rule defines CSS custom functions. These custom functions are reusable blocks of CSS that can accept arguments, contain complex logic, and return values based on that logic. @function originally handwritten and published with love on CSS-Tricks . You should really get the newsletter as well.

2026-06-03 原文 →
AI 资讯

Building a Car Showroom Website for Only $50 (800,000 IDR)

Recently, I started building a website for a local car showroom. The budget? 800,000 Indonesian Rupiah (around $50 USD). At first, it sounded impossible. But when working with small businesses in Indonesia, budgets are often very different from what many developers in the US or Europe are used to. Instead of building a complex custom platform, I focused on solving the showroom's real problems. What the client gets Vehicle Management Add and edit car listings Manage prices Vehicle specifications Featured inventory Vehicle Search & Filters Visitors can filter cars by: Brand Model Year Price Condition Built-in CMS The showroom can publish: Car buying guides Automotive news SEO articles Promotions Lead Generation Every car listing includes direct WhatsApp contact buttons to maximize inquiries. Extra Services Included For the same price: Free maintenance for simple issues Free consultation and support 3 free blog articles during the first month AI-powered statistics assistant Why WordPress? Many developers immediately think about Laravel, React, Next.js, microservices, and other modern stacks. For this project, WordPress was the right tool. The client needed: A website they could update themselves Better Google visibility A simple inventory system More WhatsApp leads WordPress delivered all of that quickly. A Lesson I've Learned Small businesses rarely care about technology. They care about outcomes. They don't ask: "Does it use React?" They ask: "Will this help me sell more cars?" And honestly, that's probably the better question. What would you include in a low-budget car showroom website?

2026-06-02 原文 →
AI 资讯

I Spent 2 Months Building a 150+ Tool Website with $0 Server Cost

📚 This is Part 1 (Opening) of the UtlKit Tech Series — Next: [Architecture & Trade-offs →] As a frontend developer, I've used countless online tools. And almost all of them suck: Sign-up required — just to format a JSON string? Ad overload — the actual tool gets squeezed into a corner Privacy concerns — your JSON might contain API keys, and the tool sends it to a server Fragmented — formatters on one site, Base64 on another, hashing on a third So I decided to build one that doesn't: no sign-up, no ads, pure client-side computation, data never leaves the browser. The goal was simple — if I need this tool, someone else does too. The result is utlkit.com : 150+ tools, 8 categories, zero server costs. Requirements Requirement Meaning Pure client-side All logic runs in the browser Zero server cost Static hosting, no Node.js backend 150+ pages One page per tool, SEO-friendly Bilingual (EN/ZH) i18n support Dark/Light mode User preference Mobile responsive Works on all devices Why Not Other Frameworks? Option Pros Cons Verdict Vanilla HTML/JS Simple Managing 150+ pages is painful Too slow VuePress / VitePress Fast Docs-oriented, not for interactive tools Not flexible enough Nuxt SSR Powerful Needs a server Violates zero-cost principle Next.js 15 + output: 'export' SSR SEO + client interactivity + static hosting Has pitfalls (covered later) ✅ Best balance The Key Decision: output: 'export' // next.config.js const nextConfig = { output : ' export ' , // Static export trailingSlash : true , // Required for static files images : { unoptimized : true }, // No image optimization server } This means: ✅ Build output is plain HTML/CSS/JS files ✅ Deployable to any static host (Cloudflare Pages, Vercel, GitHub Pages) ✅ Zero server cost ❌ No API Routes, no Server Components, limited dynamic routing Deployment: Zero Cost on Cloudflare Pages Build output : out/ directory, ~14 MB Hosting : Cloudflare Pages Domain : utlkit.com Monthly cost : $0 Build Pipeline npm run build → next build ( o

2026-06-01 原文 →
AI 资讯

State-Driven Animations in Vue: Create Smooth UI Transitions with Reactive State

Animations can make an application feel faster, smoother, and more polished. However, many developers think animations are only useful for things like: page transitions modals enter/leave effects But Vue provides another powerful pattern - State-driven animations. Instead of animating when elements are added or removed from the DOM, you animate changes in reactive state. This allows you to create rich interactive experiences while keeping your code declarative and easy to maintain. In this article, we'll explore: What state-driven animations are How they differ from regular Vue transitions What problems they solve How to implement them in Vue Best practices for creating smooth UI interactions Let's dive in. 🤔 What Are State-Driven Animations? Most Vue developers are familiar with the <Transition> component. Example: <Transition> <Modal v-if= "isOpen" /> </Transition> This animates an element when it enters or leaves the DOM. But what if the element already exists and only its state changes? For example: a progress bar grows a card expands a chart updates a panel changes size a value changes position This is where state-driven animations shine. Instead of animating DOM insertion or removal, you animate changes caused by reactive state. 🟢 What Problem Do State-Driven Animations Solve? Without animations, state changes can feel abrupt. Example: <div :style= "{ width: progress + '%' }" ></div> When progress changes: progress . value = 80 The width instantly jumps. This works technically... but it doesn't feel great. 🟢 A Simple Example Let's create an animated progress bar. < script setup lang= "ts" > const progress = ref ( 20 ) function increase () { progress . value += 20 } </ script > < template > <button @ click= "increase" > Increase Progress </button> <div class= "progress-container" > <div class= "progress-bar" :style= " { width: `${progress}%` }" /> </div> </ template > CSS: .progress-container { width : 100% ; height : 12px ; background : #eee ; } .progress-bar

2026-06-01 原文 →
AI 资讯

Why your React tournament bracket breaks in Safari (and a 4 KB pure-CSS fix)

You build a tournament bracket with a popular React library. In Chrome it's perfect — neat columns, clean connector lines. Then you open it on an iPhone, or in Safari, or inside your Capacitor app… and every match is crammed into the top-left corner, stacked on top of the round headers. If you've ever shipped a bracket to iOS, you've probably seen this exact bug. Here's why it happens — and a tiny library that fixes it for good. The symptom It looks fine everywhere Chromium runs (Chrome, Edge, Android WebView) and completely broken everywhere WebKit runs: Safari (macOS and iOS) iOS WKWebView Capacitor / Cordova apps Electron-on-WebKit The matches don't just shift a little — they all render at coordinate (0,0) of the bracket, piling on top of each other and the headers. The cause: SVG <foreignObject> in WebKit Most React bracket libraries — @g-loot/react-tournament-brackets , react-tournament-bracket , and friends — render the bracket as an SVG and place each match's HTML inside a <foreignObject> positioned with x / y attributes. WebKit has a long-standing bug: it ignores x , y , and transform on <foreignObject> and positions the content relative to the top-level <svg> instead of the foreignObject's own coordinates. Every match therefore collapses to the origin. And there's no CSS escape hatch — x , y , and transform are all ignored on foreignObject in Safari, so you can't nudge the content back into place. I even tried patching a library to wrap each match in a <g transform="translate(x,y)"> instead of a nested <svg x y> ; WebKit ignores ancestor transforms for foreignObject positioning too. The SVG approach is simply a dead end on WebKit. The fix: don't use SVG at all A bracket is really just columns of cards joined by connector lines — and both are expressible in plain CSS. Here's the key insight. Put each round in a flex column where every match sits in an equal flex: 1 slot. Because each round has half the matches of the previous one, a match's slot spans exactl

2026-05-31 原文 →
AI 资讯

CSS @function

CSS just got its biggest quality-of-life upgrade since custom properties. For years, if you wanted reusable logic in CSS, you had two choices: wrestle with custom properties that couldn't do real computation, or reach for a preprocessor like Sass. That era just quietly ended. CSS now has native custom functions — and they're as powerful as you'd hope. 1. What Exactly Is @function ? Think of it exactly like a JavaScript function — but living inside your stylesheet. You give it a name (always prefixed with -- ), define some parameters, and write a result: descriptor that determines what it returns. /* BASIC SYNTAX */ /* Define it once */ @function --double ( --x ) { result : calc ( var ( --x ) * 2 ); } /* Call it anywhere */ .box { width : --double ( 20px ); /* → 40px */ height : --double ( 50px ); /* → 100px */ } No var() wrapper needed to call it. No build step. No Sass import. Just define and use — as many times as you like, across your entire stylesheet. Note: Unlike Sass, native CSS functions don't evaluate math automatically. You must wrap mathematical operations in calc() inside your result descriptor. 2. The Syntax in Full Detail Parameters with Default Values You can make parameters optional by giving them a fallback — the function still works even if you don't pass a value. @function --spacing ( --size : 16px ) { result : calc ( var ( --size ) * 1.5 ); } .card { padding : --spacing (); /* → 24px (uses default) */ margin : --spacing ( 20px ); /* → 30px */ } Type-Safe Parameters You can declare the expected type of each parameter — and the return type too. The browser will validate this at parse time, preventing weird cascading bugs. @function --fade ( --color < color > , --alpha < number > : 0.5 ) returns < color > { result : color-mix ( in srgb , var ( --color ), transparent calc ( var ( --alpha ) * 100% ) ); } .overlay { background : --fade ( royalblue , 0.3 ); /* 70% opaque blue */ } Logic Inside Functions This is where @function gets genuinely exciting. Y

2026-05-31 原文 →
AI 资讯

I don't want to write HTML or fight global CSS, so I built a TypeScript DSL

TL;DR I got tired of writing HTML and chasing global CSS rules. I had a hunch: what if you could write a page the same way you write an app — same declarative tree, same modifier chains, scoped style per node? I spent a year quietly testing the bet on my own side projects. It... seems okay? I've open-sourced it as DraftOle ( npm / live demo ). page() writes plain static HTML + scoped CSS — zero runtime JavaScript shipped. app() adds reactive state() and event handlers — TypeScript arrow functions get serialized into a minimal runtime at build time. Same DSL, same modifiers, in both cases. No bundler, no JSX, no template language, zero production dependencies. pnpm add draft-ole # or npm install draft-ole # or yarn add draft-ole This is the 0.9.0 pre-1.0 release. The API surface is essentially settled and 1.0 is the next tag, but I'm intentionally holding back the 1.0 promise until I hear from real users. If you try it and it feels great or terrible, please tell me — both signals are useful. (Yes, AI can generate HTML/CSS now. I'm not making a claim about how DraftOle compares — that's a separate experiment I haven't run. This article is just about what I built and why.) ## Honestly? I just don't want to write HTML or global CSS anymore Let me be candid about the motivation. It's not a refined "type safety extends to the leaves" pitch. It's two embarrassingly small frustrations I kept hitting on every side project. 1. I don't want to write HTML I'm building logic in TypeScript — typed values, typed functions, typed data flow — and then at the last mile I have to drop into stringly-typed HTML. Attribute names are strings. Class names are strings. Five levels of nesting and I can't tell which element carries which style anymore. The logical layer is type-safe, and then the presentation layer reverts to "paste these strings together carefully." That mismatch grates every time. 2. I don't understand global CSS CSS-in-JS, CSS Modules, Tailwind — pick your weapon, eventual

2026-05-31 原文 →
产品设计

Computing and Displaying Discounted Prices in CSS

A clever use of CSS to calculate and display a discounted product price by providing a base price and discount amount, featuring modern CSS features like attr() , mod() , and round() . Computing and Displaying Discounted Prices in CSS originally handwritten and published with love on CSS-Tricks . You should really get the newsletter as well.

2026-05-14 原文 →