CSS 媒体查询适配
基础方向检测
/* 竖屏样式 */
@media screen and (orientation: portrait) {
.container {
flex-direction: column;
padding: 20px;
}
}
/* 横屏样式 */
@media screen and (orientation: landscape) {
.container {
flex-direction: row;
padding: 10px;
}
}
结合宽高比适配
/* 移动端竖屏 */
@media screen and (max-aspect-ratio: 3/4) {
/* 窄屏样式 */
}
/* 平板/横屏 */
@media screen and (min-aspect-ratio: 4/3) {
/* 宽屏样式 */
}
JavaScript 方向检测
监听方向变化
// 检测方向变化
function handleOrientationChange() {
if (window.matchMedia("(orientation: portrait)").matches) {
console.log("竖屏模式");
// 执行竖屏逻辑
} else {
console.log("横屏模式");
// 执行横屏逻辑
}
}
// 初始化检测
handleOrientationChange();
// 添加监听
window.addEventListener('resize', handleOrientationChange);
window.addEventListener('orientationchange', handleOrientationChange);
获取详细方向信息
// 获取屏幕方向
const getOrientation = () => {
const angle = window.orientation;
switch(angle) {
case 0:
case 180:
return 'portrait';
case 90:
case -90:
return 'landscape';
default:
return window.innerWidth > window.innerHeight ? 'landscape' : 'portrait';
}
};
React 组件适配
自定义 Hook
import { useState, useEffect } from 'react';
function useOrientation() {
const [orientation, setOrientation] = useState(
window.innerWidth > window.innerHeight ? 'landscape' : 'portrait'
);
useEffect(() => {
const handleResize = () => {
setOrientation(
window.innerWidth > window.innerHeight ? 'landscape' : 'portrait'
);
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return orientation;
}
// 使用示例
function MyComponent() {
const orientation = useOrientation();
return (
<div className={orientation === 'landscape' ? 'horizontal-layout' : 'vertical-layout'}>
{/* 内容 */}
</div>
);
}
方向敏感组件
function ResponsiveLayout({ children }) {
const isLandscape = window.innerWidth > window.innerHeight;
return (
<div className={`layout ${isLandscape ? 'landscape' : 'portrait'}`}>
{isLandscape ? (
<div className="side-by-side">
<div className="left-panel">{children[0]}</div>
<div className="right-panel">{children[1]}</div>
</div>
) : (
<div className="stacked">
<div className="top-section">{children[0]}</div>
<div className="bottom-section">{children[1]}</div>
</div>
)}
</div>
);
}
实用 CSS 适配方案
响应式布局容器
/* 基础容器 */
.responsive-container {
display: flex;
transition: all 0.3s ease;
}
/* 竖屏:垂直排列 */
@media (orientation: portrait) {
.responsive-container {
flex-direction: column;
min-height: 100vh;
}
.content {
padding: 1rem;
}
}
/* 横屏:水平排列 */
@media (orientation: landscape) {
.responsive-container {
flex-direction: row;
min-height: auto;
height: 100vh;
}
.sidebar {
width: 250px;
flex-shrink: 0;
}
.content {
flex: 1;
padding: 2rem;
}
}
字体大小适配
:root {
--base-font-size: 16px;
}
@media (orientation: landscape) {
:root {
--base-font-size: 14px;
}
h1 {
font-size: calc(var(--base-font-size) * 2.5);
}
}
@media (orientation: portrait) {
:root {
--base-font-size: 18px;
}
h1 {
font-size: calc(var(--base-font-size) * 2);
}
}
完整示例
// OrientationManager.js
class OrientationManager {
constructor() {
this.orientation = this.getOrientation();
this.listeners = new Set();
window.addEventListener('resize', this.handleResize.bind(this));
window.addEventListener('orientationchange', this.handleOrientationChange.bind(this));
}
getOrientation() {
return window.innerWidth > window.innerHeight ? 'landscape' : 'portrait';
}
handleResize() {
const newOrientation = this.getOrientation();
if (newOrientation !== this.orientation) {
this.orientation = newOrientation;
this.notifyListeners();
}
}
handleOrientationChange() {
setTimeout(() => {
this.handleResize();
}, 100);
}
addListener(callback) {
this.listeners.add(callback);
return () => this.listeners.delete(callback);
}
notifyListeners() {
this.listeners.forEach(callback => callback(this.orientation));
}
isLandscape() {
return this.orientation === 'landscape';
}
isPortrait() {
return this.orientation === 'portrait';
}
}
// 创建单例
export default new OrientationManager();
最佳实践建议
- 移动端优先:先设计竖屏布局,再适配横屏
- 渐进增强:基础功能在两种方向都能使用,横屏提供增强体验
- 避免锁定方向:除非必要(如游戏、视频播放器),不要强制锁定屏幕方向
- 测试多设备:在不同尺寸和分辨率的设备上测试
- 性能考虑:避免在方向变化时进行大量DOM操作
这些方法可以帮助你在 OpenClaw 项目中实现良好的横竖屏适配体验。

版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。