数学函数和逻辑属性

55 阅读7分钟

第13章:数学函数和逻辑属性

13.1 CSS数学函数

13.1.1 calc() 函数

calc() 函数是CSS中最常用的数学函数,允许在CSS属性值中进行数学计算。

/* 基础用法 */
.container {
    width: calc(100% - 200px);
    height: calc(100vh - 80px);
}

/* 复杂计算 */
.card {
    width: calc((100% - 60px) / 3);
    margin: calc(20px + 2%);
}

/* 响应式字体大小 */
.fluid-text {
    font-size: calc(16px + 1vw);
}

/* 动态间距 */
.spacing {
    gap: calc(var(--base-spacing) * 2);
}

13.1.2 min() 和 max() 函数

min()max() 函数用于设置值的范围限制。

/* 最小宽度限制 */
.sidebar {
    width: min(300px, 25%);
}

/* 最大宽度限制 */
.content {
    width: max(50%, 400px);
}

/* 响应式容器 */
.container {
    width: min(1200px, 90vw);
    height: max(400px, 50vh);
}

/* 字体大小范围 */
.heading {
    font-size: clamp(1.5rem, 4vw, 3rem);
}

13.1.3 clamp() 函数

clamp() 函数是 min()max() 的组合,设置最小、首选和最大值。

/* 响应式字体大小 */
.responsive-text {
    font-size: clamp(1rem, 2.5vw, 2rem);
}

/* 动态间距 */
.adaptive-spacing {
    padding: clamp(1rem, 5%, 3rem);
}

/* 图片尺寸控制 */
.responsive-image {
    width: clamp(200px, 50%, 600px);
    height: clamp(150px, 30vh, 400px);
}

13.2 高级数学函数

13.2.1 三角函数

CSS支持基本的三角函数运算。

/* 旋转角度计算 */
.rotated-element {
    transform: rotate(calc(45deg + var(--angle-adjustment)));
}

/* 正弦函数应用 */
.wave-effect {
    transform: translateY(calc(sin(var(--time)) * 10px));
}

/* 复杂动画路径 */
.animated-element {
    transform: 
        translateX(calc(100px * cos(var(--angle))))
        translateY(calc(100px * sin(var(--angle))));
}

13.2.2 数学函数组合使用

多个数学函数可以组合使用,实现复杂布局。

/* 网格布局计算 */
.grid-container {
    --columns: 4;
    --gap: 20px;
    
    grid-template-columns: repeat(
        auto-fit,
        minmax(
            calc((100% - var(--gap) * (var(--columns) - 1)) / var(--columns)),
            1fr
        )
    );
    gap: var(--gap);
}

/* 响应式卡片布局 */
.card-grid {
    display: grid;
    grid-template-columns: repeat(
        auto-fill,
        minmax(
            clamp(250px, calc(33.333% - 20px), 400px),
            1fr
        )
    );
    gap: clamp(10px, 3%, 30px);
}

13.3 逻辑属性

13.3.1 逻辑属性基础

逻辑属性根据书写模式(writing-mode)和文本方向(direction)自动调整。

/* 传统物理属性 */
.physical {
    margin-left: 20px;
    padding-right: 10px;
    border-top: 1px solid #ccc;
}

/* 对应的逻辑属性 */
.logical {
    margin-inline-start: 20px;
    padding-inline-end: 10px;
    border-block-start: 1px solid #ccc;
}

13.3.2 块级和行内逻辑属性

块级逻辑属性
/* 块级尺寸 */
.block-sizing {
    block-size: 200px;        /* 相当于 height */
    min-block-size: 100px;    /* 相当于 min-height */
    max-block-size: 300px;    /* 相当于 max-height */
}

/* 块级边距和填充 */
.block-spacing {
    margin-block: 20px;       /* 相当于 margin-top 和 margin-bottom */
    padding-block: 10px 30px; /* 相当于 padding-top 和 padding-bottom */
    
    border-block: 2px solid #333; /* 相当于 border-top 和 border-bottom */
}
行内逻辑属性
/* 行内尺寸 */
.inline-sizing {
    inline-size: 300px;       /* 相当于 width */
    min-inline-size: 200px;   /* 相当于 min-width */
    max-inline-size: 500px;   /* 相当于 max-width */
}

/* 行内边距和填充 */
.inline-spacing {
    margin-inline: 15px;      /* 相当于 margin-left 和 margin-right */
    padding-inline: 20px 40px; /* 相当于 padding-left 和 padding-right */
    
    border-inline: 1px solid #666; /* 相当于 border-left 和 border-right */
}

13.4 逻辑属性实战应用

13.4.1 多语言支持

