| name | data-dense-design |
| description | Web and App implementation guide for Data-Dense Design. Trigger when user wants professional tools, maximum information density, and expert interfaces (like Bloomberg terminals or IDEs). |
| date_added | 2026-06-17 |
| risk | safe |
| source | self |
| source_type | self |
Data-Dense Design
"Density is a feature. For expert users, reducing clicks is more important than whitespace."
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
- Compact Layouts: Extremely tight margins and padding (often 2px to 4px).
- Monospace & Tabular Data: Numbers must align vertically perfectly.
- High Utility: Every pixel serves a functional purpose. Minimal purely decorative elements.
Visual DNA
- Colors: Industrial Chic (high contrast) or Minimalist Slate. Avoid bright backgrounds. Dark themes are heavily preferred to reduce eye strain over 8-hour sessions.
- Typography: Small base sizes (
11px - 13px). Strict use of monospace fonts (Fira Code, JetBrains Mono) for data.
- Borders: Thin
1px borders (#333 or #e0e0e0) are used extensively to separate tiny cells of data.
Web Implementation
- Tables, CSS Grid, and Flexbox with zero gap.
- CSS Example:
body {
background-color: #1e1e1e;
color: #cccccc;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 12px;
margin: 0;
}
.dense-toolbar {
display: flex;
background-color: #2d2d2d;
border-bottom: 1px solid #3c3c3c;
padding: 2px 4px;
}
.dense-btn {
background: transparent;
color: #ccc;
border: 1px solid transparent;
padding: 2px 8px;
border-radius: 2px;
cursor: pointer;
}
.dense-btn:hover {
background-color: #3c3c3c;
border-color: #555;
}
.data-table {
width: 100%;
border-collapse: collapse;
font-family: 'JetBrains Mono', monospace;
}
.data-table th, .data-table {
: ;
: solid ;
: right;
}
(even) { : ; }
{ : ; : ; }
App Implementation
SwiftUI
struct DataDenseView: View {
var body: some View {
ScrollView([.horizontal, .vertical]) {
Grid(horizontalSpacing: 0, verticalSpacing: 0) {
GridRow {
HeaderCell("SYM")
HeaderCell("BID")
HeaderCell("ASK")
HeaderCell("CHG")
}
DataRow(sym: "AAPL", bid: "173.40", ask: "173.45", chg: "+0.12", isPos: true)
DataRow(sym: "MSFT", bid: "320.10", ask: "320.15", chg: "-0.45", isPos: false)
DataRow(sym: "GOOG", bid: "135.20", ask: "135.30", chg: "+0.02", isPos: true)
}
.border(Color.gray.opacity(0.3), width: 1)
}
.background(Color(white: 0.12))
}
}
struct HeaderCell: View {
text:
( : ) { .text text }
body: {
(text)
.font(.system(size: , weight: .bold, design: .monospaced))
.foregroundColor(.gray)
.padding()
.frame(minWidth: , alignment: .leading)
.border(.gray.opacity(), width: )
.background((white: ))
}
}
: {
sym, bid, ask, chg:
isPos:
body: {
{
(sym, color: .white)
(bid, color: .white, align: .trailing)
(ask, color: .white, align: .trailing)
(chg, color: isPos .green : .red, align: .trailing)
}
}
}
: {
text:
color:
align:
( : , : , : .leading) {
.text text; .color color; .align align
}
body: {
(text)
.font(.system(size: , design: .monospaced))
.foregroundColor(color)
.padding()
.frame(minWidth: , alignment: align)
.border(.gray.opacity(), width: )
}
}
- Use
Grid with 0 spacing.
- Font must be
.system(..., design: .monospaced).
- Use a
.border() with 0.5 width on every single cell to recreate the dense spreadsheet look.
Flutter
class DataDenseScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF1E1E1E),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Theme(
// Override theme specifically to make the table hyper-dense
data: Theme.of(context).copyWith(
dividerColor: Colors.grey[800],
),
child: DataTable(
headingRowHeight: 28, // Extremely dense
dataRowMinHeight: 24,
dataRowMaxHeight: 24, // Extremely dense
columnSpacing: 16,
border: TableBorder.all(color: Colors.grey[800]!, width: 1),
columns: const [
DataColumn(label: Text('SYM', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono'))),
DataColumn(label: Text('BID', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono')), numeric: true),
DataColumn(label: Text('ASK', style: TextStyle(color: Colors.grey, fontSize: 11, fontFamily: 'RobotoMono')), numeric: true),
],
rows: [
_buildRow('AAPL', '173.40', '173.45'),
_buildRow('MSFT', '320.10', '320.15'),
_buildRow('GOOG', '135.20', '135.30'),
],
),
),
),
),
);
}
DataRow _buildRow(String sym, String bid, String ask) {
const style = TextStyle(color: Colors.white, fontSize: 12, fontFamily: 'RobotoMono');
return DataRow(
cells: [
DataCell(Text(sym, style: style)),
DataCell(Text(bid, style: style)),
DataCell(Text(ask, style: style)),
],
);
}
}
- Flutter's
DataTable is perfect, but you must manually crush the headingRowHeight and dataRowHeight down from their Material defaults (which are huge).
- Wrap in dual
SingleChildScrollView to allow panning around large data sets.
React Native
const DataDenseScreen = () => {
return (
<ScrollView style={{ backgroundColor: '#1E1E1E', flex: 1 }}>
<ScrollView horizontal>
<View style={{ borderWidth: 1, borderColor: '#333' }}>
{/* Header */}
<View style={{ flexDirection: 'row', backgroundColor: '#2D2D2D' }}>
<HeaderCell text="SYM" width={60} />
<HeaderCell text="BID" width={80} align="right" />
<HeaderCell text="ASK" width={80} align="right" />
<HeaderCell text="CHG" width={60} align= />
{/* Rows */}
);
};
= () => (
);
= () => (
);
= () => (
);
- React Native doesn't have a native Table component, so you must construct a grid using
flexDirection: 'row' and strict width properties on cells.
- Double scroll views (one vertical, one horizontal inside it) are standard for mobile data tables.
Jetpack Compose
@Composable
fun DataDenseScreen() {
val scrollStateHorizontal = rememberScrollState()
val scrollStateVertical = rememberScrollState()
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFF1E1E1E))
.verticalScroll(scrollStateVertical)
.horizontalScroll(scrollStateHorizontal)
.padding(8.dp)
) {
Column(modifier = Modifier.border(1.dp, Color(0xFF333333))) {
Row(modifier = Modifier.background(Color(0xFF2D2D2D))) {
Cell("SYM", 60.dp, Color.Gray, true)
Cell("BID", 80.dp, Color.Gray, true, TextAlign.End)
Cell("ASK", 80.dp, Color.Gray, true, TextAlign.End)
}
DataRow("AAPL", "173.40", "173.45")
DataRow("MSFT", "320.10", "320.15")
}
}
}
@Composable
fun DataRow(sym: String, bid: String, ask: String) {
Row {
Cell(sym, 60.dp, Color.White, false)
Cell(bid, 80.dp, Color.White, false, TextAlign.End)
Cell(ask, 80.dp, Color.White, false, TextAlign.End)
}
}
@Composable
{
Text(
text = text,
color = color,
fontSize = (isHeader) sp sp,
fontWeight = (isHeader) FontWeight.Bold FontWeight.Normal,
fontFamily = FontFamily.Monospace,
textAlign = align,
modifier = Modifier
.width(width)
.border(.dp, Color())
.padding(dp)
)
}
- Chain
.verticalScroll() and .horizontalScroll() on the root Box.
- Compose allows
.border() directly on Text modifiers, making spreadsheet grids very clean to implement without wrapping everything in Boxes.
Do's and Don'ts
- DO: Use color coding (red/green) for data deltas, but keep the saturation muted to prevent eye fatigue.
- DON'T: Use large padding or giant H1 headers. Expert users already know what screen they are on.
Limitations
- This is a styling reference and does not replace enprojectnment-specific validation, accessibility testing, or expert review.
- Ensure appropriate contrast ratios and responsive behaviors are verified separately.