Izak Filmalter me escribió:
En el sitio en el que estoy trabajando hay una barra de navegación con algunos elementos: una entrada de búsqueda, el nombre completo del usuario y algunos iconos. Los iconos son fijos con, el nombre del usuario varía y la barra de búsqueda debería ocupar el resto del espacio utilizable.
No importa lo que intente, no puedo hacer que la barra de búsqueda use todo el espacio disponible y no más cuando la longitud del nombre de usuario es dinámica.
Ya le envié una respuesta a Izak, pero compartiré esa solución aquí. Flexbox! Estoy seguro de que no sorprende que flexbox sea una herramienta de diseño maravillosa. Aquí tengo una guía para flexbox que es una muy buena referencia.
La buena noticia aquí es que esto es algo bastante fácil de hacer con el diseño de flexbox. Daremos más detalles, pero estas pocas líneas de código básicamente lo hacen:
.bar {
display: flex;
}
.search {
flex: 1;
}
Paso a paso
Supongamos un marcado como este. Realmente no hay sorpresas aquí. Acabo de envolver la entrada de búsqueda en un <div>
principalmente porque me extraña que una entrada se convierta en un elemento flexible, pero probablemente desee un elemento de envoltura (como un <form>
) de todos modos, porque probablemente tendrías un <label>
Y qué no.
<div class="bar">
<div class="icon icon-1"></div>
<div class="icon icon-2"></div>
<div class="icon icon-3"></div>
<div class="username">
Emily Blunt
</div>
<div class="search">
<input type="search" placeholder="search..." />
</div>
</div>
Sin CSS
Para alinearlos horizontalmente y centrados:
.bar {
display: flex;
align-items: center;
}
Asegurémonos de que la barra sea tan ancha como la ventana del navegador. Podemos establecer el 100% de ancho con bastante facilidad. Pero cada vez que hago eso, me recuerda que deberíamos cambiar el tamaño de una caja: caja de borde; – De lo contrario, cualquier relleno o borde en ese contenedor sería más ancho que el 100% y eso es lo peor.
*, *:before, *:after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
.bar {
display: flex;
align-items: center;
width: 100%;
background: #eee;
padding: 20px;
}
Para el truco final:
.search {
/* take up the rest of the remaining space */
flex: 1;
}
.search input {
width: 100%;
}
Funcionará así:
Ahora que estamos en flexbox-land, incluso podemos cambiar el orden de las cosas todo lo que queramos y obtener la misma acción de espaciado. La propiedad de la orden es 0 de forma predeterminada, por lo que cualquier valor positivo colocará ese elemento flexible al final o el valor negativo al principio. Y luego en orden, como z-index
.
.bar-2 .username {
order: 2;
}
.bar-2 .icon-3 {
order: 3;
}
.bar-3 .search {
order: -1;
}
.bar-3 .username {
order: 1;
}
Bonus RWD!
Flexbox es muy amigable con el diseño receptivo, porque podemos intercambiar pedidos y tamaños, e incluso envolver, muy fácilmente. Hagamos que nuestra demostración se ajuste, y hagamos que la búsqueda y el nombre de usuario sean de ancho completo:
@media (max-width: 650px) {
.bar {
flex-wrap: wrap;
}
.icon {
order: 0 !important;
}
.username {
order: 1 !important;
width: 100%;
margin: 15px;
}
.search {
order: 2 !important;
width: 100%;
}
}
Manifestación
Aquí vamos:
Vea el reordenamiento de Pen Flexbox por Chris Coyier (@chriscoyier) en CodePen.
Soporte del navegador
No se puede mencionar flexbox en estos días sin un navegador de gentuza. Como siempre, puedes consultar Can I Use. IE 9 es el gran limitador que queda. Si necesita apoyar eso, tendrá que encontrar otra forma. De lo contrario, entre sintaxis antigua / nueva / tweener, estará bien. No estamos usando nada extraño aquí.
El truco es usar Autoprefixer que maneja maravillosamente flexbox. Al usar eso, las propiedades / valores de flexbox en esta demostración se convierten en:
.bar {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
.search {
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
.bar-2 .username {
-webkit-order: 2;
-ms-flex-order: 2;
order: 2;
}
¡Pero necesito una alternativa mejor!
Una posibilidad es utilizar Modernizr para detectar el soporte de flexbox. Pondrá un nombre de clase en el elemento html, como:
<html class="no-flexbox">
Puede usar eso para usar una técnica de diseño diferente:
.no-flexbox .bar {
display: table;
border-spacing: 15px;
padding: 0;
}
.no-flexbox .bar > * {
display: table-cell;
vertical-align: middle;
white-space: nowrap;
}
.no-flexbox .username {
width: 1px;
}
Funciona bastante bien:
No es la única forma posible. Podría meterse con bloques en línea o flotar y medir cosas con JavaScript. O podrías usar una mesa real. La web, yo, siempre hay una manera.