310 lines
12 KiB
Markdown
310 lines
12 KiB
Markdown
---
|
|
name: gradient-design
|
|
description: Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels.
|
|
date_added: "2026-06-17"
|
|
risk: safe
|
|
source: self
|
|
source_type: self
|
|
---
|
|
|
|
# Gradient Design
|
|
|
|
> "Color in motion. Fluid transitions that add energy and depth to flat surfaces."
|
|
|
|
|
|
## When to Use
|
|
Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly.
|
|
|
|
## Core Principles
|
|
1. **Gradients are the Primary Visual**: Backgrounds, buttons, text, and borders all use gradients instead of solid colors.
|
|
2. **Analogous or Complementary Blends**: Gradients must be carefully chosen so the transition colors don't become muddy (e.g., blending red to green creates a muddy brown in the middle. Blend red to yellow to green instead).
|
|
3. **Subtle Animation**: Background gradients should slowly shift and rotate.
|
|
|
|
## Visual DNA
|
|
- **Colors**: **Warm Tech** (blues to oranges) or create custom vibrant pairs (e.g., Purple to Coral, Deep Blue to Cyan).
|
|
- **Typography**: Clean, heavy sans-serifs that can be easily masked with a gradient fill.
|
|
- **Layout**: Keep the UI structure minimal (glass panels or white/black cards) to let the gradients breathe.
|
|
|
|
## Web Implementation
|
|
- **CSS Example**:
|
|
```css
|
|
body {
|
|
/* Complex mesh-like animated gradient */
|
|
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
|
|
background-size: 400% 400%;
|
|
animation: gradientBG 15s ease infinite;
|
|
color: #fff;
|
|
}
|
|
|
|
@keyframes gradientBG {
|
|
0% { background-position: 0% 50%; }
|
|
50% { background-position: 100% 50%; }
|
|
100% { background-position: 0% 50%; }
|
|
}
|
|
|
|
.gradient-text {
|
|
background: linear-gradient(90deg, #F9D423 0%, #FF4E50 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
font-size: 4rem;
|
|
font-weight: 900;
|
|
}
|
|
|
|
.gradient-border-card {
|
|
background: #ffffff;
|
|
color: #333;
|
|
padding: 32px;
|
|
border-radius: 12px;
|
|
position: relative;
|
|
/* Use a pseudo-element for the gradient border */
|
|
}
|
|
.gradient-border-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: -3px; left: -3px; right: -3px; bottom: -3px;
|
|
background: linear-gradient(90deg, #8A2387, #E94057, #F27121);
|
|
z-index: -1;
|
|
border-radius: 15px;
|
|
}
|
|
```
|
|
|
|
## App Implementation
|
|
|
|
### SwiftUI
|
|
```swift
|
|
struct GradientDesignView: View {
|
|
@State private var animateGradient = false
|
|
|
|
var body: some View {
|
|
ZStack {
|
|
// Animated Background Gradient
|
|
LinearGradient(
|
|
colors: [Color(hex: "ee7752"), Color(hex: "e73c7e"), Color(hex: "23a6d5"), Color(hex: "23d5ab")],
|
|
startPoint: animateGradient ? .topLeading : .bottomLeading,
|
|
endPoint: animateGradient ? .bottomTrailing : .topTrailing
|
|
)
|
|
.ignoresSafeArea()
|
|
.onAppear {
|
|
withAnimation(.linear(duration: 5.0).repeatForever(autoreverses: true)) {
|
|
animateGradient.toggle()
|
|
}
|
|
}
|
|
|
|
VStack(spacing: 40) {
|
|
// Gradient Text
|
|
Text("VIBRANT")
|
|
.font(.system(size: 60, weight: .black))
|
|
.foregroundStyle(
|
|
LinearGradient(
|
|
colors: [Color(hex: "F9D423"), Color(hex: "FF4E50")],
|
|
startPoint: .leading,
|
|
endPoint: .trailing
|
|
)
|
|
)
|
|
|
|
// Gradient Border Card
|
|
Text("Gradient Border")
|
|
.padding()
|
|
.frame(width: 250, height: 150)
|
|
.background(Color.white)
|
|
.cornerRadius(12)
|
|
.overlay(
|
|
RoundedRectangle(cornerRadius: 12)
|
|
.stroke(
|
|
LinearGradient(
|
|
colors: [Color(hex: "8A2387"), Color(hex: "E94057"), Color(hex: "F27121")],
|
|
startPoint: .leading, endPoint: .trailing
|
|
),
|
|
lineWidth: 3
|
|
)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
- `.foregroundStyle(LinearGradient(...))` makes gradient text incredibly easy in modern SwiftUI.
|
|
- Use `.stroke(LinearGradient(...))` inside an `.overlay` to create gradient borders.
|
|
|
|
### Flutter
|
|
```dart
|
|
class GradientDesignScreen extends StatefulWidget {
|
|
@override
|
|
State<GradientDesignScreen> createState() => _GradientDesignScreenState();
|
|
}
|
|
|
|
class _GradientDesignScreenState extends State<GradientDesignScreen> with SingleTickerProviderStateMixin {
|
|
late AnimationController _controller;
|
|
late Animation<Alignment> _topAlignment;
|
|
late Animation<Alignment> _bottomAlignment;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_controller = AnimationController(vsync: this, duration: const Duration(seconds: 5))..repeat(reverse: true);
|
|
_topAlignment = TweenSequence<Alignment>([
|
|
TweenSequenceItem(tween: AlignmentTween(begin: Alignment.topLeft, end: Alignment.topRight), weight: 1),
|
|
]).animate(_controller);
|
|
_bottomAlignment = TweenSequence<Alignment>([
|
|
TweenSequenceItem(tween: AlignmentTween(begin: Alignment.bottomRight, end: Alignment.bottomLeft), weight: 1),
|
|
]).animate(_controller);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: AnimatedBuilder(
|
|
animation: _controller,
|
|
builder: (context, _) {
|
|
return Container(
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
// Animated Background Gradient
|
|
gradient: LinearGradient(
|
|
begin: _topAlignment.value,
|
|
end: _bottomAlignment.value,
|
|
colors: const [Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)],
|
|
),
|
|
),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
// Gradient Text
|
|
ShaderMask(
|
|
blendMode: BlendMode.srcIn,
|
|
shaderCallback: (bounds) => const LinearGradient(
|
|
colors: [Color(0xFFF9D423), Color(0xFFFF4E50)],
|
|
).createShader(Rect.fromLTWH(0, 0, bounds.width, bounds.height)),
|
|
child: const Text('VIBRANT', style: TextStyle(fontSize: 60, fontWeight: FontWeight.w900, color: Colors.white)),
|
|
),
|
|
const SizedBox(height: 40),
|
|
// Gradient Border Card
|
|
Container(
|
|
width: 250, height: 150,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
gradient: const LinearGradient(colors: [Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121)]),
|
|
),
|
|
padding: const EdgeInsets.all(3), // Border width
|
|
child: Container(
|
|
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)),
|
|
alignment: Alignment.center,
|
|
child: const Text('Gradient Border'),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
```
|
|
- Flutter text gradients require `ShaderMask` with `BlendMode.srcIn`.
|
|
- To animate a gradient background, animate the `Alignment` values of the `LinearGradient`.
|
|
|
|
### React Native
|
|
```jsx
|
|
// REQUIRES: expo-linear-gradient OR react-native-linear-gradient
|
|
import { LinearGradient } from 'expo-linear-gradient';
|
|
import MaskedView from '@react-native-masked-view/masked-view';
|
|
|
|
const GradientDesignScreen = () => {
|
|
return (
|
|
<LinearGradient
|
|
colors={['#ee7752', '#e73c7e', '#23a6d5', '#23d5ab']}
|
|
start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }}
|
|
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}
|
|
>
|
|
{/* Gradient Text */}
|
|
<MaskedView
|
|
style={{ height: 80, width: '100%', flexDirection: 'row' }}
|
|
maskElement={
|
|
<View style={{ backgroundColor: 'transparent', flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
<Text style={{ fontSize: 60, fontWeight: '900', color: 'black' }}>VIBRANT</Text>
|
|
</View>
|
|
}
|
|
>
|
|
<LinearGradient
|
|
colors={['#F9D423', '#FF4E50']}
|
|
start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }}
|
|
style={{ flex: 1 }}
|
|
/>
|
|
</MaskedView>
|
|
|
|
<View style={{ marginTop: 40 }}>
|
|
{/* Gradient Border Card */}
|
|
<LinearGradient
|
|
colors={['#8A2387', '#E94057', '#F27121']}
|
|
start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }}
|
|
style={{ padding: 3, borderRadius: 15 }}
|
|
>
|
|
<View style={{ backgroundColor: '#FFF', width: 250, height: 150, borderRadius: 12, justifyContent: 'center', alignItems: 'center' }}>
|
|
<Text>Gradient Border</Text>
|
|
</View>
|
|
</LinearGradient>
|
|
</View>
|
|
</LinearGradient>
|
|
);
|
|
};
|
|
```
|
|
- Gradient text in React Native is notoriously annoying. You must use `@react-native-masked-view/masked-view` to mask a `LinearGradient` with a `<Text>` node.
|
|
- Gradient borders are achieved by nesting a solid view inside a `LinearGradient` with a small padding (e.g., `padding: 3`).
|
|
|
|
### Jetpack Compose
|
|
```kotlin
|
|
@Composable
|
|
fun GradientDesignScreen() {
|
|
// Animated Background
|
|
val infiniteTransition = rememberInfiniteTransition()
|
|
val offset by infiniteTransition.animateFloat(
|
|
initialValue = 0f, targetValue = 1000f,
|
|
animationSpec = infiniteRepeatable(tween(5000, easing = LinearEasing), RepeatMode.Reverse)
|
|
)
|
|
|
|
val bgBrush = Brush.linearGradient(
|
|
colors = listOf(Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)),
|
|
start = Offset(offset, 0f), end = Offset(offset + 500f, 1000f)
|
|
)
|
|
|
|
Box(
|
|
modifier = Modifier.fillMaxSize().background(bgBrush),
|
|
contentAlignment = Alignment.Center
|
|
) {
|
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
|
// Gradient Text
|
|
val textBrush = Brush.horizontalGradient(listOf(Color(0xFFF9D423), Color(0xFFFF4E50)))
|
|
Text(
|
|
text = "VIBRANT",
|
|
style = TextStyle(brush = textBrush, fontSize = 60.sp, fontWeight = FontWeight.Black)
|
|
)
|
|
|
|
Spacer(Modifier.height(40.dp))
|
|
|
|
// Gradient Border Card
|
|
val borderBrush = Brush.horizontalGradient(listOf(Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121)))
|
|
Box(
|
|
modifier = Modifier
|
|
.size(250.dp, 150.dp)
|
|
.border(3.dp, borderBrush, RoundedCornerShape(12.dp))
|
|
.background(Color.White, RoundedCornerShape(12.dp)),
|
|
contentAlignment = Alignment.Center
|
|
) {
|
|
Text("Gradient Border")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
- Compose handles gradients beautifully via `Brush`.
|
|
- You can pass a `Brush` directly into a `TextStyle` for gradient text, or into a `Modifier.border()` for gradient borders.
|
|
|
|
## Do's and Don'ts
|
|
- **DO**: Use multi-stop gradients (3 or 4 colors) rather than just simple A-to-B gradients for a more modern, rich look.
|
|
- **DON'T**: Apply gradients to tiny text or thin icons, they will lose legibility immediately.
|
|
|
|
## Limitations
|
|
- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review.
|
|
- Ensure appropriate contrast ratios and responsive behaviors are verified separately.
|