Apply Color Blocking Principles to UI Designs
Color Blocking is a design sub-style that creates Mondrian-inspired layouts with large geometric blocks of contrasting solid colors separated by black grid
Why it matters
Help designers and developers implement color blocking techniques in user interfaces by providing structured guidance on selecting, organizing, and applying bold color sections that create visual hierarchy, improve readability, and enhance modern UI aesthetics.
Outcomes
What it gets done
Define color blocking zones and boundaries within a layout
Select complementary or contrasting color palettes for blocks
Balance visual weight across colored sections for hierarchy
Generate CSS or design tokens for color block implementations
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/ag-color-blocking | bash Overview
Color Blocking
Color Blocking creates Mondrian-inspired layouts by dividing the viewport into large rectangles or squares, each filled with a solid, distinct color. Blocks touch each other directly with no margins, separated by black lines or letting colors clash. Typography is placed precisely within blocks using clean, bold sans-serifs. Use this sub-style when the user's request matches the aesthetic of large, solid swaths of contrasting color defining the layout. This is a child reference of the `design-it` skill and is not meant to be triggered directly.
What it does
Color Blocking creates bold, geometric layouts inspired by Mondrian paintings, dividing the viewport into large rectangles or squares filled with solid, distinct colors. The implementation uses black grid lines between blocks, creating a stark visual grid where colors can clash directly. Typography is placed precisely within blocks to balance the visual weight of the colors, using clean, bold sans-serifs. Blocks touch each other directly, often separated only by a stark 1px or 2px black line (or no line at all, letting the colors clash), with no margins between blocks.
Inputs and outputs
The skill outputs implementation code across web and mobile platforms. For web, CSS Grid is described as the only way to effectively build this style. Mobile implementations include SwiftUI views, Flutter widgets, React Native components, and Jetpack Compose functions. The implementations use geometric divisions created through grid or flex systems, with black backgrounds that peek through gaps to form grid lines. Colors are highly contrasting, bold pairings, with examples showing 3 to 4 strong colors.
Integrations
The source material provides implementation patterns for:
- Web (CSS Grid): Uses CSS Grid with gap properties and black backgrounds to create the grid effect
- SwiftUI: Implements VStack and HStack with spacing properties, where black backgrounds peek through gaps to form grid lines
- Flutter: Uses Expanded widgets with flex factors and SizedBox spacing to expose black Scaffold backgrounds
- React Native: Leverages flexbox with gap properties and flex ratios for proportional block sizing
- Jetpack Compose: Employs Column and Row with weight modifiers and Arrangement.spacedBy for grid spacing
Here's the CSS implementation pattern:
body {
margin: 0;
font-family: 'Space Grotesk', sans-serif;
color: #000;
}
.color-block-grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: 60vh 40vh;
/* Thick black lines between blocks */
gap: 4px;
background-color: #000;
border: 4px solid #000;
min-height: 100vh;
}
.block {
padding: 40px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.block-yellow { background-color: #FACC15; }
.block-white { background-color: #FFFFFF; }
.block-blue { background-color: #2563EB; color: #FFF; }
.block-red { background-color: #EF4444; }
.block-title {
font-size: 3rem;
font-weight: 900;
text-transform: uppercase;
margin: 0;
}
Who it's for
This sub-style is for users whose design requests match the Color Blocking aesthetic. The source material provides cross-platform implementation examples for developers working across web and mobile platforms.
Source README
Color Blocking
"The grid made visible. Large, solid swaths of contrasting color defining the layout."
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
- Geometric Division: The viewport is divided into large rectangles or squares, each filled with a solid, distinct color.
- No Margins Between Blocks: Blocks touch each other directly, often separated only by a stark, 1px or 2px black line (or no line at all, letting the colors clash).
- Typography as Texture: Text is placed precisely within these blocks to balance the visual weight of the colors.
Visual DNA
- Colors: Highly contrasting, bold pairings. Use 3 to 4 strong colors from palettes like Industrial Chic (Red, Black, Grey, White) or custom bold pairings (Yellow, Navy, Pink).
- Typography: Very clean, bold sans-serifs that can hold their own against massive blocks of color.
- Borders: Often uses thick black borders (
2px solid #000) between blocks to emphasize the grid, reminiscent of Mondrian paintings.
Web Implementation
- CSS Grid is the only way to effectively build this.
- CSS Example:
body {
margin: 0;
font-family: 'Space Grotesk', sans-serif;
color: #000;
}
.color-block-grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: 60vh 40vh;
/* Thick black lines between blocks */
gap: 4px;
background-color: #000;
border: 4px solid #000;
min-height: 100vh;
}
.block {
padding: 40px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.block-yellow { background-color: #FACC15; }
.block-white { background-color: #FFFFFF; }
.block-blue { background-color: #2563EB; color: #FFF; }
.block-red { background-color: #EF4444; }
.block-title {
font-size: 3rem;
font-weight: 900;
text-transform: uppercase;
margin: 0;
}
App Implementation
SwiftUI
struct ColorBlockingView: View {
let gridSpacing: CGFloat = 4 // Thickness of the black lines
var body: some View {
// Black background acts as the grid lines between blocks
VStack(spacing: gridSpacing) {
// Top Row
HStack(spacing: gridSpacing) {
ColorBlock(color: .yellow, text: "CREATE", textColor: .black)
ColorBlock(color: .blue, text: "VISION", textColor: .white)
}
.frame(height: 300)
// Bottom Row
HStack(spacing: gridSpacing) {
ColorBlock(color: .red, text: "BOLD", textColor: .white)
.frame(width: 120) // Fixed narrow block
ColorBlock(color: .white, text: "MINIMAL", textColor: .black)
}
}
.background(Color.black) // The grid lines
.border(Color.black, width: gridSpacing) // Outer border
.ignoresSafeArea()
}
}
struct ColorBlock: View {
let color: Color
let text: String
let textColor: Color
var body: some View {
color
.overlay(
Text(text)
.font(.system(size: 32, weight: .black))
.foregroundColor(textColor)
.padding(),
alignment: .bottomLeading
)
}
}
- In SwiftUI, the easiest way to create Mondrian-style thick black grid lines is to set
.background(Color.black)on the parent stack and usespacing: 4. The background peeks through the gaps. .ignoresSafeArea()allows the blocks to bleed to the edge of the physical device.
Flutter
class ColorBlockingScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
// Black background creates the grid lines
backgroundColor: Colors.black,
body: SafeArea(
bottom: false,
child: Column(
children: [
// Top Row
Expanded(
flex: 3, // 3/5 of vertical space
child: Row(
children: [
Expanded(flex: 1, child: ColorBlock(color: const Color(0xFFFACC15), text: 'CREATE', textColor: Colors.black)),
const SizedBox(width: 4), // Grid line
Expanded(flex: 2, child: ColorBlock(color: const Color(0xFF2563EB), text: 'VISION', textColor: Colors.white)),
],
),
),
const SizedBox(height: 4), // Horizontal grid line
// Bottom Row
Expanded(
flex: 2, // 2/5 of vertical space
child: Row(
children: [
Expanded(flex: 1, child: ColorBlock(color: const Color(0xFFEF4444), text: 'BOLD', textColor: Colors.white)),
const SizedBox(width: 4),
Expanded(flex: 2, child: ColorBlock(color: Colors.white, text: 'MINIMAL', textColor: Colors.black)),
],
),
),
],
),
),
);
}
}
class ColorBlock extends StatelessWidget {
final Color color;
final String text;
final Color textColor;
const ColorBlock({required this.color, required this.text, required this.textColor});
@override
Widget build(BuildContext context) {
return Container(
color: color,
padding: const EdgeInsets.all(24),
alignment: Alignment.bottomLeft,
child: Text(text, style: TextStyle(fontSize: 32, fontWeight: FontWeight.w900, color: textColor)),
);
}
}
- Use
Expandedwith varyingflexfactors to divide the screen geometrically. - Insert
SizedBox(width: 4)orheight: 4between rows and columns to expose the blackScaffoldbackground, creating the grid lines.
React Native
const ColorBlockingScreen = () => {
return (
<View style={{ flex: 1, backgroundColor: '#000', gap: 4 }}>
{/* Top Row */}
<View style={{ flex: 3, flexDirection: 'row', gap: 4 }}>
<View style={[styles.block, { flex: 1, backgroundColor: '#FACC15' }]}>
<Text style={[styles.text, { color: '#000' }]}>CREATE</Text>
</View>
<View style={[styles.block, { flex: 2, backgroundColor: '#2563EB' }]}>
<Text style={[styles.text, { color: '#FFF' }]}>VISION</Text>
</View>
</View>
{/* Bottom Row */}
<View style={{ flex: 2, flexDirection: 'row', gap: 4 }}>
<View style={[styles.block, { flex: 1, backgroundColor: '#EF4444' }]}>
<Text style={[styles.text, { color: '#FFF' }]}>BOLD</Text>
</View>
<View style={[styles.block, { flex: 2, backgroundColor: '#FFF' }]}>
<Text style={[styles.text, { color: '#000' }]}>MINIMAL</Text>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
block: {
justifyContent: 'flex-end',
padding: 24,
},
text: {
fontSize: 32,
fontWeight: '900',
fontFamily: 'SpaceGrotesk-Bold',
}
});
- The
gapproperty in React Native flexbox makes this trivial. Set a black background on the parent, setgap: 4, and the children automatically space out, revealing the thick black lines. - Use
flex: 1,flex: 2etc. to determine block proportions.
Jetpack Compose
@Composable
fun ColorBlockingScreen() {
val gridSpacing = 4.dp
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Black) // Grid lines
) {
// Top Row
Row(
modifier = Modifier.weight(3f),
horizontalArrangement = Arrangement.spacedBy(gridSpacing)
) {
ColorBlock(Color(0xFFFACC15), "CREATE", Color.Black, Modifier.weight(1f))
ColorBlock(Color(0xFF2563EB), "VISION", Color.White, Modifier.weight(2f))
}
Spacer(Modifier.height(gridSpacing))
// Bottom Row
Row(
modifier = Modifier.weight(2f),
horizontalArrangement = Arrangement.spacedBy(gridSpacing)
) {
ColorBlock(Color(0xFFEF4444), "BOLD", Color.White, Modifier.weight(1f))
ColorBlock(Color.White, "MINIMAL", Color.Black, Modifier.weight(2f))
}
}
}
@Composable
fun ColorBlock(color: Color, text: String, textColor: Color, modifier: Modifier = Modifier) {
Box(
modifier = modifier
.fillMaxHeight()
.background(color)
.padding(24.dp),
contentAlignment = Alignment.BottomStart
) {
Text(text, fontSize = 32.sp, fontWeight = FontWeight.Black, color = textColor)
}
}
- Like other mobile frameworks,
Modifier.background(Color.Black)combined withArrangement.spacedBy(4.dp)perfectly creates the Mondrian grid. - Use
Modifier.weight(Xf)to mathematically divide the screen real estate.
Do's and Don'ts
- DO: Ensure extreme contrast. Text on a yellow block should be black. Text on a dark blue block should be white.
- DON'T: Use drop shadows, rounded corners, or gradients. Keep it completely flat and sharp.
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.
FAQ
Common questions
Discussion
Questions & comments ยท 0
Sign In Sign in to leave a comment.