代码之家  ›  专栏  ›  技术社区  ›  ccpizza

使用鼠标动态调整css网格布局中的列大小

  •  37
  • ccpizza  · 技术社区  · 7 年前

    我设置 resize: horizontal; nav 元素来调整大小,当我拖动元素右下角的小调整手柄时,它会调整大小,但相邻列的宽度不会自动调整,这会导致重叠。这是一个坏的 codepen .

    HTML :

    <main>
     <nav>#1</nav>
     <header>#2</header>
     <section>#3</section>
    </main>
    

    CSS :

    main {
        display: grid;
        border: 3px dotted red;
        grid-gap: 3px;
        grid-template-columns: 200px 1fr;
        grid-template-rows: 100px 1fr;
        height: 100%;
    }
    
    nav {
        grid-column: 1;
        grid-row: 1;
        grid-row: 1 / span 2;
        resize: horizontal;
        overflow: scroll;
        border: 3px dotted blue;
    }
    

    我希望css网格引擎能够自动处理这种情况,但显然没有。

    我用 jquery-ui resizable

    我正在研究如何通过设置网格属性来使用jquery grid-template-columns/rows: resize window 对象,而不是dom元素。

    不必处理诸如dragstart/dragend之类的低级鼠标事件,有什么方法可以做到这一点?

    2 回复  |  直到 7 年前
        1
  •  42
  •   baetheus    6 年前

    您希望实现的目标仅使用css是可能的。我修改了你的例子。主要收获如下:

    1. 最重要的是,尽量不要在语义布局标记中插入原始内容。使用标题、段落和列表标记,而不是文本和br标记。这使您的代码更易于阅读和推理。您的许多问题都是因为在网格区域中如何处理回流。
    2. 使用网格模板简化布局,因为它将使断点回流更容易。
    3. 使用溢出:自动;同时指定调整大小:垂直/水平。如果不设置溢出,调整大小将失败。

    body {
        margin: 10px;
        height: 100%;
    }
    
    main {
        display: grid;
        border: 3px dotted red;
        padding: 3px;
        grid-gap: 3px;
        
        grid-template: 
        "nav head" min-content
        "nav main" 1fr
            / min-content 1fr;
    }
    
    nav {
        grid-area: nav;
        border: 3px dotted blue;
        overflow: auto;
        resize: horizontal;
        
        min-width: 120px;
        max-width: 50vw;
    }
    
    header {
        grid-area: head;
        border: 3px dotted orange;
        overflow: auto;
        resize: vertical;
        
        min-height: min-content;
        max-height: 200px;
    }
    
    section {
        grid-area: main;
        border: 3px dotted gray;
    }
    <main>
      <nav>
        <ul>
          <li>Nav Item</li>
          <li>Nav Item</li>
          <li>Nav Item</li>
          <li>Nav Item</li>
          <li>Nav Item</li>
          <li>Nav Item</li>
        </ul>
      </nav>
    
      <header>
        <h1>Header Title</h1>
        <small>Header Subtitle</small>
      </header>
    
      <section>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      </section>
    </main>
        2
  •  12
  •   ccpizza    6 年前

    解决方案是 使用显式固定列大小( grid-template-columns: 200px 1fr; grid-template-columns: 0.2fr 1fr; 然后,网格CSS引擎将处理相邻框的大小调整。下一步是在网格框内添加嵌套div,将其最小高度/宽度设置为100%,并通过 jqueryui resizable .

    jsfiddle .

    /* Javscript */
    
    $('.left_inner').resizable();
    $('.right_top_inner').resizable();
    $('.right_bottom_inner').resizable();
    /* CSS */
    
    	.grid {
    		display: grid;
    		grid-template-columns: 0.2fr 1fr;
    		grid-template-rows: 1fr 4fr;
            grid-gap: 3px;
    		position: relative;
    	}
    
    	.left {
    		grid-row: 1 / span 2;
    	}
    
    	.right_top {
    		grid-column: 2;
    		grid-row: 1;
    	}
    
    	.right_bottom {
    		grid-column: 2;
    		grid-row: 2;
    	}
    
    	.left_inner {
    		background-color: #fedcd2;
    		padding: 0;
    		width: 100%;
    		min-width: 100%;
    		height: 100%;
    		min-height: 100%;
    		text-align: center;
    	}
    
    	.right_top_inner {
    		background-color: #f9cf00;
    		padding: 0;
    		width: 100%;
    		min-width: 100%;
    		height: 100%;
    		min-height: 100%;
    		text-align: center;
    	}
    
    	.right_bottom_inner {
    		background-color: #f8eee7;
    		padding: 0;
    		width: 100%;
    		min-width: 100%;
    		height: 100%;
    		min-height: 100%;
    		text-align: center;
    	}
    <!-- HTML -->
    
    <script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/css/smoothness/jquery-ui-1.10.0.custom.min.css" />
    <script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/jquery-ui.js"></script>
    
    	<main class="grid">
    	 <aside class='left'>
    	  <div class="left_inner">
    		drag the bottom right handle to resize
    	  </div>
    	 </aside>
    	 <section class="right_top">
    	  <div class="right_top_inner">right_top_inner</div>
    	 </section>
    	 <section class="right_bottom">
    	  <div class="right_bottom_inner">right_bottom_inner</div>
    	 </section>
    	</main>

    虽然这在可能的最简单场景中有效,但在实际用例中会出现问题。我试过了 jquery-ui layout 哪一种效果更好(这是一个 demo angular-split-pane (基于angular 1),工作良好,尺寸较小。