Files
dns-server/static/css/style.css
2025-11-24 22:51:50 +08:00

1063 lines
19 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 全局样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
color: #333;
line-height: 1.6;
width: 100%;
height: 100%;
overflow-x: hidden;
}
body {
position: relative;
}
/* 基础响应式变量 */
:root {
--sidebar-width: 250px;
--sidebar-mobile-width: 70px;
--header-height: 130px;
--content-padding: 1rem;
--card-min-width: 300px;
}
/* 主容器样式 */
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
max-width: 100%;
background-color: #fff;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
}
/* 头部样式 */
header.header-container {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1.5rem;
width: 100%;
text-align: center;
box-sizing: border-box;
position: relative;
z-index: 10;
}
.logo {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1rem;
}
.logo i {
margin-right: 1rem;
color: white;
}
.logo h1 {
font-size: 1.8rem;
margin: 0;
font-weight: 600;
}
header p {
font-size: 1rem;
opacity: 0.9;
}
/* 主体布局容器 */
.main-layout {
display: flex;
flex: 1;
min-height: 0;
transition: all 0.3s ease;
}
/* 侧边栏样式 */
.sidebar {
width: var(--sidebar-width);
background-color: #2c3e50;
color: white;
padding: 1rem 0;
flex-shrink: 0;
overflow-y: auto;
height: calc(100vh - var(--header-height)); /* 减去header的高度 */
transition: width 0.3s ease;
position: relative;
}
/* 移动设备侧边栏切换按钮 */
.sidebar-toggle {
position: fixed;
top: calc(var(--header-height) + 10px);
left: 10px;
z-index: 100;
background-color: #2c3e50;
color: white;
border: none;
border-radius: 4px;
padding: 8px 12px;
cursor: pointer;
display: none;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
/* 响应式布局 - 平板设备 */
@media (max-width: 992px) {
.sidebar {
width: var(--sidebar-mobile-width);
}
.nav-item span {
display: none;
}
.nav-item i {
margin-right: 0;
}
.sidebar-toggle {
display: block;
}
}
/* 响应式布局 - 移动设备 */
@media (max-width: 768px) {
.sidebar {
position: fixed;
left: -var(--sidebar-width);
top: var(--header-height);
z-index: 99;
height: calc(100vh - var(--header-height));
}
.sidebar.open {
left: 0;
width: var(--sidebar-width);
}
.sidebar.open .nav-item span {
display: block;
}
.sidebar.open .nav-item i {
margin-right: 1rem;
}
}
.nav-menu {
list-style: none;
}
.nav-item {
padding: 1rem 1.5rem;
display: flex;
align-items: center;
cursor: pointer;
transition: all 0.3s ease;
}
.nav-item:hover {
background-color: #34495e;
padding-left: 1.75rem;
}
.nav-item.active {
background-color: #3498db;
border-left: 4px solid #fff;
}
.nav-item i {
margin-right: 1rem;
width: 20px;
text-align: center;
}
/* 主内容区域样式 */
.content {
flex: 1;
padding: var(--content-padding);
overflow-y: auto;
background-color: #f8f9fa;
min-width: 0; /* 防止flex子元素溢出 */
height: calc(100vh - var(--header-height)); /* 减去header的高度 */
transition: padding-left 0.3s ease;
}
/* 平板设备适配 - 侧边栏折叠时调整内容区域 */
@media (max-width: 992px) {
.content {
padding-left: calc(var(--content-padding) + 10px);
}
}
/* 移动设备适配 - 侧边栏隐藏时的内容区域 */
@media (max-width: 768px) {
.content {
padding-left: var(--content-padding);
}
/* 响应式头部样式 */
header.header-container {
padding: 1rem;
}
.logo h1 {
font-size: 1.5rem;
}
header p {
font-size: 0.9rem;
}
}
/* 面板样式 */
.panel {
display: none;
background-color: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
box-sizing: border-box;
overflow: hidden;
}
.panel.active {
display: block;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid #e9ecef;
}
.panel-header h2 {
font-size: 1.5rem;
color: #2c3e50;
}
/* 状态指示器 */
.status-indicator {
display: flex;
align-items: center;
}
.status-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #e74c3c;
margin-right: 8px;
animation: pulse 2s infinite;
}
.status-dot.connected {
background-color: #2ecc71;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.1);
opacity: 0.7;
}
100% {
transform: scale(1);
opacity: 1;
}
}
/* 按钮样式 */
.btn {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
font-weight: 500;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
}
.btn i {
margin-right: 0.5rem;
}
.btn-primary {
background-color: #3498db;
color: white;
}
.btn-primary:hover {
background-color: #2980b9;
}
.btn-secondary {
background-color: #7f8c8d;
color: white;
}
.btn-secondary:hover {
background-color: #6c757d;
}
.btn-success {
background-color: #2ecc71;
color: white;
}
.btn-success:hover {
background-color: #27ae60;
}
.btn-danger {
background-color: #e74c3c;
color: white;
}
.btn-danger:hover {
background-color: #c0392b;
}
.btn-warning {
background-color: #f39c12;
color: white;
}
.btn-warning:hover {
background-color: #e67e22;
}
.btn-sm {
padding: 0.375rem 0.75rem;
font-size: 0.8rem;
}
.btn-block {
width: 100%;
}
/* 统计卡片网格 */
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr));
gap: clamp(1rem, 3vw, 1.5rem); /* 根据屏幕宽度动态调整间距 */
margin-bottom: 2rem;
}
/* 图表容器 */
.charts-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
gap: clamp(1rem, 3vw, 1.5rem); /* 根据屏幕宽度动态调整间距 */
margin-bottom: 1.5rem;
}
.stat-card {
background-color: white;
border-radius: 8px;
padding: clamp(1rem, 3vw, 1.5rem); /* 根据屏幕宽度动态调整内边距 */
text-align: center;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
transition: transform 0.3s ease, box-shadow 0.3s ease;
min-width: 0; /* 防止内容溢出 */
display: flex;
flex-direction: column;
justify-content: center;
}
.stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
/* 卡片布局的响应式优化 */
@media (max-width: 640px) {
/* 在极小屏幕上,调整卡片网格为单列显示 */
.stats-grid,
.charts-container,
.tables-container {
grid-template-columns: 1fr;
}
/* 卡片更紧凑的内边距 */
.stat-card,
.chart-card,
.table-card {
padding: 1rem;
min-height: 120px;
}
/* 优化统计卡片的图标大小 */
.stat-card i {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
/* 优化统计卡片的数值和标签 */
.stat-value {
font-size: clamp(1.2rem, 5vw, 1.5rem);
}
.stat-label {
font-size: clamp(0.7rem, 3vw, 0.8rem);
}
/* 优化图表卡片标题 */
.chart-card h3 {
font-size: clamp(1rem, 4vw, 1.1rem);
}
/* 优化面板标题 */
.panel-header h2 {
font-size: clamp(1.2rem, 5vw, 1.3rem);
}
}
.stat-card i {
font-size: 2rem;
margin-bottom: 1rem;
color: #3498db;
}
.stat-value {
font-size: 2rem;
font-weight: bold;
margin-bottom: 0.5rem;
color: #2c3e50;
}
.stat-label {
font-size: 0.9rem;
color: #7f8c8d;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* 图表容器 */
.charts-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin-bottom: 1.5rem;
}
.chart-card {
background-color: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}
.chart-card h3 {
margin-bottom: 1rem;
font-size: 1.2rem;
color: #2c3e50;
}
/* 表格容器 */
.tables-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
gap: 1.5rem;
}
/* 表格卡片样式 */
.table-card {
background-color: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
min-width: 0; /* 防止子元素溢出 */
}
/* 表格响应式样式 */
@media (max-width: 768px) {
/* 调整卡片内边距 */
.table-card,
.stat-card,
.chart-card {
padding: 1rem;
}
/* 调整表格单元格内边距 */
th, td {
padding: 0.5rem;
font-size: 0.9rem;
}
/* 调整表格卡片标题 */
.table-card h3,
.chart-card h3 {
font-size: 1.1rem;
}
/* 调整统计卡片数值和标签 */
.stat-value {
font-size: 1.5rem;
}
.stat-label {
font-size: 0.8rem;
}
/* 调整面板标题 */
.panel-header h2 {
font-size: 1.3rem;
}
/* 调整按钮大小 */
.btn {
padding: 0.4rem 0.8rem;
font-size: 0.85rem;
}
}
.table-card {
background-color: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}
.table-card h3 {
margin-bottom: 1rem;
font-size: 1.2rem;
color: #2c3e50;
}
/* 表格样式 */
.table-wrapper {
overflow-x: auto;
border-radius: 8px;
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 16px;
display: block;
width: 100%;
-webkit-overflow-scrolling: touch; /* iOS平滑滚动 */
}
/* 最常屏蔽和最常解析域名表格的特殊样式 */
#top-blocked-table, #top-resolved-table {
font-size: 0.85rem;
}
/* 限制域名表格高度只显示5条内容 */
.table-card .table-wrapper {
max-height: 220px;
overflow-y: auto;
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
background-color: #ffffff;
margin: 0;
table-layout: fixed; /* 固定布局,有助于响应式设计 */
}
th, td {
padding: 0.75rem 1rem;
text-align: left;
border-bottom: 1px solid #e9ecef;
word-break: break-word; /* 长文本自动换行 */
}
/* 缩小最常屏蔽和最常解析域名表格的单元格内边距 */
#top-blocked-table th, #top-blocked-table td,
#top-resolved-table th, #top-resolved-table td {
padding: 0.5rem 0.75rem;
font-size: 0.85rem;
}
/* 移动设备上表格的优化 */
@media (max-width: 768px) {
/* 确保表格可以水平滚动 */
.table-wrapper {
max-width: 100%;
margin-left: -1rem;
margin-right: -1rem;
border-radius: 0;
}
/* 表格单元格内容截断处理 */
td {
font-size: 0.85rem;
max-width: 150px; /* 限制单元格最大宽度 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 当用户触摸单元格时显示完整内容 */
td:active {
white-space: normal;
word-break: break-word;
}
/* 优化百分比条在小屏幕上的显示 */
.count-cell {
position: relative;
padding-right: 50px; /* 为百分比文本留出空间 */
}
.percentage-text {
font-size: 10px;
right: 5px;
}
}
th {
background-color: #f8f9fa;
font-weight: 600;
color: #2c3e50;
}
td.loading {
text-align: center;
color: #7f8c8d;
font-style: italic;
}
tr:hover {
background-color: #f8f9fa;
}
/* 百分比条样式 */
.count-cell {
position: relative;
}
.count-number {
position: relative;
z-index: 2;
display: inline-block;
}
.percentage-text {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
z-index: 2;
font-size: 12px;
color: #bdc3c7;
}
.percentage-bar-container {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
z-index: 1;
overflow: hidden;
border-radius: 4px;
opacity: 0.2;
}
.percentage-bar {
height: 100%;
transition: width 0.5s ease;
border-radius: 4px;
}
/* 分页控件样式 */
.pagination-controls {
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 16px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 16px;
}
.pagination-info {
font-size: 14px;
color: #666;
}
.pagination-buttons {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.items-per-page {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
}
.items-per-page select {
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #fff;
font-size: 14px;
cursor: pointer;
}
.nav-buttons {
display: flex;
gap: 8px;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* 规则内容样式优化 */
.rule-content {
max-width: 600px;
}
.rule-content pre {
margin: 0;
font-family: inherit;
white-space: pre-wrap;
word-break: break-all;
font-size: 14px;
}
/* 表单样式 */
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
color: #2c3e50;
}
.form-group input,
.form-group select {
width: 100%;
padding: 0.75rem;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 1rem;
transition: border-color 0.3s ease;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #3498db;
}
.form-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
/* 管理区域样式 */
.rules-management,
.hosts-management,
.blacklists-management {
margin-top: 1rem;
}
.rules-input,
.rules-filter,
.hosts-filter {
display: grid;
grid-template-columns: 1fr auto;
gap: 1rem;
margin-bottom: 1.5rem;
}
.rules-input {
grid-template-columns: 1fr auto auto;
}
/* 查询表单 */
.query-form .form-group {
display: grid;
grid-template-columns: 1fr auto;
gap: 1rem;
}
/* 查询结果样式 */
.query-result {
margin-top: 2rem;
}
#query-result-container {
background-color: #f8f9fa;
border-radius: 8px;
padding: 1.5rem;
}
#query-result-container.hidden {
display: none;
}
.result-header {
margin-bottom: 1rem;
border-bottom: 1px solid #e9ecef;
padding-bottom: 0.5rem;
}
.result-header h3 {
font-size: 1.2rem;
color: #2c3e50;
}
.result-item {
padding: 0.5rem 0;
border-bottom: 1px solid #e9ecef;
}
.result-item:last-child {
border-bottom: none;
}
/* 配置表单样式 */
.config-form {
margin-top: 1rem;
}
.config-section {
background-color: #f8f9fa;
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 2rem;
}
.config-section h3 {
margin-bottom: 1.5rem;
font-size: 1.2rem;
color: #2c3e50;
}
.config-actions {
text-align: center;
margin-top: 2rem;
}
/* 通知组件 */
.notification {
position: fixed;
bottom: 20px;
right: 20px;
background-color: #3498db;
color: white;
padding: 1rem 1.5rem;
border-radius: 4px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
z-index: 1000;
transform: translateX(100%);
transition: transform 0.3s ease;
}
.notification.show {
transform: translateX(0);
}
.notification.success {
background-color: #2ecc71;
}
.notification.error {
background-color: #e74c3c;
}
.notification.warning {
background-color: #f39c12;
}
.notification-content {
display: flex;
align-items: center;
}
.notification-content i {
margin-right: 1rem;
}
/* 大屏幕优化 */
@media (min-width: 1200px) {
.container {
max-width: 1400px;
margin: 0 auto;
}
}
/* 平板设备 */
@media (max-width: 1024px) {
.content {
padding: 1rem;
}
.stats-grid,
.charts-container {
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.tables-container {
grid-template-columns: 1fr;
}
}
/* 移动设备 */
@media (max-width: 768px) {
.container {
flex-direction: column;
}
.sidebar {
width: 100%;
height: auto;
max-height: 120px;
}
.nav-menu {
display: flex;
overflow-x: auto;
padding-bottom: 0.5rem;
}
.nav-item {
white-space: nowrap;
padding: 0.75rem 1rem;
}
.stats-grid,
.charts-container,
.tables-container {
grid-template-columns: 1fr;
}
.rules-input,
.rules-filter,
.hosts-filter {
grid-template-columns: 1fr;
}
.form-row {
grid-template-columns: 1fr;
}
.query-form .form-group {
grid-template-columns: 1fr;
}
.panel {
padding: 1rem;
}
.pagination-controls {
flex-direction: column;
align-items: stretch;
gap: 12px;
}
.pagination-buttons {
flex-direction: column;
align-items: stretch;
gap: 12px;
}
.nav-buttons {
justify-content: center;
}
}
/* 小屏幕移动设备 */
@media (max-width: 480px) {
header {
padding: 1.5rem 1rem;
}
.logo h1 {
font-size: 1.5rem;
}
.content {
padding: 0.75rem;
}
.panel-header {
flex-direction: column;
align-items: flex-start;
gap: 1rem;
}
.stat-card {
padding: 1rem;
}
.stat-value {
font-size: 1.5rem;
}
.chart-card {
padding: 1rem;
}
th, td {
padding: 0.5rem;
font-size: 0.9rem;
}
}
/* 加载动画 */
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-top: 3px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 确保按钮在不同容器中保持一致宽度 */
.w-full {
width: 100%;
}
/* 确保输入和按钮在表单组中有合适的高度对齐 */
.form-group button {
height: auto;
align-self: flex-end;
}
/* 优化表格中的操作按钮间距 */
.actions-cell {
display: flex;
gap: 0.5rem;
}