【问题标题】:Flex box 3 column layout with sticky footer带有粘性页脚的 Flex 框 3 列布局
【发布时间】:2017-01-05 18:51:58
【问题描述】:

我发现 here 的 flex 布局有问题。它来自this guy。问题是页脚与页面一起向下滚动,而不是停留在内容的底部或在没有足够内容的情况下停留在页面的底部。我的意思是

代码用于 React 组件,但很容易理解。

非常感谢任何帮助。

//// All styles are in Layout component. 

///////////  LAYOUT START  ////////////////

class Layout extends React.Component {
  constructor() {
    super();
  }

  render() {
    
    // STYLES START HERE
    
    const styleLayout = {
      siteWrapper: {
              display: 'flex',
              flexDirection: "column",
              height: '100vh'
      },      
      site: {        
              display: 'flex',
              flexGrow: '1',
              background: 'pink'   
      },
      siteContent: {        
              flexGrow: '1',
              paddingTop: '80px',
              background: 'lightgreen',  
      },
      rightColumn : {            
            width: '200px',
            paddingTop: '80px',
            background: 'lightblue'
      },
      leftColumn : {
            order: '-1',
            width: '200px',
            paddingTop: '80px',
            background: 'honeydew'
      }
    }
    

    return (
       
        <div style={styleLayout.siteWrapper}>               
            <Header />  
        
            <div style={styleLayout.site}>
                
                <div style={styleLayout.siteContent}>
                    dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
       dummy content dummy content dummy content dummy content dummy content
                </div> 
                
                <div style={styleLayout.leftColumn}>
                    <LeftColumn />
                </div>
                
                <div style={styleLayout.rightColumn}>
                    <RightColumn />
                </div>

            </div>
            <Footer />
      </div>    
    );
  }
}

////////////  COMPONENTS START

class RightColumn extends React.Component {
  render() {
  
    return (
      <div >Right Column</div>
    );
  }
}


class LeftColumn extends React.Component {
  render() {

    return (
      <div >Left dsargsrtdgfeadcsfdsColumn</div>
    );
  }
}

class Header extends React.Component {

  constructor(props) {
    super(props)  
  }

  render() {
    const styleHeader = {
      background: 'olivedrab'
    }
    return (
      <div style={styleHeader}>
         <h2> Header</h2>
        </div>
      
    );
  }
}


class Footer extends React.Component {
  render() {
  	const styleFooter = {
  		backgroundColor: 'grey',
  		height: '100px',
    }
    return (
      <footer style={styleFooter}>footer</footer>
    );
  }
}

///////////  COMPONENTS END  ////////////////


