请问是否有上下左右的布局推荐呢?

求推荐有上下左右的布局,

我查看antv的layout,只有上下左、上下右的布局,请问是否有上下左右的布局推荐呢?

image.png

想要的效果:
image.png

阅读 634
3 个回答

其实这种布局就是上中下的页面布局,然后中间再分成左中右三栏。
对于这样的布局,能实现的方式有很多,不过具体的方案必然是根据具体的情况来分析的。

对于现在的浏览器兼容情况来说,其实很简单,flex 分分钟搞定,再不行就用 grid 来实现。
CleanShot 2025-03-13 at 21.22.26@2x.png
CleanShot 2025-03-13 at 21.22.56@2x.png

代码就不抠了,抠代码太累了,直接发 url 吧。 https://linxz.github.io/tianyizone/free-flex.html

大布局就自己写吧,没几行代码,实在不行丢给 AI 也行。其实现在大部份网站都是这种布局,比如 SF,你仔细看看。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>纯Tailwind CSS文件浏览器与设计区布局</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/all.min.js"></script>
</head>
<body class="flex flex-col h-screen overflow-hidden bg-gray-50">
    <!-- 顶部区域 -->
    <div class="bg-white border-b border-gray-200 shadow-sm">
        <!-- 菜单栏 -->
        <div class="flex items-center px-4 h-10 border-b border-gray-200 text-sm">
            <div class="flex space-x-4">
                <div class="font-medium hover:bg-gray-100 px-2 py-1 rounded cursor-pointer">文件</div>
                <div class="font-medium hover:bg-gray-100 px-2 py-1 rounded cursor-pointer">编辑</div>
                <div class="font-medium hover:bg-gray-100 px-2 py-1 rounded cursor-pointer">视图</div>
                <div class="font-medium hover:bg-gray-100 px-2 py-1 rounded cursor-pointer">工具</div>
                <div class="font-medium hover:bg-gray-100 px-2 py-1 rounded cursor-pointer">帮助</div>
            </div>
        </div>
        
        <!-- 工具栏 -->
        <div class="flex items-center px-4 h-12 border-b border-gray-200">
            <div class="flex space-x-2">
                <button class="p-1.5 rounded hover:bg-gray-100" title="新建文件">
                    <i class="fas fa-file text-blue-600"></i>
                </button>
                <button class="p-1.5 rounded hover:bg-gray-100" title="保存">
                    <i class="fas fa-save text-blue-600"></i>
                </button>
                <button class="p-1.5 rounded hover:bg-gray-100" title="撤销">
                    <i class="fas fa-undo text-blue-600"></i>
                </button>
                <button class="p-1.5 rounded hover:bg-gray-100" title="重做">
                    <i class="fas fa-redo text-blue-600"></i>
                </button>
                <div class="border-r border-gray-300 h-6 mx-1"></div>
                <button class="p-1.5 rounded hover:bg-gray-100" title="预览">
                    <i class="fas fa-eye text-blue-600"></i>
                </button>
                <button class="p-1.5 rounded hover:bg-gray-100" title="发布">
                    <i class="fas fa-upload text-blue-600"></i>
                </button>
            </div>
        </div>
    </div>
    
    <!-- 中间内容区域 -->
    <div class="flex flex-1 overflow-hidden">
        <!-- 左侧文件列表区 -->
        <div id="leftPanel" class="w-64 bg-white border-r border-gray-200 flex flex-col shadow-sm overflow-hidden relative">
            <div id="leftResizer" class="absolute right-0 top-0 h-full w-1 bg-transparent hover:bg-blue-300 cursor-col-resize"></div>
            
            <div class="flex items-center justify-between p-2 border-b border-gray-200">
                <h2 class="font-medium text-gray-700">资源管理器</h2>
                <div class="flex">
                    <button class="p-1 rounded hover:bg-gray-100" title="新建文件夹">
                        <i class="fas fa-folder-plus text-gray-600 text-sm"></i>
                    </button>
                    <button class="p-1 rounded hover:bg-gray-100" title="刷新">
                        <i class="fas fa-sync text-gray-600 text-sm"></i>
                    </button>
                    <button class="p-1 rounded hover:bg-gray-100" title="折叠所有">
                        <i class="fas fa-compress-alt text-gray-600 text-sm"></i>
                    </button>
                </div>
            </div>
            
            <!-- 搜索框 -->
            <div class="p-2 border-b border-gray-200">
                <div class="relative">
                    <input type="text" class="w-full p-1.5 pl-7 rounded border border-gray-300 bg-white text-sm focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500" placeholder="搜索文件...">
                    <i class="fas fa-search text-gray-400 absolute left-2.5 top-2.5 text-sm"></i>
                </div>
            </div>
            
            <!-- 文件树结构 -->
            <div class="overflow-y-auto flex-1">
                <div class="p-1.5 text-sm">
                    <div class="flex items-center py-1 px-2 hover:bg-blue-50 rounded cursor-pointer">
                        <i class="fas fa-chevron-down text-gray-500 text-xs mr-1.5"></i>
                        <i class="fas fa-folder text-yellow-500 mr-1.5"></i>
                        <span>aaa</span>
                    </div>
                    <div class="pl-5">
                        <div class="flex items-center py-1 px-2 bg-blue-50 rounded cursor-pointer">
                            <i class="fas fa-chevron-down text-gray-500 text-xs mr-1.5"></i>
                            <i class="fas fa-folder-open text-yellow-500 mr-1.5"></i>
                            <span>bbb</span>
                        </div>
                        <div class="pl-5">
                            <div class="flex items-center py-1 px-2 hover:bg-blue-50 rounded cursor-pointer">
                                <i class="fas fa-file-code text-blue-500 mr-1.5"></i>
                                <span>bbb.ts</span>
                            </div>
                            <div class="flex items-center py-1 px-2 bg-blue-50 rounded cursor-pointer">
                                <i class="fas fa-file-alt text-blue-500 mr-1.5"></i>
                                <span>bbb.test.ts</span>
                            </div>
                            <div class="flex items-center py-1 px-2 hover:bg-blue-50 rounded cursor-pointer">
                                <i class="fas fa-file-code text-blue-500 mr-1.5"></i>
                                <span>bbb.flow.json</span>
                            </div>
                        </div>
                    </div>
                    <div class="flex items-center py-1 px-2 hover:bg-blue-50 rounded cursor-pointer">
                        <i class="fas fa-chevron-right text-gray-500 text-xs mr-1.5"></i>
                        <i class="fas fa-folder text-yellow-500 mr-1.5"></i>
                        <span>ccc</span>
                    </div>
                    <div class="flex items-center py-1 px-2 hover:bg-blue-50 rounded cursor-pointer">
                        <i class="fas fa-chevron-right text-gray-500 text-xs mr-1.5"></i>
                        <i class="fas fa-folder text-yellow-500 mr-1.5"></i>
                        <span>ddd</span>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 中间设计区 -->
        <div class="flex-1 flex flex-col bg-white border-r border-gray-200 overflow-hidden">
            <!-- 选项卡 -->
            <div class="flex h-9 bg-gray-50 border-b border-gray-200 overflow-x-auto whitespace-nowrap">
                <div class="flex items-center px-3 bg-white border-r border-gray-200 text-sm">
                    <i class="fas fa-file-code text-blue-500 mr-2 text-xs"></i>
                    <span class="truncate">bbb.test.ts</span>
                    <button class="ml-2 p-1 rounded-full hover:bg-gray-200 focus:outline-none">
                        <i class="fas fa-times text-gray-500 text-xs"></i>
                    </button>
                </div>
                <div class="flex items-center px-3 bg-gray-50 border-r border-gray-200 text-sm">
                    <i class="fas fa-file-code text-blue-500 mr-2 text-xs"></i>
                    <span class="truncate">bbb.flow.json</span>
                    <button class="ml-2 p-1 rounded-full hover:bg-gray-200 focus:outline-none">
                        <i class="fas fa-times text-gray-500 text-xs"></i>
                    </button>
                </div>
            </div>
            
            <!-- 工作区域 -->
            <div class="flex-1 p-4 overflow-auto bg-white bg-opacity-75 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImdyaWQiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZD0iTSAwIDEgTCAyMCAxIE0gMSAwIEwgMSAyMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2JhKDIyMCwgMjIwLCAyMjAsIDAuNSkiIHN0cm9rZS13aWR0aD0iMSIvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmlkKSIvPjwvc3ZnPg==')]">
                <!-- 示例设计元素 -->
                <div class="bg-white border border-gray-300 rounded shadow-sm p-3 mb-4 w-64 cursor-move">
                    <div class="font-medium mb-2">组件A</div>
                    <div class="bg-blue-50 border border-blue-200 rounded p-2 text-sm">
                        <p>单击编辑此组件内容</p>
                    </div>
                </div>
                
                <div class="bg-white border border-gray-300 rounded shadow-sm p-3 ml-20 w-72 cursor-move">
                    <div class="font-medium mb-2">组件B</div>
                    <div class="bg-green-50 border border-green-200 rounded p-2 text-sm">
                        <p>在这里添加你的设计内容</p>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 右侧属性/预览区 -->
        <div id="rightPanel" class="w-72 bg-white border-r border-gray-200 flex flex-col shadow-sm overflow-hidden relative">
            <div id="rightResizer" class="absolute left-0 top-0 h-full w-1 bg-transparent hover:bg-blue-300 cursor-col-resize"></div>
            
            <div class="flex items-center justify-between p-2 border-b border-gray-200">
                <h2 class="font-medium text-gray-700">属性面板</h2>
                <button class="p-1 rounded hover:bg-gray-100" title="关闭">
                    <i class="fas fa-times text-gray-600 text-sm"></i>
                </button>
            </div>
            
            <!-- 属性内容 -->
            <div class="overflow-y-auto flex-1 p-3">
                <div class="mb-4">
                    <div class="flex items-center mb-2">
                        <i class="fas fa-cog text-gray-500 mr-2"></i>
                        <span class="font-medium text-gray-700">常规</span>
                    </div>
                    <div class="pl-6 space-y-2">
                        <div class="flex justify-between">
                            <span class="font-medium text-gray-600">名称</span>
                            <span class="text-blue-800">组件B</span>
                        </div>
                        <div class="flex justify-between">
                            <span class="font-medium text-gray-600">类型</span>
                            <span class="text-blue-800">Container</span>
                        </div>
                        <div class="flex justify-between">
                            <span class="font-medium text-gray-600">可见性</span>
                            <div>
                                <label class="inline-flex items-center">
                                    <input type="checkbox" class="rounded text-blue-600 focus:ring-blue-500" checked>
                                </label>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="mb-4">
                    <div class="flex items-center mb-2">
                        <i class="fas fa-palette text-gray-500 mr-2"></i>
                        <span class="font-medium text-gray-700">样式</span>
                    </div>
                    <div class="pl-6 space-y-2">
                        <div>
                            <span class="font-medium text-gray-600 block mb-1">背景色</span>
                            <div class="flex items-center">
                                <div class="w-6 h-6 bg-green-50 border border-gray-300 rounded mr-2"></div>
                                <span class="text-sm">#f0fdf4</span>
                            </div>
                        </div>
                        <div>
                            <span class="font-medium text-gray-600 block mb-1">边框</span>
                            <select class="block w-full text-sm border border-gray-300 rounded p-1.5">
                                <option>细线</option>
                                <option>虚线</option>
                                <option>无</option>
                            </select>
                        </div>
                        <div>
                            <span class="font-medium text-gray-600 block mb-1">圆角</span>
                            <input type="range" class="w-full" min="0" max="20" value="4">
                        </div>
                    </div>
                </div>
                
                <div>
                    <div class="flex items-center mb-2">
                        <i class="fas fa-code text-gray-500 mr-2"></i>
                        <span class="font-medium text-gray-700">事件</span>
                    </div>
                    <div class="pl-6">
                        <select class="block w-full text-sm border border-gray-300 rounded p-1.5 mb-2">
                            <option>点击事件</option>
                            <option>悬停事件</option>
                            <option>拖拽事件</option>
                        </select>
                        <div class="bg-gray-50 border border-gray-200 rounded p-2 text-sm font-mono">
                            function onClick() {<br>
                            &nbsp;&nbsp;// 处理点击事件<br>
                            }
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 底部区域 -->
    <div class="h-20 bg-gray-50 border-t border-gray-200 flex flex-col">
        <!-- 选项卡栏 -->
        <div class="flex h-8 border-b border-gray-200 bg-gray-100">
            <div class="flex items-center px-4 bg-white border-r border-gray-200 text-sm font-medium">
                <span>控制台</span>
            </div>
            <div class="flex items-center px-4 text-sm">
                <span>问题</span>
            </div>
            <div class="flex items-center px-4 text-sm">
                <span>输出</span>
            </div>
            <div class="flex items-center px-4 text-sm">
                <span>调试控制台</span>
            </div>
        </div>
        
        <!-- 控制台内容 -->
        <div class="flex-1 bg-white p-2 font-mono text-sm overflow-y-auto">
            <div class="text-gray-500">> 正在编译 bbb.test.ts...</div>
            <div class="text-green-600">> 编译成功,无错误。</div>
            <div class="text-gray-500">> 正在执行测试...</div>
            <div class="text-green-600">> 所有测试通过 (3 tests, 12 assertions)</div>
            <div class="flex items-center">
                <span class="text-gray-400">></span>
                <div class="ml-1 w-2 h-4 bg-gray-500 animate-pulse"></div>
            </div>
        </div>
    </div>
    
    <!-- 简单交互脚本 -->
    <script>
        // 文件夹点击事件
        document.querySelectorAll('.fa-folder, .fa-folder-open, .fa-chevron-down, .fa-chevron-right').forEach(icon => {
            icon.parentElement.addEventListener('click', function(e) {
                // 仅当点击的是图标的父元素时执行
                if (e.target === this || e.target.tagName === 'I' || e.target.tagName === 'SPAN') {
                    const chevron = this.querySelector('.fa-chevron-down, .fa-chevron-right');
                    const folder = this.querySelector('.fa-folder, .fa-folder-open');
                    
                    if (chevron) {
                        if (chevron.classList.contains('fa-chevron-down')) {
                            chevron.classList.remove('fa-chevron-down');
                            chevron.classList.add('fa-chevron-right');
                        } else {
                            chevron.classList.remove('fa-chevron-right');
                            chevron.classList.add('fa-chevron-down');
                        }
                    }
                    
                    if (folder) {
                        if (folder.classList.contains('fa-folder')) {
                            folder.classList.remove('fa-folder');
                            folder.classList.add('fa-folder-open');
                        } else {
                            folder.classList.remove('fa-folder-open');
                            folder.classList.add('fa-folder');
                        }
                    }
                    
                    // 切换下一个兄弟元素的可见性
                    const sibling = this.nextElementSibling;
                    if (sibling && sibling.classList.contains('pl-5')) {
                        sibling.style.display = sibling.style.display === 'none' ? '' : 'none';
                    }
                }
            });
        });

        // 左侧面板调整大小
        document.getElementById('leftResizer').addEventListener('mousedown', function(e) {
            e.preventDefault();
            const leftPanel = document.getElementById('leftPanel');
            const startX = e.clientX;
            const startWidth = parseInt(window.getComputedStyle(leftPanel).width, 10);
            
            function onMouseMove(e) {
                const newWidth = startWidth + e.clientX - startX;
                leftPanel.style.width = `${newWidth}px`;
            }
            
            function onMouseUp() {
                document.removeEventListener('mousemove', onMouseMove);
                document.removeEventListener('mouseup', onMouseUp);
            }
            
            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', onMouseUp);
        });
        
        // 右侧面板调整大小
        document.getElementById('rightResizer').addEventListener('mousedown', function(e) {
            e.preventDefault();
            const rightPanel = document.getElementById('rightPanel');
            const startX = e.clientX;
            const startWidth = parseInt(window.getComputedStyle(rightPanel).width, 10);
            
            function onMouseMove(e) {
                const newWidth = startWidth - e.clientX + startX;
                rightPanel.style.width = `${newWidth}px`;
            }
            
            function onMouseUp() {
                document.removeEventListener('mousemove', onMouseMove);
                document.removeEventListener('mouseup', onMouseUp);
            }
            
            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', onMouseUp);
        });
    </script>
</body>
</html>

更多示例可以参考 https://pageforge.devlive.org 该站点就是类似这种布局,使用纯 Tailwind CSS 实现

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题