style: modernize CSS with light-dark(), nesting, logical props, and fix a11y

This commit is contained in:
NetworkCats
2026-03-03 03:04:51 +08:00
parent b45e44c8e3
commit f480131809
2 changed files with 164 additions and 141 deletions
+155 -134
View File
@@ -1,71 +1,49 @@
:root {
--color-red: #FF3B30;
--color-orange: #FF9500;
--color-yellow: #FFCC00;
--color-green: #34C759;
--color-mint: #00C7BE;
--color-teal: #30B0C7;
--color-cyan: #32ADE6;
--color-blue: #007AFF;
--color-indigo: #5856D6;
--color-purple: #AF52DE;
--color-pink: #FF2D55;
--color-brown: #A2845E;
color-scheme: light dark;
--color-red: light-dark(#FF3B30, #FF453A);
--color-orange: light-dark(#FF9500, #FF9F0A);
--color-yellow: light-dark(#FFCC00, #FFD60A);
--color-green: light-dark(#34C759, #30D158);
--color-mint: light-dark(#00C7BE, #63E6E2);
--color-teal: light-dark(#30B0C7, #40C8E0);
--color-cyan: light-dark(#32ADE6, #64D2FF);
--color-blue: light-dark(#007AFF, #0A84FF);
--color-indigo: light-dark(#5856D6, #5E5CE6);
--color-purple: light-dark(#AF52DE, #BF5AF2);
--color-pink: light-dark(#FF2D55, #FF375F);
--color-brown: light-dark(#A2845E, #AC8E68);
--color-gray: #8E8E93;
--color-gray2: #AEAEB2;
--color-gray3: #C7C7CC;
--color-gray4: #D1D1D6;
--color-gray5: #E5E5EA;
--color-gray6: #F2F2F7;
--color-gray2: light-dark(#AEAEB2, #636366);
--color-gray3: light-dark(#C7C7CC, #48484A);
--color-gray4: light-dark(#D1D1D6, #3A3A3C);
--color-gray5: light-dark(#E5E5EA, #2C2C2E);
--color-gray6: light-dark(#F2F2F7, #1C1C1E);
--color-label: #000000;
--color-label-secondary: rgba(60, 60, 67, 0.6);
--color-label-tertiary: rgba(60, 60, 67, 0.3);
--color-label-quaternary: rgba(60, 60, 67, 0.18);
--color-label: light-dark(#000000, #EEEEEE);
--color-label-secondary: light-dark(
rgba(60, 60, 67, 0.6),
rgba(235, 235, 245, 0.6)
);
--color-label-tertiary: light-dark(
rgba(60, 60, 67, 0.3),
rgba(235, 235, 245, 0.3)
);
--color-label-quaternary: light-dark(
rgba(60, 60, 67, 0.18),
rgba(235, 235, 245, 0.18)
);
--color-link: #007AFF;
--color-separator: rgba(60, 60, 67, 0.29);
--color-link: light-dark(#007AFF, #0984FF);
--color-separator: light-dark(
rgba(60, 60, 67, 0.29),
rgba(84, 84, 88, 0.65)
);
--color-bg: #FFFFFF;
--color-bg-secondary: #F2F2F7;
--color-bg-tertiary: #FFFFFF;
}
@media (prefers-color-scheme: dark) {
:root {
--color-red: #FF453A;
--color-orange: #FF9F0A;
--color-yellow: #FFD60A;
--color-green: #30D158;
--color-mint: #63E6E2;
--color-teal: #40C8E0;
--color-cyan: #64D2FF;
--color-blue: #0A84FF;
--color-indigo: #5E5CE6;
--color-purple: #BF5AF2;
--color-pink: #FF375F;
--color-brown: #AC8E68;
--color-gray: #8E8E93;
--color-gray2: #636366;
--color-gray3: #48484A;
--color-gray4: #3A3A3C;
--color-gray5: #2C2C2E;
--color-gray6: #1C1C1E;
--color-label: #EEEEEE;
--color-label-secondary: rgba(235, 235, 245, 0.6);
--color-label-tertiary: rgba(235, 235, 245, 0.3);
--color-label-quaternary: rgba(235, 235, 245, 0.18);
--color-link: #0984FF;
--color-separator: rgba(84, 84, 88, 0.65);
--color-bg: #111111;
--color-bg-secondary: #1C1C1E;
--color-bg-tertiary: #2C2C2E;
}
--color-bg: light-dark(#FFFFFF, #111111);
--color-bg-secondary: light-dark(#F2F2F7, #1C1C1E);
--color-bg-tertiary: light-dark(#FFFFFF, #2C2C2E);
}
*,
@@ -80,113 +58,124 @@ body {
font-family: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
color: var(--color-label);
background: var(--color-bg);
accent-color: var(--color-blue);
-webkit-font-smoothing: antialiased;
}
main {
max-width: 540px;
margin: 80px auto 0;
padding: 0 20px;
max-inline-size: 540px;
margin-block-start: 80px;
margin-inline: auto;
padding-inline: 20px;
}
.sr-only {
position: absolute;
inline-size: 1px;
block-size: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border: 0;
}
.search-form {
display: flex;
.search-input-wrap {
flex: 1;
position: relative;
}
.search-icon {
position: absolute;
inset-inline-start: 12px;
inset-block-start: 50%;
translate: 0 -50%;
color: var(--color-label-tertiary);
font-size: 14px;
pointer-events: none;
}
input {
inline-size: 100%;
block-size: 38px;
padding-inline: 34px 12px;
border: 1px solid var(--color-separator);
border-radius: 6px;
font-size: 14px;
font-family: inherit;
color: var(--color-label);
background: var(--color-bg);
&:focus-visible {
outline: 2px solid var(--color-blue);
outline-offset: -1px;
}
&::placeholder {
color: var(--color-label-tertiary);
}
}
}
.search-input-wrap {
flex: 1;
position: relative;
}
.search-icon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--color-label-tertiary);
font-size: 14px;
pointer-events: none;
}
.search-form input {
width: 100%;
height: 38px;
padding: 0 12px 0 34px;
border: 1px solid var(--color-separator);
border-radius: 6px;
font-size: 14px;
font-family: inherit;
color: var(--color-label);
background: var(--color-bg);
outline: none;
}
.search-form input:focus {
border-color: var(--color-gray);
}
.search-form input::placeholder {
color: var(--color-label-tertiary);
}
.ip-display {
text-align: center;
font-size: clamp(28px, 6vw, 42px);
font-weight: 200;
margin: 28px 0 20px;
margin-block: 28px 20px;
letter-spacing: -0.5px;
overflow-wrap: break-word;
word-break: break-all;
}
.info-table {
width: 100%;
inline-size: 100%;
border-collapse: collapse;
table-layout: fixed;
}
.info-table td {
padding: 10px 0;
border-top: 1px solid var(--color-separator);
font-size: 15px;
vertical-align: top;
overflow-wrap: break-word;
}
td {
padding-block: 10px;
border-block-start: 1px solid var(--color-separator);
font-size: 15px;
vertical-align: top;
overflow-wrap: break-word;
}
.info-table tr:last-child td {
border-bottom: 1px solid var(--color-separator);
}
tr:last-child td {
border-block-end: 1px solid var(--color-separator);
}
.info-table .label {
width: 42%;
padding-left: 24px;
padding-right: 32px;
font-weight: 600;
color: var(--color-label);
}
.label {
inline-size: 42%;
padding-inline: 24px 32px;
font-weight: 600;
color: var(--color-label);
}
.info-table .bool-true {
color: var(--color-green);
}
.bool-true {
color: var(--color-green);
}
.info-table .bool-false {
color: var(--color-label-secondary);
.bool-false {
color: var(--color-label-secondary);
}
}
@media (max-width: 480px) {
main {
margin-top: 40px;
padding: 0 16px;
margin-block-start: 40px;
padding-inline: 16px;
}
.search-form input {
height: 44px;
block-size: 44px;
}
.ip-display {
margin: 20px 0 16px;
margin-block: 20px 16px;
}
.info-table td {
@@ -195,7 +184,39 @@ main {
}
@media (max-width: 360px) {
.search-form {
flex-direction: column;
.info-table .label {
inline-size: 36%;
padding-inline: 12px 16px;
}
}
@media (prefers-contrast: more) {
:root {
--color-separator: light-dark(
rgba(0, 0, 0, 0.5),
rgba(255, 255, 255, 0.5)
);
--color-label-secondary: light-dark(
rgba(0, 0, 0, 0.75),
rgba(255, 255, 255, 0.75)
);
--color-label-tertiary: light-dark(
rgba(0, 0, 0, 0.5),
rgba(255, 255, 255, 0.5)
);
}
.search-form input {
border-width: 2px;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
+9 -7
View File
@@ -12,10 +12,12 @@
</head>
<body>
<main>
<form method="GET" action="/" class="search-form">
<form method="GET" action="/" class="search-form" role="search">
<div class="search-input-wrap">
<i class="icon-magnifier search-icon"></i>
<label for="ip-search" class="sr-only">Search IP address</label>
<i class="icon-magnifier search-icon" aria-hidden="true"></i>
<input
id="ip-search"
type="text"
name="ip"
placeholder="Type to search IP data"
@@ -28,7 +30,7 @@
<h1 class="ip-display">{{ ip }}</h1>
<table class="info-table">
<table class="info-table" aria-label="IP address information">
<tbody>
<tr>
<td class="label">ASN</td>
@@ -48,19 +50,19 @@
</tr>
<tr>
<td class="label">Proxy</td>
<td><i class="{% if is_proxy %}icon-check bool-true{% else %}icon-minus bool-false{% endif %}"></i></td>
<td>{% if is_proxy %}<i class="icon-check bool-true" aria-hidden="true"></i><span class="sr-only">Yes</span>{% else %}<i class="icon-minus bool-false" aria-hidden="true"></i><span class="sr-only">No</span>{% endif %}</td>
</tr>
<tr>
<td class="label">VPN</td>
<td><i class="{% if is_vpn %}icon-check bool-true{% else %}icon-minus bool-false{% endif %}"></i></td>
<td>{% if is_vpn %}<i class="icon-check bool-true" aria-hidden="true"></i><span class="sr-only">Yes</span>{% else %}<i class="icon-minus bool-false" aria-hidden="true"></i><span class="sr-only">No</span>{% endif %}</td>
</tr>
<tr>
<td class="label">Hosting</td>
<td><i class="{% if is_hosting %}icon-check bool-true{% else %}icon-minus bool-false{% endif %}"></i></td>
<td>{% if is_hosting %}<i class="icon-check bool-true" aria-hidden="true"></i><span class="sr-only">Yes</span>{% else %}<i class="icon-minus bool-false" aria-hidden="true"></i><span class="sr-only">No</span>{% endif %}</td>
</tr>
<tr>
<td class="label">Tor</td>
<td><i class="{% if is_tor %}icon-check bool-true{% else %}icon-minus bool-false{% endif %}"></i></td>
<td>{% if is_tor %}<i class="icon-check bool-true" aria-hidden="true"></i><span class="sr-only">Yes</span>{% else %}<i class="icon-minus bool-false" aria-hidden="true"></i><span class="sr-only">No</span>{% endif %}</td>
</tr>
</tbody>
</table>