逻辑属性特别适合多语言网站的布局。

/* 支持从左到右和从右到左语言 */
.multilingual-layout {
    /* 物理属性(不推荐) */
    &.physical {
        text-align: left;
        margin-left: auto;
        padding-right: 20px;
    }
    
    /* 逻辑属性(推荐) */
    &.logical {
        text-align: start;
        margin-inline-start: auto;
        padding-inline-end: 20px;
    }
}

/* 垂直书写模式支持 */
.vertical-writing {
    writing-mode: vertical-rl;
    
    .logical-element {
        margin-block-start: 20px;    /* 在垂直模式下相当于 margin-top */
        padding-inline-end: 10px;    /* 在垂直模式下相当于 padding-right */
    }
}

13.4.2 响应式逻辑布局

结合媒体查询和逻辑属性创建自适应布局。

.responsive-logical-layout {
    /* 基础逻辑属性 */
    padding-inline: clamp(1rem, 5%, 3rem);
    margin-block: var(--spacing-md);
    
    /* 水平布局 */
    @media (min-width: 768px) {
        display: flex;
        gap: var(--spacing-lg);
        
        .sidebar {
            flex: 0 0 clamp(200px, 25%, 300px);
        }
        
        .main-content {
            flex: 1;
            min-inline-size: 0; /* 防止flex项目溢出 */
        }
    }
    
    /* 垂直布局 */
    @media (max-width: 767px) {
        .sidebar {
            margin-block-end: var(--spacing-md);
        }
    }
}

13.5 现代CSS布局模式

13.5.1 内在网页设计

内在网页设计强调内容驱动布局,而非固定尺寸。

.intrinsic-layout {
    /* 内容优先的容器 */
    .container {
        width: min(100% - 2rem, 70ch);
        margin-inline: auto;
    }
    
    /* 内在网格布局 */
    .intrinsic-grid {
        --min: 250px;
        --max: 1fr;
        
        display: grid;
        grid-template-columns: 
            repeat(auto-fit, minmax(min(var(--min), 100%), var(--max)));
        gap: clamp(1rem, 2vw, 2rem);
    }
    
    /* 流体排版 */
    .fluid-typography {
        font-size: clamp(1rem, 2.5vw, 1.5rem);
        line-height: clamp(1.4, 1.6, 1.8);
        max-inline-size: 65ch;
    }
}

13.5.2 容器查询与逻辑属性

结合容器查询和逻辑属性创建组件级响应式设计。

.card-component {
    container-type: inline-size;
    
    /* 基础样式 */
    padding: var(--spacing-md);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    
    /* 容器查询 - 窄容器 */
    @container (max-width: 400px) {
        .card-content {
            flex-direction: column;
            gap: var(--spacing-sm);
            
            .card-image {
                inline-size: 100%;
                block-size: 200px;
            }
            
            .card-text {
                padding-inline: 0;
            }
        }
    }
    
    /* 容器查询 - 宽容器 */
    @container (min-width: 401px) {
        .card-content {
            display: flex;
            gap: var(--spacing-lg);
            align-items: flex-start;
            
            .card-image {
                flex: 0 0 clamp(150px, 30%, 250px);
                block-size: auto;
            }
            
            .card-text {
                flex: 1;
                min-inline-size: 0;
            }
        }
    }
}

13.6 实战案例:现代卡片组件

13.6.1 完整的卡片组件实现

.modern-card {
    /* 逻辑属性定义 */
    --card-padding: clamp(1rem, 3vw, 2rem);
    --card-gap: clamp(0.5rem, 2vw, 1.5rem);
    --card-radius: clamp(8px, 2vw, 16px);
    
    /* 容器样式 */
    container-type: inline-size;
    background: var(--surface-color);
    border-radius: var(--card-radius);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    
    /* 内容布局 */
    .card-content {
        padding: var(--card-padding);
        display: flex;
        flex-direction: column;
        gap: var(--card-gap);
    }
    
    /* 图片容器 */
    .card-image {
        position: relative;
        aspect-ratio: 16 / 9;
        overflow: hidden;
        
        img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.3s ease;
        }
        
        &:hover img {
            transform: scale(1.05);
        }
    }
    
    /* 文本内容 */
    .card-text {
        .card-title {
            font-size: clamp(1.25rem, 3vw, 1.5rem);
            line-height: 1.3;
            margin-block-end: 0.5em;
        }
        
        .card-description {
            font-size: clamp(0.875rem, 2vw, 1rem);
            line-height: 1.5;
            color: var(--text-secondary);
        }
    }
    
    /* 操作区域 */
    .card-actions {
        display: flex;
        gap: 0.5rem;
        flex-wrap: wrap;
        justify-content: flex-end;
        margin-block-start: auto;
        
        .btn {
            padding-inline: clamp(0.75rem, 2vw, 1.25rem);
            padding-block: clamp(0.5rem, 1.5vw, 0.75rem);
            font-size: clamp(0.875rem, 2vw, 1rem);
        }
    }
    
    /* 容器查询适配 */
    @container (max-width: 300px) {
        .card-content {
            padding: calc(var(--card-padding) * 0.75);
        }
        
        .card-actions {
            justify-content: stretch;
            
            .btn {
                flex: 1;
                min-inline-size: 0;
            }
        }
    }
    
    @container (min-width: 500px) {
        .card-content {
            flex-direction: row;
            align-items: flex-start;
            
            .card-image {
                flex: 0 0 40%;
            }
            
            .card-text {
                flex: 1;
            }
        }
    }
}

