Im trying to build a responsive navigation using flexbox. I have the desktop version looking fine. But when it enters the phone media query, I want the order of the items to change. I want the logo above the navigation links on its own line, and the 4 nav links below centrally aligned. I have tried everything so I come to the great people of stack overflow for help.
link to code:
http://codepen.io/Davabo/pen/EKNBMz
* {margin:0; padding:0; font-weight: normal;}
$phone: 480px;
#mixin phone {
#media (max-width: #{$phone}) {
#content;
}
}
.menu{
display:flex;
height: auto;
max-width: 100%;
a{text-decoration:none;color: black;padding:20px;}
& > div {
flex: 2;
font-size: 20px;
text-align: center;
padding-top: 30px;
}
.logo {
width: 100%;
flex: 1;
padding-top: 40px;
text-align: center;
}
#include phone {
.logo {
background: pink;
text-align: center;
flex: 5;
flex-grow: 5;
}
.nav1, .nav2 {
flex-basis: 100%;
width: 100%;
}
}
}
I have attached what I want the phone navigation to look like:
http://prntscr.com/afwt0g
Thank you so much for any help!
You need to use a combination of the order and flex-grow properties on the items e.g.
#media screen and {max-width: 480px){
.menu{flex-wrap: wrap;}
.logo{order: 1; flex-grow: 2;}
.nav1{order: 2; flex-grow: 1;}
.nav2{order: 3; flex-grow: 1;}
}
Order rearranges the order of items within a flex container.
Flex-grow works out the sizing of an element compared to it's siblings within a flex container
wrap on the container forces items to wrap when the container width forces it
Here is a link to a good flexbox resource: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Related
I'm trying to build a portfolio website like this now.
Website Link
Typically when the width of the screen size is less than half of the full width for the website, its content starts to be hidden instead of shrinking. Mine on the other hand, keeps shrinking.
How do I do that with CSS?
It's what I've done so far. I'm using sass and React.js.
App.scss
$main-container-height: 87vh;
$navbar-height: 13vh;
/* Navbar style */
.navbar {
height: $navbar-height;
text-transform: uppercase;
.name {
text-align: left;
margin-left: 1.5rem;
a {
color: black;
font-size: 25px;
margin: 0 0 0 0.5rem;
text-decoration: none;
}
.box {
height: 15px;
width: 15px;
background-color: blue;
display: inline-block;
}
}
.nav-list {
a {
color: black;
margin: 0 1.5rem;
}
a:hover {
color: #519df9;
text-decoration: none;
}
}
}
/* Homepage Style */
.main-box {
height: $main-container-height;
min-width: 50%;
.left-main-box {
height: $main-container-height;
width: 40vw;
display: inline-block;
background-color: #e8c9c9;
}
.right-main-box {
display: inline-block;
height: $main-container-height;
width: 60vw;
background-color: white;
}
}
HomeMain.js
import React, { Component } from "react";
import CenterBox from "./CenterBox";
import Footer from "./Footer";
export class HomeMain extends Component {
render() {
return (
<div className="main-box">
<div className="left-main-box">left</div>
<div className="right-main-box">right</div>
</div>
);
}
}
I'm not sure of what you expect since I can't replicate the problem: decreasing screen width on the link you provided has no shrinking effect for me in Firefox.
That being said:
I recommend that you do you layout for small screens first as it is way easier to do this way rather than the other.
In order to do that you can use grid along with media queries.
For example, you can achieve that using grid-template-areas property, and change this layout using a media query.
Once your template is ok, you can style elements within containers with flex for alignment etc.
Don't forget to use min-width and max-width when using responsive units.
something like that (you get the idea)
/* mobile */
.main-box{
display: grid;
grid-template-areas:
"header"
"nav"
"content"
"footer";
}
/* desktop */
#media screen and (min-width: 1024px){
.main-box{
grid-template-areas:
"header header header"
"nav nav nav"
"leftbox content rightbox"
"footer footer footer";
}
More on grid and flex if you want to practice.
There is a website I am handling https://www.onlinesalebazaar.in/.
When opened on Android it looks fine, but on Apple, the UI is distorted. Beneath the slider it's intended to show 2 images horizontally but on iPhone it is distorted.
I tried changing the CSS to width 49% etc, but nothing works.
Styles used is as follows:
/* Create four equal columns that sits next to each other */
.column {
-ms-flex: 25%; /* IE10 */
flex: 25%;
max-width: 25%;
padding: 0 4px;
}
.column img {
margin-top: 8px;
vertical-align: middle;
}
/* Responsive layout - makes a two column-layout instead of four columns */
#media screen and (max-width: 800px) {
.column {
-ms-flex: 50%;
flex: 50%;
max-width: 50%;
}
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 600px) {
.column {
-ms-flex: 100%;
flex: 100%;
max-width: 50%;
}
}
Can someone help please on this
Bootstrap is causing this to happen with this bit of CSS:
.row:before,
.row:after {
display: table;
content: " ";
}
Safari on iOS counts these pseudo elements as actual elements thus causing the flex container to have an additional child element before and after it.
By adding the CSS below it will make the items appear properly in iOS Safari:
.row:before,
.row:after {
display: none;
}
This may have an undesired effect elsewhere so it's probably recommended to add a class to target those rows that use flex and do something like this instead:
.myFlexRow.row:before,
.myFlexRow.row:after {
display: none;
}
You're using Bootstrap 3.2 for your site which wasn't built with flexbox in mind. With Bootstrap 4+ you would simply be able to use the .d-flex class instead.
The image on my home page is left aligned.
While it looks great on desktop, it does not look good on mobile
I am trying to "center" the image defined by .entry-image.attachment-post.gsfc-alignleft on mobile views.
I have tried the following without success :
#media all and (max-width: 675px) {
.entry-image.attachment-post.gsfc-alignleft {
width: 100%!important;
max-width: none;
text-align: center;
margin-left: auto!important;
margin-right: auto!important;
}
}
My website is : parlons-survivalisme.com
What am I missing ?
You need to set the outer a Tag to width: 100% in order to align the image above the whole width.
For instance:
a.alignleft {
width: 100%;
}
As advised by Luca, changed the code to the following, which works !!
#media all and (max-width: 675px) {
a.alignleft {
width: 100%;
margin-left: auto;
margin-right: auto;
text-align: center;
}
}
There are 2 straightforward solutions to center an image.
The first is to set your image to 'display: inline-block' and then wrap it with an outer div where you set the 'text-align' property to center.
.wrapper-div {
width: 100%;
text-align: center
}
.img {
display: inline-block;
}
The other solution is to make sure your img is a block element (display: block) and then set the margin-right and margin-left to auto.
.img {
display: block;
margin-right: auto;
margin-left: auto;
}
If you still have a bug, look at the parent element width (to make sure it is 100% on small screens).
I'm newish to flexbox. My current layout isn't working as well as I'd hoped - my columns are only as tall as the content within them.
+----------------+
| header |
+-+--------------+
|n|content |
|v+--------------+
+-+
empty
----------------------
I'm hoping flexbox will solve that. I'll have to retrofit my existing markup.
Page is full screen width, with a full-width header, then the rest of the page is fluid width content with a fixed width sidebar. (Some pages have a sidebar on the left, others have one on the right.)
Ideally, the two content areas will both extend to the bottom of the page (with their coloured backgrounds) but only go over the fold and scroll if the content is longer than a page.
+----------------+
| header |
+-+--------------+
|n| content |
|a| |
|v| |
--+-+--------------+--
Do I treat the entire page as the "container", in which I create two rows, one of which is split? Or do I just start the flexbox stuff with the second row that has the sidebar?
It seems to me, it has to be the former, if flexbox is to know how high my header is. Otherwise, when I set their heights to 100%, they'll go over the fold by an amount equal to my header.
I didn't see a header-and-split-columns as a simple example in the flexbox docs, but I'll continue to read and experiment.
(Naturally, it will also have to be responsive, so that, at smaller screen sizes, the elements wrap under each other to fit on a narrow screen.)
OK, gathering all the feedback I've gotten above, and borrowing heavily from here, this is what I came up with.
<div class="page-body no-nav no-aside">
<main>
<p>content</p>
</main>
<nav>nav</nav>
<aside>details</aside>
</div>
.
.wrapper {
display: flex;
min-height: 100vh;
flex-direction: column;
background-color: blue;
header {
height: 155px;
}
.page-body {
display: flex;
flex: 1;
background-color: lavender;
flex-direction: column;
min-height: calc(100vh - 155px);
min-height: -webkit-calc(100vh - 155px);
nav {
order: -1;
background-color: red;
}
aside {
background-color: orange;
}
&.no-nav nav,
&.no-aside aside {
display: none;
}
}
}
#media (min-width: 768px) {
.wrapper {
.page-body {
flex-direction: row;
flex: 1;
main {
flex: 1;
}
nav {
flex: 0 0 385px;
}
aside {
flex: 0 0 320px;
}
}
}
}
Header is fixed height
Page-body fills the rest of the page
pretty straightforward to add a footer if needed (see Holy-Grail article above)
all columns are full height, no scrolling unless content flows
sidebars are fixed width, content body is fluid
structure is responsive
added some functionality to hide/show the sidebars as-needed per page
Oddly, this defaults to small-screen as has a media query that overrides for larger screens. (Usually the other way around where I come from.)
You can use calc for the min-height (assuming header height as 50px):
.content {
min-height: calc(100% - 50px);
min-height: -webkit-calc(100% - 50px);
}
As for the fixed width sidebar, prevent it from growing or shrinking:
.sidebar {
flex-shrink: 0;
flex-grow: 0;
}
I would only put the sidebar and the content in the flex box. Put both the sidebar and the content inside a container div and assign display:flex to the container:
.container {
display: flex;
flex-direction: row;
}
You will likely need your sidebar to collapse or become fluid with media queries when the window width decreases to a certain point. Also, I find this tool helpful when working with flex, as it does get complex.
You can create two flexboxes - one to divide header and "rest", and the other inside "rest" to divide it into nav and content.
Also you can just set min-height of header, as can be seen here
I hope I've understood your question.. This approach might help get you started. Let me know if you have any specific questions...
body {
margin: 0;
height: 100vh;
font-family: sans-serif;
color: white;
}
.container {
height: 100%;
background: grey;
display: flex;
flex-direction: column;
}
header {
height: 150px;
background: blue;
}
.content {
height: 100%;
display: flex;
background: green;
}
.sidebar {
background: #76c5ff;
width: 200px;
}
.main {
background: #ef3a59;
flex: 1;
}
#media (max-width: 600px) {
body {
height: initial;
}
.content {
height: initial;
}
.content {
flex-direction: column;
}
.sidebar {
width: 100%;
order: 2; /* remove this to keep sidebar above main content */
}
}
<div class="container">
<header>header
</header>
<div class="content">
<div class="sidebar">sidebar</div>
<div class="main">main content</div>
</div>
</div>
First of all, here's the jsfiddle for the particular markup/styling in question.
Main question is why the img and text box (dark_block) do not have the same margin. Both are set to 100% width of the container div, so I'm not sure what's up. Mind taking a look?
Other things I'm still trying to figure out and googling (thus far) has not helped me:
When the text box is in-line (to the left) of the photo container, how do I get it to be the same height as the photo container
If the image's width is smaller than the photo container, how do I get it to center horizontally and vertically?
For accessibility sake, can I just create a non-responsive version of the css before the #media tag stuff?
Sorry, I'm sort of new to web development, and any help would definitely be appreciated. Also if anything in the code fragment seems awfully done, call me out! I'd love to learn some best-practices in addition to solving the issue at hand. Especially display types, having a hard time wrapping my head around 'em.
Appreciate you taking the time to look at this!
John
CODE:
<div id="home_top_container">
<div id="photo_slider">
<img src="redacted">
</div>
<div id="dark_block"></div>
</div>
#home_top_contianer {
width: 100%;
margin-left: 10px;
margin-right: 10px;
margin-bottom: 20px;
}
#media screen and (min-width: 800px){
#photo_slider{
float:right;
background-color: #cccccc;
padding: 0px;
width: 69%;
min-width: 500px;
display: inline-block;
}
}
#media screen and (max-width: 799px){
#photo_slider{
float:none;
background-color: #cccccc;
padding: 0px;
width: 100%;
min-width: 500px;
display: inline-block;
}
}
#media screen and (min-width: 800px){
#dark_block {
float:left;
background-color: #383838;
padding: 10px;
width: 28%;
display: inline-block;
}
}
#media screen and (max-width: 799px){
#dark_block {
float:left;
background-color: #383838;
margin-top: 20px;
padding: 10px;
width: 100%;
min-height: 200px;
display: inline-block;
}
}
img {
max-width: 100%;
margin: 0px;
}
You need to read up on the CSS box model. The width of an element refers to its content. The padding, border and margin are then added it to it. That means your #dark_block is actually 100% + 2*10px wide.
The proper solution would be to set #dark_block to display: block and remove both floatand width. The default value for width is auto, which automatically makes the block as wide s possible without overflowing. Rule of thumb in web development: If you give a display: block element width: 100%, then you are doing something wrong.
Another simple solution would be to set box-sizing: border-box; on #dark_block, however box-sizing is a relatively new property, so it won't work if you need to support older browsers.
Getting them to the same height, is not a trivial thing. You could use the display: table-* properties, and give them height: 100% but that requires you to put #dark_block first in the HTML.
Quick example:
<div id="home_top_container">
<div>
<div id="dark_block"></div>
<div id="photo_slider">
<img src="http://caldwellfellows.ncsu.edu/wp/wp-content/uploads/2013/06/Justin-sews.jpg">
</div>
</div>
</div>
#home_top_container > div > div {
display: table-cell;
width: 50%;
border: 1px solid red;
}
img {
width: 100%;
}
Again centering vertically is not a trivial thing in CSS. Your best bet would be to use display: table-cell with vertical-align: middle.
Most certainly. Especially you should move all properties that are common to all media-variants to outside the media rules, so that you don't repeat them.
Also it's no need to repeat the media rules around each rule. Just have one media rule:
#media screen and (min-width: 800px) {
#photo_slider {
/* ... */
}
#dark_block {
/* ... */
}
}
#media screen and (max-width: 799px) {
#photo_slider {
/* ... */
}
#dark_block {
/* ... */
}
}