So basically i have this markup
<div class="container">
<article>1</article>
<article>2</article>
<article>3</article>
<article>4</article>
<article>5</article>
<article>6</article>
</div>
How will i be able to have alternate width for the first & second div per row?
I tried article:nth-child+ diff stepping to target alternate divs, but i cant find the right combination of stepping
Edit: I really can't edit the HTML structure since this is a WordPress plugin output
You will need to use :nth-child() selector here...
Actually here the pattern is repeating itself after every 4th element...So you will need to taregt 4n, 4n+1, 4n+2 and 4n+3
.container {
display: flex;
flex-wrap: wrap;
}
article {
display: flex;
align-items: center;
justify-content: center;
height: 100px;
border: 5px solid #fff;
background: gray;
box-sizing: border-box;
color: #fff;
font: bold 20px Verdana;
}
article:nth-child(4n),
article:nth-child(4n+1) {
width: 25%
}
article:nth-child(4n+2),
article:nth-child(4n+3) {
width: 75%
}
<div class="container">
<article>1</article>
<article>2</article>
<article>3</article>
<article>4</article>
<article>5</article>
<article>6</article>
<article>7</article>
<article>8</article>
<article>9</article>
<article>10</article>
<article>11</article>
<article>12</article>
</div>
you should apply class for correct adjustment of articles use only two class with width 66% and 33%
1
2
3
4
5
6
article
{
float:left;
height:50px;
width: 30%;
background: #444;
margin: 0 0 5px 0;
}
article:nth-child(2n) {
background: #f0f;
width: 70%;
float: right;
}
article:nth-child(3n) {
width: 70%;
}
article:nth-child(4n) {
width: 30%;
float: right;
}
You can use flexbox. With display: flex;flex-wrap: wrap; on ".container" and flex-grow: 1;flex-shrink:1; on article. The article will get the width based on the content.
With flexbox you can do anything, here is a good tutorial https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Related
I have a container, in my case the body and html tags are the containers. And then I have 3 divs in them and I want the last one to fill the remaining vertical space available while still having a margin.
The third div is generated dynamically so I can't predict what height it's gonna need. The problem is, if it grows too much and a scrollbar is required, the bottom-margin it used to have goes away too. If a scrollbar is NOT required and doesn't appear, the margin is still there and everything looks like I want it to.
I tried to draw what I meant as best as I could in the above image. The 1st case is what I want to happen all the time, regardless of whether there's a scrollbar or not. The 2nd picture is what actually happens, the blue div loses its bottom margin, despite having it set.
Here's my CSS for the html and body tags (they contain the 3 divs, including the blue one):
html,
body
{
width: 100%;
height:100%;
margin: 0px;
padding: 0px;
display: flex;
flex-direction:column;
align-items: center;
background: #494d5f ;
}
and here's my code for the 3rd div, the blue one:
.bottomDiv
{
display:flex;
flex-direction:column;
background: #a0d2eb ;
align-items: center;
width: 97%;
margin-bottom:1.5%;
flex: 1 1 auto;
padding-top:1%;
padding-bottom:1%;
}
Maybe I didn't clarify well enough but the 3rd div in my case, the blue one grows just like it should, fully obeying its margins UNTIL a scrollbar appears and is needed. No matter the amount of growth it has to do, it does it perfectly while respecting its margin. But if it has to grow "out of bounds" of the page so to say, as in, a scrollbar is needed to display all the webpage then its margin is simply gone. IF there is NO scrollbar, everything looks perfect.
Just change this line: body { height: 100%; } to: body { min-height: 100vh; }.
With that line the body will have a height of at least the screen height (100vh) but allows i proper overflow as it is allowed to eb alrger then the screen. As such the margins wont get removed.
html,
body {
width: 100%;
min-height: 100vh;
margin: 0px;
padding: 0px;
display: flex;
flex-direction: column;
align-items: center;
background: #494d5f;
}
.topDiv,
.midDiv {
width: 97%;
height: 50px;
}
.topDiv {
margin-top: 1.5%;
background-color: red;
}
.midDiv {
background-color: blue;
}
.bottomDiv {
display: flex;
flex-direction: column;
background: #a0d2eb;
align-items: center;
width: 97%;
margin-bottom: 1.5%;
flex: 1 1 auto;
padding-top: 1%;
padding-bottom: 1%;
}
#height:checked + label::after {
content: "";
display: block;
height: 150vh;
}
<div class="topDiv"></div>
<div class="midDiv"></div>
<div class="bottomDiv">
<input type="checkbox" id="height" name="height">
<label for="height">checkmark me to extend box height</label>
</div>
I've put an example, so you may try this approach:
body,
html {
margin: 0;
padding: 0;
}
#page {
display: flex;
flex-direction: column;
height: 100vh;
outline: 1px solid purple;
}
#header {
height: 30px;
outline: 1px solid red;
}
#middle {
flex-grow: 1;
/* height: 100vh; */
/* flex-direction: column; */
outline: 1px solid green;
}
#footer {
outline: 1px solid blue;
}
<div id="page">
<div id="header">...</div>
<div id="middle">...</div>
<div id="footer">...</div>
</div>
Try to remove #footer and see that #middle fills the entire screen till the end.
In addition if you need any margins so you have to modify the container like this: #page { ..., margin: 10px; height: calc(100vh - 20px); }
I am creating a responsive menu for a website, but I have a problem: The a tag (red color) is losing a couple of pixels when defining the 100% width of the div (blue color).
To notice the difference it is necessary to open the link of the Pen, use the Chrome inspector and select the red box. The width is shown with pixels less than 30 (example: 28.72, 27.60, etc.).
I have tried other HTML tags although the result has been the same. Why does it happen and what would be the optimal solution for the tag to keep the width and height at 30px, please?
Here the pen: https://codepen.io/Jnico/pen/RQaEoa
body {
padding: 0;
margin: 0;
}
.menu__container {
width: 100%;
background: black;
padding: 0 5px;
}
.menu {
width: 100%;
max-width: 1024px;
height: 55px;
margin: auto;
display: flex;
align-items: center;
}
.logo {
width: 30px;
height: 30px;
background: red;
display: inline-block;
}
.menu__buttons {
width: 100%;
background: blue;
margin-left: 15px;
display: flex;
justify-content: space-between;
}
.button {
padding: 6px 20px;
border: 1px solid #FFFFFF;
}
<nav class="menu__container">
<div class="menu">
<a class="logo"></a>
<div class="menu__buttons">
<a class="button">Button 1</a>
<a class="button">Button 2</a>
</div>
</div>
</nav>
Because of flexbox..
Add flex: 0 0 auto to your .logo so it doesn't flex at all an it should be fine ;) Also, you don't need display:inline-block there, as it's a flex-item already.
.logo {
width: 30px;
height: 30px;
background: red;
flex:0 0 auto;
}
When i set display to inline-table or table is ok and set 30*30
or you can set flex to 0 0 auto;
Either you can use flex-wrap: wrap to the flex container if you want that the flexible items will wrap if necessary.
Or you have to use flex-basis:30px to the <a>(No need to mention the width) and
flex-grow:1 to the .menu__buttons so that it can take the remaining width...
And remove width:100% from the .menu__buttons...No need
Updated Code
My best alternative was:
.logo {
min-width: 30px
}
Because "min" can be used without interrupting my receptive system with fixed pixels or by adding extensive code.
I have 3 elements in HTML as follows:
.navigation {
display: inline-block;
width: 25%;
}
.content {
display: inline-block;
width: 50%;
}
.sidebar {
display: inline-block;
width: 25%;
}
<nav class="navigation">Navigation</nav>
<section class="content">Section</section>
<aside class="sidebar">Aside</aside>
This should fit in the 100% width of the container (<body> or any other <div>). However the .sidebar is being dropped to the next line. I tried to setup border, margin and padding to 0 with the !important definition (just to test) but the result is the same. How can I fit this 3 elements in the same line keeping the width property?
Thanks in advance for your answers.
As someone else mentioned, the issue is that when using display: inline-block, white-space - even between element tags - is accounted for in rendering. There are a few ways to get around this.
Setting display: table-cell rather than inline-block can work in a simple situation like this; just note that it prevents the blocks from wrapping
You can set font-size:0; on the parent to get rid of the whitespace, but you'll have to reset it on all the direct children.
Unless you have to support pre-IE10 browsers, I'd recommend flexbox here! You may need to add some browser prefixes, but the base would look like this (name your parent element something better than 'parent', though!):
.parent { display: flex; }
.navigation, .sidebar { flex: 1 }
.content { flex: 2 }
What that snippet is saying is "make the children fit, and make .content twice as big as the other two".
Even though you removed the padding, margin, and border, inline elements are actually sensitive to white space in the code itself. Remove that and they line up:
.navigation {
display: inline-block;
width: 25%;
}
.content {
display: inline-block;
width: 50%;
}
.sidebar {
display: inline-block;
width: 25%;
}
* {
margin: 0;
padding: 0;
border: 0;
}
<nav class="navigation">Navigation</nav><section class="content">Section</section><aside class="sidebar">Aside</aside>
When you're using display inline-block, it takes the space in your code as a character(space), so, you have 100% + the space required for 2 characters, you could keep the formatting of your code and ¨remove¨ the space between your containers setting the font-size of the parent to 0
.container{
font-size:0;
}
.container *{
font-size:12px;
}
.navigation {
display: inline-block;
width: 25%;
}
.content {
display: inline-block;
width: 50%;
}
.sidebar {
display: inline-block;
width: 25%;
}
<div class="container">
<nav class="navigation">Navigation</nav>
<section class="content">Section</section>
<aside class="sidebar">Aside</aside>
</div>
It's because you're using the style of display:inline-block which will recognize and create a space between element if your code have a space (either space, or new line), so what you need to do is just remove the space like answered by j08691 here
Or you can either remove the spacing by using a comment like this one
.navigation {
display: inline-block;
width: 25%;
}
.content {
display: inline-block;
width: 50%;
}
.sidebar {
display: inline-block;
width: 25%;
}
<nav class="navigation">Navigation</nav><!--
--><section class="content">Section</section><!--
--><aside class="sidebar">Aside</aside>
Or other way around is using the style margin like in this example, the background is used to visualize the size of the the inline-block element only
.navigation {
display: inline-block;
width: 25%;
margin: 0 -0.4em 0 0; background: red;
}
.content {
display: inline-block;
width: 50%;
margin: 0 -0.4em 0 0; background: green;
}
.sidebar {
display: inline-block;
width: 25%;
margin: 0 -0.4em 0 0; background: blue;
}
<nav class="navigation">Navigation</nav>
<section class="content">Section</section>
<aside class="sidebar">Aside</aside>
Hi this is probably easier to explain with an image. I'm using foundation 6 to make a layout with a banner. The layout looks like this:
The issue I have is that I don't know how to do a pure CSS solution to get box 1, 2, 3 etc a third (with margins) of the responsive image. I can do it no problem with a few lines of jquery but I can't help but think this isn't really the best / fastest solution.
Like I said i'm using foundation 6 so happy to use flexbox to get it sorted if that's a way of doing it but so far my experimentation has failed.
I can post the code I have so far but I don't think it's particularly helpful since getting a layout like this easy it's just the height on the grey boxes doesn't extend the full height.
Thanks for any help
General
viewport measurements vw vh
percentage measurements
The outer container:
display: table
min-width: fit-content
Left
background-image background-repeat (in shorthand)
background-size
display: table-cell
Right is flexbox
display: flex
flex-flow: row wrap
align-content: space-between
Snippet
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>flexSeries3</title>
<style>
#main { min-width: -moz-fit-content; min-width: -webkit-fit-content; min-width: fit-content; height: auto; overflow: hidden; display: table; table-layout: fixed; }
.iImg { width: 49vw; height: 96vh; display: table-cell; background: url(https://cdn0.vox-cdn.com/thumbor/xH2LQ-c4CZJp6X-Iv27s7kvDRts=/cdn0.vox-cdn.com/uploads/chorus_asset/file/4106218/GettyImages-489748146_master.0.jpg) no-repeat; background-size: contain; background-position: center; outline: 3px ridge #999; }
.iFlex { display: flex; flex-flow: row wrap; align-items: center; align-content: space-between; width: 49vw; height: 96vh; background: #fff; }
.fBox { width: 48%; height: 32%; background: #777; margin: 1%; }
.fFoot { width: 98%; height: 32%; background: #777; margin: 1%; }
#f1 { order: 1; }
#f2 { order: 2; }
#f3 { order: 3; }
#f4 { order: 4; }
#f5 { order: 5; }
</style>
</head>
<body>
<main id="main">
<section class="iImg">
</section>
<section class="iFlex">
<div id="f1" class="fBox">1</div>
<div id="f2" class="fBox">2</div>
<div id="f3" class="fBox">3</div>
<div id="f4" class="fBox">4</div>
<div id="f5" class="fFoot">5</div>
</section>
</main>
</body>
</html>
I'm playing with css3's flexbox in Chrome (no need to worry about cross-browser for this). I'm having a hard time convincing it to lay out my content the way I'd like. Here's a sketch of my goal:
Here's a jsFiddle of my attempt: http://jsfiddle.net/Yht4V/2/ This seems to work great except each .group will expand its height rather than create multiple columns.
I'm using flexbox pervasively here. The body lays out vertically, with the #content div taking the remaining height of the page. Each .group is laid out horizontally. Finally, each .item is laid out within a .group vertically with wrapping.
Unfortunately, each .group ends up as a single column by expanding the #content height, which causes a vertical scrollbar (unwanted). If I set the height of each .group to a fixed pixel size, the items break out into multiple columns, but this defeats the fluidity of the flexbox. Here's what it looks like with fixed heights: http://jsfiddle.net/Yht4V/3/
So, how can I get my #content div to not expand vertically since everything is managed with flexboxes without setting a fixed height? I was expecting the flexbox to trigger more columns instead of expanding the height of its parent and causing a scrollbar.
From what I've seen with the Chrome and Opera implementations for Flexbox, a flex-direction of column requires restricting the height of the element, otherwise it will continue expanding vertically. It doesn't have to be a fixed value, it can be a percentage.
That said, the layout you want for your .group elements can also be achieved by using the CSS Columns module. The flow of the elements will be similar to that of the flexbox column orientation, but it will create columns as long as there's enough width for them, regardless of how long the document is.
http://jsfiddle.net/Yht4V/8/ (you'll have to excuse the lack of prefixes)
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
h1 {
padding: 1em;
}
#content {
padding: 10px;
background-color: #eee;
display: flex;
flex-grow: 1;
}
#content > .group {
margin: 10px;
padding: 10px;
border: 1px solid #cfcfcf;
background-color: #ddd;
flex: 1 1 auto;
}
#content > .group:first-child {
columns: 10em;
flex-grow: 2;
}
#content > .group .item {
margin: 10px;
padding: 10px;
background-color: #aaa;
break-inside: avoid;
}
#content > .group .item:first-child {
margin-top: 0;
}
Leaving it as a bunch of nested flexboxes, this was about as close as I could get it:
http://jsfiddle.net/Yht4V/9/ (again, no prefixes)
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
h1 {
padding: 1em;
}
#content {
padding: 10px;
background-color: #eee;
display: flex;
flex: 1 1 auto;
height: 100%;
width: 100%;
}
#content > .group {
margin: 10px;
padding: 10px;
border: 1px solid #cfcfcf;
background-color: #ddd;
display: flex;
flex-flow: column wrap;
flex: 1 1 30%;
max-height: 100%;
}
#content > .group .item {
margin: 10px;
padding: 10px;
background-color: #aaa;
}
Replace the following in your css -
display: -webkit-flex;
to the following -
display: -webkit-box;
This worked very well for me :-)