ReactDOM.render(
<Layout />
 	
,document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'></div>

【问题讨论】:

    标签: javascript css reactjs layout flexbox


    【解决方案1】:

    您必须使用min-height 而不是height

    这个

    siteWrapper: {
              display: 'flex',
              flexDirection: "column",
              height: '100vh'
    }
    

    应该是

    siteWrapper: {
               display: 'flex',
               flexDirection: "column",
               minHeight: '100vh'
    }
    

    //// All styles are in Layout component. 
    
    ///////////  LAYOUT START  ////////////////
    
    class Layout extends React.Component {
      constructor() {
        super();
      }
    
      render() {
        
        // STYLES START HERE
        
        const styleLayout = {
          siteWrapper: {
                  display: 'flex',
                  flexDirection: "column",
                  minHeight: '100vh'
          },      
          site: {        
                  display: 'flex',
                  flexGrow: '1',
                  background: 'pink'   
          },
          siteContent: {        
                  flexGrow: '1',
                  paddingTop: '80px',
                  background: 'lightgreen',  
          },
          rightColumn : {            
                width: '200px',
                paddingTop: '80px',
                background: 'lightblue'
          },
          leftColumn : {
                order: '-1',
                width: '200px',
                paddingTop: '80px',
                background: 'honeydew'
          }
        }
        
    
        return (
           
            <div style={styleLayout.siteWrapper}>               
                <Header />  
            
                <div style={styleLayout.site}>
                    
                    <div style={styleLayout.siteContent}>
                        dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
                    </div> 
                    
                    <div style={styleLayout.leftColumn}>
                        <LeftColumn />
                    </div>
                    
                    <div style={styleLayout.rightColumn}>
                        <RightColumn />
                    </div>
    
                </div>
                <Footer />
          </div>    
        );
      }
    }
    
    ////////////  COMPONENTS START
    
    class RightColumn extends React.Component {
      render() {
      
        return (
          <div >Right Column</div>
        );
      }
    }
    
    
    class LeftColumn extends React.Component {
      render() {
    
        return (
          <div >Left dsargsrtdgfeadcsfdsColumn</div>
        );
      }
    }
    
    class Header extends React.Component {
    
      constructor(props) {
        super(props)  
      }
    
      render() {
        const styleHeader = {
          background: 'olivedrab'
        }
        return (
          <div style={styleHeader}>
             <h2> Header</h2>
            </div>
          
        );
      }
    }
    
    
    class Footer extends React.Component {
      render() {
      	const styleFooter = {
      		backgroundColor: 'grey',
      		height: '100px',
        }
        return (
          <footer style={styleFooter}>footer</footer>
        );
      }
    }
    
    ///////////  COMPONENTS END  ////////////////
    
    
    ReactDOM.render(
    <Layout />
     	
    ,document.getElementById('app')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id='app'></div>

    【讨论】:

    • 该死的。我在包装和身体上玩高度。可惜我自己没有弄清楚。非常感谢。你救了我。
    【解决方案2】:

    如果你想让你的页脚贴在页面底部,请使用这个

    //// All styles are in Layout component. 
    
    ///////////  LAYOUT START  ////////////////
    
    class Layout extends React.Component {
      constructor() {
        super();
      }
    
      render() {
        
        // STYLES START HERE
        
        const styleLayout = {
          siteWrapper: {
                  display: 'flex',
                  flexDirection: "column",
                  height: '100vh'
          },      
          site: {        
                  display: 'flex',
                  flexGrow: '1',
                  background: 'pink'   
          },
          siteContent: {        
                  flexGrow: '1',
                  paddingTop: '80px',
                  background: 'lightgreen',  
          },
          rightColumn : {            
                width: '200px',
                paddingTop: '80px',
                background: 'lightblue'
          },
          leftColumn : {
                order: '-1',
                width: '200px',
                paddingTop: '80px',
                background: 'honeydew'
          }
        }
        
    
        return (
           
            <div style={styleLayout.siteWrapper}>               
                <Header />  
            
                <div style={styleLayout.site}>
                    
                    <div style={styleLayout.siteContent}>
                        dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
           dummy content dummy content dummy content dummy content dummy content
                    </div> 
                    
                    <div style={styleLayout.leftColumn}>
                        <LeftColumn />
                    </div>
                    
                    <div style={styleLayout.rightColumn}>
                        <RightColumn />
                    </div>
    
                </div>
                <Footer />
          </div>    
        );
      }
    }
    
    ////////////  COMPONENTS START
    
    class RightColumn extends React.Component {
      render() {
      
        return (
          <div >Right Column</div>
        );
      }
    }
    
    
    class LeftColumn extends React.Component {
      render() {
    
        return (
          <div >Left dsargsrtdgfeadcsfdsColumn</div>
        );
      }
    }
    
    class Header extends React.Component {
    
      constructor(props) {
        super(props)  
      }
    
      render() {
        const styleHeader = {
          background: 'olivedrab'
        }
        return (
          <div style={styleHeader}>
             <h2> Header</h2>
            </div>
          
        );
      }
    }
    
    
    class Footer extends React.Component {
      render() {
      	const styleFooter = {
      		backgroundColor: 'grey',
      		height: '30px',
      		position: 'fixed',
      		bottom: 0,
      		left: 0,
      		width: '100%'
        }
        return (
          <footer style={styleFooter}>footer</footer>
        );
      }
    }
    
    ///////////  COMPONENTS END  ////////////////
    
    
    ReactDOM.render(
    <Layout />
     	
    ,document.getElementById('app')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id='app'></div>

    【讨论】:

    • 感谢您抽出宝贵时间。实际上,我一直在寻找一个位于页面/内容末尾的页脚,除非只有少量内容,否则它会位于屏幕底部。顺便说一句,如果您仔细观察,您的粘性页脚可以工作,但布局仍然损坏。
    【解决方案3】:

    我最初编写了自己的React layout library "Re-Flex" 来处理可调整大小的窗格和复杂的嵌套布局。这对于您要完成的工作可能有点过头了,但如果有一天您决定在页面中添加一个可调整大小的窗格,这可能会派上用场。

    doc 中的一个示例是带有粘性页眉和页脚的完整布局:

    class ReflexAdvancedDemo extends React.Component {
    
      constructor () {
    
        super()
    
        this.resizeProps = {
          onStopResize: this.onStopResize.bind(this),
          onResize: this.onResize.bind(this)
        }
      }
    
      onResize (e) {
    
        if (e.domElement) {
    
          e.domElement.classList.add('resizing')
        }
      }
    
      onStopResize (e) {
    
        if (e.domElement) {
    
          e.domElement.classList.remove('resizing')
        }
      }
    
      render () {
    
        return (
          <ReflexContainer orientation="horizontal">
            <ReflexElement className="header" flex={0.1}>
              <div className="pane-content">
                <label>
                  Header (fixed)
                </label>
              </div>
            </ReflexElement>
            <ReflexElement>
              <ReflexContainer orientation="vertical">
                <ReflexElement {...this.resizeProps}>
                  <ReflexContainer orientation="horizontal">
                    <ReflexElement {...this.resizeProps}>
                      <div className="pane-content">
                        <div style={{height: '30%'}}/>
                        <label style={{height: '0%'}}>
                          Left Pane <br/> Top
                          <br/>
                          (splitter propagation)
                        </label>
                      </div>
                    </ReflexElement>
                    <ReflexSplitter propagate={true} {...this.resizeProps}/>
                    <ReflexElement {...this.resizeProps}>
                      <div className="pane-content">
                        <div style={{height: '30%'}}/>
                        <label style={{height: '0%'}}>
                          Left Pane <br/> Middle
                          <br/>
                          (splitter propagation)
                        </label>
                      </div>
                    </ReflexElement>
                    <ReflexSplitter propagate={true} {...this.resizeProps}/>
                    <ReflexElement {...this.resizeProps}>
                      <div className="pane-content">
                        <div style={{height: '30%'}}/>
                        <label style={{height: '0%'}}>
                          Left Pane <br/> Bottom
                          <br/>
                          (splitter propagation)
                        </label>
                      </div>
                    </ReflexElement>
                  </ReflexContainer>
                </ReflexElement>
                <ReflexSplitter {...this.resizeProps}/>
                <ReflexElement flex={0.5} {...this.resizeProps}>
                  <div className="pane-content">
                    <label>
                      Middle Pane
                    </label>
                  </div>
                </ReflexElement>
                <ReflexSplitter{...this.resizeProps}/>
                <ReflexElement {...this.resizeProps}>
                  <ReflexContainer orientation="horizontal">
                    <ReflexElement {...this.resizeProps}>
                      <div>
                        <ReflexContainer orientation="vertical">
                          <ReflexElement {...this.resizeProps}>
                            <div className="pane-content">
                              <label>
                                Right Pane <br/> Upper-Left
                              </label>
                            </div>
                          </ReflexElement>
                          <ReflexSplitter/>
                          <ReflexElement {...this.resizeProps}>
                            <div className="pane-content">
                              <label>
                                Right Pane <br/> Upper-Right
                              </label>
                            </div>
                          </ReflexElement>
                        </ReflexContainer>
                      </div>
                    </ReflexElement>
                    <ReflexSplitter {...this.resizeProps}/>
                    <ReflexElement {...this.resizeProps}>
                      <div className="pane-content">
                        <label>
                          Right Pane <br/> Bottom
                        </label>
                      </div>
                    </ReflexElement>
                  </ReflexContainer>
                </ReflexElement>
              </ReflexContainer>
            </ReflexElement>
            <ReflexElement className="footer" flex={0.1}>
              <div className="pane-content">
                <label>
                  Footer (fixed)
                </label>
              </div>
            </ReflexElement>
          </ReflexContainer>
        )
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-13
      • 1970-01-01
      • 2013-07-03
      • 1970-01-01
      • 2013-09-23
      • 2018-03-26
      • 2011-10-21
      • 2021-06-25
      • 2012-12-28
      相关资源
      最近更新 更多