Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: search box will be automatically resize base on windows size using Flexbox

Tags:

html

css

flexbox

I want to design a layout as below image:

layout

As in this layout, this is my header. Black rectangle is some components (buttons, link ...) with fixed width, and red rectangle is my search form.

I want when user changes the size of browser windows, search form will be smaller (in width), until some value, will appear horizontal scrollbar. Maybe the hard part is: I don't know how to solve "auto-resize" in css.

Here is my sample code:

my HTML:

<!--[if lt IE 7 ]> <html class="ie6"> <![endif]-->
<!--[if IE 7 ]>    <html class="ie7"> <![endif]-->
<!--[if IE 8 ]>    <html class="ie8"> <![endif]-->
<!--[if IE 9 ]>    <html class="ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html class=""> <!--<![endif]-->
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title Here</title>
    <link type="text/css" rel="stylesheet" href="css/application.css">
    <script src="javascripts/pace.js"></script>
</head>
<body>
    <header class="page-head">
        <div class="wrapper">
            <div class="logo"></div>
            <form class="form-search" action="#" onsubmit="return false" method="get" name="search_form">
                <div class="search-box"></div>  
            </form>
            <nav class="site-nav">
                <span><a href="/" class="site-nav__home"></a></span>
                <div class="site-nav__item">Home</div>
                <div class="site-nav__item">Notifications</div>
                <div class="site-nav__item">Profile</div>
                <div class="site-nav__button">Add Question</div>
            </nav>
        </div>
    </header>
</body> 
</html> 

my CSS:

.html {
    box-sizing: border-box;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

*, *:before, *:after {
    box-sizing: inherit;
}

.page-head {
    position: fixed;
    top: 0;
    left: 0;
    height: 45px;
    width: 100%;
    font-size: 14px;
    color: #fff;
}

.page-head.wrapper {
    width: 1020px;
    margin: 0 auto;     
    /* center horizontally. apply for block level element */
    border-bottom: 1px solid #ddd; 
    /* drop shadow effect */
    box-shadow: 0 3px 5px -3px rgba(200, 200, 200, 0.3);
    height: 45px;
    display: flex;
    flex-direction: row;
}

form {
    display: block;
}

.logo {
    width: 45px;
    height: 45px;
    background: red;
}
.form-search {
    margin: 0;
    float: none;
    position: static;
    height: 27px;
    background-image: url(../images/search.png);
}

.search-box {
    border-radius: 2px;
    -webkit-font-smoothing: antialiased;
    margin-top: 0;
    padding: 5px;
    padding-left: 26px;
    float: none;
    width: 100%;
    height: 27px;
    font-size: 15px;
    line-height: normal;
    background: #eee;
}

.site-nav {
    display: flex;
    flex-direction: row;
    z-index: 1;
    margin-left: 20px;

}

.site-nav__item {
    display: block;
    height: 45px;
    color: #666;
    padding: 0 16px;
    background-repeat: no-repeat;
    background-position: 10px center;
    border-bottom: 1px solid transparent;
}

Please tell me how to design this layout using CSS. And if possible, how can do by using Flexbox ?

Thanks :)

like image 793
Trần Kim Dự Avatar asked May 10 '15 17:05

Trần Kim Dự


People also ask

How do you stop CSS from resizing?

To prevent a text field from being resized, you can use the CSS resize property with its "none" value. After it you can use the height and width properties to define a fixed height and width for your <textarea> element.

How do you auto resize in CSS?

Answer: Use the CSS max-width Property You can simply use the CSS max-width property to auto-resize a large image so that it can fit into a smaller width <div> container while maintaining its aspect ratio.

How do I stop my browser window from resizing CSS?

How Do I Stop Html From Resizing? You can control a text field from being resized by adding the attribute “none” to the CSS resize property. Then, after defining the width for your *textarea* element and height for your height, you can use them as parameter values that are to determine a fixed height.

How do I resize a box in CSS?

The box-sizing property allows us to include the padding and border in an element's total width and height. If you set box-sizing: border-box; on an element, padding and border are included in the width and height: Both divs are the same size now! Hooray!


2 Answers

Flexbox works well to solve this issue. You basically want the search box (or its form element) to fill available space and shrink as needed (up to a certain point) when the window size decreases.

Gif of flexbox behavior during window resizing

The secret sauce is to give the form element a flex-grow: 1 to tell it to fill the available space.

html {
  font-family: Arial, Helvetica, sans-serif;
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;   
}
.page-head {
  display: flex;  
  align-items: center;  /* Makes the nav items and logo appear vertically centered with the search box*/
  margin: 1.5rem;
}

.logo {
  /* Prevent logo from shrinking 
     so it doesn't collide when window gets narrow. */
  flex-shrink: 0;
}

.search-form {
  margin: 0 1rem;  
  flex-grow: 1; /* <-- THE SECRET SAUCE! */
  min-width: 18rem;
}

.search-box {
  width: 100%;  
  padding: .4rem;
  background-color: #ffb;
}

.site-nav > ul {
  display: flex;
  margin: 0;
}
.site-nav__item {  
  /* Prevent nav items from shrinking 
     so they won't collide when window gets narrow. */
  flex-shrink: 0;
  
  list-style-type: none;
  margin: 0 .55rem;
  cursor: pointer;
  /* Prevent multi-word nav items from wrapping. */
  white-space: nowrap;  
}
<header class="page-head">
 
  <div class="logo">Logo</div>

  <form class="search-form">
    <input type="text" class="search-box" 
           placeholder="Search   (this form fills available space)">
  </form>

  <nav class="site-nav">
    <ul>
      <li class="site-nav__item">Home</li>
      <li class="site-nav__item">Notifications</li>
      <li class="site-nav__item">Profile</li>
      <li class="site-nav__item">Add Question</li>      
    </ul>
  </nav>
</header>
like image 102
Jason Frank Avatar answered Sep 21 '22 13:09

Jason Frank


There are many ways to do this, I prefer using tables because they already have most of the required styles - even if it does add a lot of html. I decided it would be best to create a template and let you change things as necessary:

#header{
  width:100%;
  height:45px;
  table-layout:auto;
}
#header img{
  width:45px;
  height:45px;
  background-color:red;
  float:left;
}
#header form{
  float:left;
  width:100%;
  height:100%;
  margin:0;
  min-width:200px;
}
#header input{
  width:100%;
  height:45px;
}
#header nav{
  float:right;
  display:inline-table;
  vertical-align:middle;
}
#header a{
  padding:10px;
  background-color:black;
  color:white;
  vertical-align:middle;
}
<table id="header">
	<tr>
		<td>
			<img id="logo"/>
		</td>
		<td style="width: 100%;">
			<form>
				<input type="text" name ="search" id="search" placeholder="Search"/>
			</form>
		</td>
		<td style="white-space:nowrap;">
			<nav> 
				<a href="#">Home</a>  
				<a href="#">Notifications</a>
				<a href="#">Profile</a>
				<a href="#">Add question</a>
			</nav>
		</td>
	</tr>
</table>

Apologies, I tried keeping my structure as similar to yours as I could but there are a fair few differences. In any case, I hope this helps!

like image 39
jaunt Avatar answered Sep 18 '22 13:09

jaunt