13.6.2 数学函数在动画中的应用

.animated-element {
    /* 使用calc()创建动态动画 */
    --animation-duration: 2s;
    --animation-delay: calc(var(--index) * 0.1s);
    
    animation: 
        slideIn calc(var(--animation-duration) * 1.5) 
        calc(var(--animation-delay) + 0.5s) ease-out backwards;
    
    /* 关键帧中使用数学函数 */
    @keyframes slideIn {
        0% {
            transform: 
                translateX(calc(-100% - 20px))
                scale(0.8);
            opacity: 0;
        }
        50% {
            transform: 
                translateX(calc(-50% - 10px))
                scale(1.1);
        }
        100% {
            transform: 
                translateX(0)
                scale(1);
            opacity: 1;
        }
    }
    
    /* 悬停效果使用数学计算 */
    &:hover {
        transform: 
            translateY(calc(-1 * var(--hover-lift)))
            scale(calc(1 + var(--hover-scale)));
        box-shadow: 
            0 calc(var(--hover-lift) * 2) 
            calc(var(--hover-lift) * 4) 
            rgba(0, 0, 0, 0.15);
    }
}

13.7 最佳实践和注意事项

13.7.1 性能优化

/* 好的实践:使用CSS变量缓存计算结果 */
:root {
    --container-width: min(1200px, 90vw);
    --sidebar-width: clamp(200px, 25%, 300px);
    --content-width: calc(var(--container-width) - var(--sidebar-width));
}

.layout {
    width: var(--container-width);
    
    .sidebar {
        width: var(--sidebar-width);
    }
    
    .content {
        width: var(--content-width);
    }
}

/* 避免过度复杂的计算 */
.bad-practice {
    /* 过于复杂的计算可能影响性能 */
    width: calc(((100% - (20px * 3)) / 4) + (10px * var(--multiplier)) - 5%);
}

.good-practice {
    /* 分解复杂计算 */
    --base-width: calc((100% - 60px) / 4);
    --adjustment: calc(10px * var(--multiplier));
    width: calc(var(--base-width) + var(--adjustment) - 5%);
}

13.7.2 浏览器兼容性处理

/* 渐进增强策略 */
.responsive-element {
    /* 基础回退样式 */
    width: 90%;
    max-width: 400px;
    
    /* 现代浏览器支持 */
    @supports (width: min(200px, 50%)) {
        width: min(400px, 50%);
    }
    
    @supports (width: clamp(200px, 50%, 600px)) {
        width: clamp(200px, 50%, 600px);
    }
}

/* 逻辑属性的回退方案 */
.multidirectional-layout {
    /* 物理属性作为回退 */
    margin-left: 20px;
    margin-right: 20px;
    text-align: left;
    
    /* 逻辑属性覆盖 */
    margin-inline: 20px;
    text-align: start;
    
    /* 针对不支持逻辑属性的浏览器 */
    @supports not (margin-inline: 20px) {
        /* 使用物理属性适配不同文本方向 */
        html[dir="rtl"] & {
            margin-left: 0;
            margin-right: 20px;
            text-align: right;
        }
    }
}

13.8 总结

数学函数和逻辑属性是现代CSS3的核心特性,它们为开发者提供了:

  1. 更精确的布局控制 - 通过数学计算实现精确的尺寸和间距
  2. 更好的响应式设计 - 使用 clamp() 等函数创建真正的响应式布局
  3. 多语言支持 - 逻辑属性自动适配不同的书写方向和文本流向
  4. 性能优化 - 减少媒体查询的使用,提高代码可维护性
  5. 未来兼容性 - 为新的布局模式和容器查询做好准备

掌握这些特性将显著提升你的CSS技能,让你能够创建更加灵活、健壮和可维护的现代网页布局。