I guess this may have been asked a lot of times, but I've searched accross the forum and haven't find the answer for this case.
I've some divs "container" and some divs "item" all of them floated elements, and I want each "container" below the previous one.
I know I could achieve that without using floats on the containers. But I thought that using :after and clear: would be enough.
Why this doesn't work?
My code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="./style2.css">
</head>
<body>
<header></header>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
My CSS:
* {
margin: 0;
padding: 0;
}
header {
width: 100%;
min-height: 25px;
background-color: #444;
position: fixed;
overflow: auto;
}
.container {
float: left;
padding: 10px;
margin: 10px;
}
.container:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.item {
min-width: 50px;
min-height: 50px;
float: left;
background-color: lightblue;
border: 1px solid red;
margin: 5px;
}
Thank you
Just add clear:left to your .container rules
.container {
clear:left;
float: left;
padding: 10px;
margin: 10px;
}
jsFiddle example
You can use the clearfix approach by adding the .clearfix class to your .container divs:
.clearfix:before,
.clearfix:after{
content: " ";
display: table;
}
.clearfix:after{
clear: both;
}
<div class="container clearfix">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
With this approach, you don't need to float: left your .container, and also,
Clearfix it's going to help you each time a div has floated children by making it's height variable according to its children.
Another approach would be adding clear: left to your .container but I don't recommended it since it would be an specific approach solution.
Related
I make a 6 item column using the PHP loop, and I want to set the third child of each row border to none and I don't want to set the 3times in 2 rows because I want to show the theme center when the page is going smaller.
how to set the border to none for third child of each row(third child, 6th child, and ... 3*rownumber child)
<div class="full-container">
<div class="row">
<?php for($i=0;$i<6;$i++): ?>
<div class="document-item">
<a href="#">
<div class="document-img">
<img src="assets/images/book.jpg" alt="book"/>
</div>
<div class="document-detail text-middlegreen">
<h2>
<span class="parent-position">عنوان کتاب</span>
</h2>
<p>نام نویسنده</p>
<p>موضوع</p>
<p>تاریخ</p>
</div>
</a>
</div>
<?php endfor; ?>
</div>
</div>
.full-container {
width: calc(100% - 40px);
padding: 20px;
}
.row{text-align: center;}
.document-item{
width: calc(33% - 32px);
min-width: 300px;
border-left: 1px solid #5bbcb8;
margin-left: 30px;
display: inline-block;
margin-bottom: 30px;
margin-top: 30px;
}
.document-img{
width: 180px;
display: inline-block;
line-height: 100%;
text-align: center;
}
.document-img img{
width: 80%;
vertical-align: middle;
}
.document-detail{
display: inline-block;
vertical-align: middle;
}
.document-detail> h2{
margin: 10px 0;
}
.document-detail> h2>span{
font-size: 110%;
font-weight: bold;
}
.document-detail> h2>span::before{
content: '';
display: block;
width: 100%;
height: 1px;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: -2px;
background-color: #5bbcb8;
}
.document-detail> p:first-of-type{
font-size: 90%;
margin: 10px 0;
}
.document-detail> p:nth-last-of-type(2){
font-size: 90%;
margin: 10px 0;
}
.document-detail> p:last-of-type{
font-size: 90%;
margin: 10px 0;
}
is that any way to set multiplication of 3 of each element border to set none in CSS?
You can select every 3rd child using nth-child(3n).
.grid-wrapper {
display: grid;
grid-template-columns: repeat(3,1fr);
grid-gap: 20px;
}
.item {
width: 100%;
height: 50px;
background-color: red;
}
.item:nth-child(3n) {
background-color: blue;
}
<div class="grid-wrapper">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
or
You can use nth-child(3n+1) to select every 3rd child including the first one.
Like so:
.grid-wrapper {
display: grid;
grid-template-columns: repeat(3,1fr);
grid-gap: 20px;
}
.item {
width: 100%;
height: 50px;
background-color: red;
}
.item:nth-child(3n+1) {
background-color: blue;
}
<div class="grid-wrapper">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
I got the container, which width is the half of a page. That container includes several item collections (rows). Each row includes big amount of items. You can see only limited count of items, other ones can be discovered by horizontal scroll.
Please, see the snippet below.
.container {
width: 50%;
overflow-x: scroll;
overflow-y: hidden;
}
.items {
height: 100px;
background: #ccc;
white-space: nowrap;
}
.item {
display: inline-block;
width: 30%;
height: 50px;
background: #efc;
border: 1px solid;
}
.shadow {
outline: none;
border: 2px solid #3a53ed;
box-shadow: 0 0 10px #9ecaed;
}
<div class="container">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="items shadow">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
I have shadow class, which adds bright borders and shadow to an element. I want to be able to apply that class to any item collection (row). I mean, not only for visible part, but for the whole.
The problem is that width of a row element is equal to visible part. How can I make that width to be equal to the full long width (based on all items' width)?
UPDATE: layout (mostly) and scrolling behaviour should remain the same
Thank you.
I guess you not something like it.
.container {
width: 50%;
overflow-x: scroll;
overflow-y: hidden;
}
.items {
height: 100px;
background: #ccc;
white-space: nowrap;
}
.item {
display: inline-block;
width: 30%;
height: 50px;
background: #efc;
border: 1px solid;
}
.shadow {
outline: none;
border: 2px solid #3a53ed;
box-shadow: 0 0 10px #9ecaed;
}
<div class="container">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
<div class="items shadow">
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
The actual default behavior is buggy tbh, I would have assumed it would have worked as you intended it to from the get go.
Anyway, I don't think it's doable without javascript but I could be wrong.
The reason is that your item are of width: 30%, so if you changed the width of items to get the appropriate border, then the width of item would change as well.. See where I'm getting at ?
Having the shadow class on items is a no go, since even if we changed its width, it would change the width of contained items, so we have to put it somewhere else.
-
.shadow{
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
outline: none;
border: 2px solid #3a53ed;
box-shadow: 0 0 10px #9ecaed;
}
So with that out of the way, how would we give the correct width to shadow ? I don't think we can without js.
With some javascript you can grab the width of the container and apply it to a "shadow" div.
let ctnr = document.querySelector(".container");
let width = ctnr.scrollWidth;
let sel = document.querySelectorAll(".shadow");
sel.forEach( s => {
s.style.width = width + "px";
});
.container {
width: 50%;
overflow-x: auto;
overflow-y: hidden;
background: #ccc;
}
.items {
height: 100px;
white-space: nowrap;
}
.item {
display: inline-block;
width: 30%;
height: 50px;
background: #efc;
border: 1px solid;
}
.outer{
}
.sel{
position: relative;
}
.shadow{
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
outline: none;
border: 2px solid #3a53ed;
box-shadow: 0 0 10px #9ecaed;
}
<div class="container">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="items sel">
<div class="shadow"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
I'm trying to make a div stay at a fixed location inside another div. The containing div is scrollable and his location is not fixed in the screen.
This is what I got so far JSFiddle
The text "fixed text" should stay at the top right corner of the container when scrolling.
I made 2 copies of the div and kept the same class in order to simulate 2 different locations of the div.
Can it be done with CSS only?
HTML
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
CSS
.cont{
width: 400px;
height: 130px;
border: 1px solid black;
margin: 10px;
overflow-x: auto;
overflow-y: hidden;
position: relative;
}
.items{
width: 600px;
}
.item{
width: 80px;
height: 80px;
background-color: blue;
margin-top: 22px;
margin-left: 3px;
display: inline-block;
}
.txt{
position: absolute;
top: 2px;
right: 10px;
}
You can use overflow: auto on items instead of cont element.
.cont {
width: 400px;
height: 130px;
border: 1px solid black;
margin: 10px;
overflow-x: hidden;
position: relative;
}
.items {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
.item {
width: 80px;
height: 80px;
background-color: blue;
margin-top: 22px;
margin-left: 3px;
display: inline-block;
}
.txt {
position: absolute;
top: 2px;
right: 10px;
}
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
Create an extra wrapper and apply height and overflow to that - I have added a div inner wrapping all the contents of cont and applied this to it:
.inner {
overflow-x: scroll;
overflow-y: hidden;
height: inherit;
}
See demo below to see what I mean:
.cont {
width: 400px;
height: 130px;
border: 1px solid black;
margin: 10px;
/*overflow-x: auto;*/
/*overflow-y: hidden;*/
position: relative;
}
.items {
width: 600px;
}
.item {
width: 80px;
height: 80px;
background-color: blue;
margin-top: 22px;
margin-left: 3px;
display: inline-block;
}
.txt {
position: absolute;
top: 2px;
right: 10px;
}
.inner {
overflow-x: scroll;
overflow-y: hidden;
height: inherit;
}
<div class="cont">
<div class="inner">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
</div>
Add the fixed height and overflow to .items instead, so that .items scrolls instead of .cont, and .txt will stay where it is since it is positioned relative to .cont and .cont isn't scrolling.
.cont{
width: 400px;
border: 1px solid black;
margin: 10px;
overflow-x: auto;
overflow-y: hidden;
position: relative;
}
.items{
width: 600px;
height: 130px;
overflow: scroll;
}
.item{
width: 80px;
height: 80px;
background-color: blue;
margin-top: 22px;
margin-left: 3px;
display: inline-block;
}
.txt{
position: absolute;
top: 2px;
right: 10px;
}
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
I have the following requirement.
The green colored parent width will be varying depending on device width. I need all the boxes to be in the center of the parent.
I have tried the following things already, but it didnt help me.
Trial 1
Parent {text-align:center} box {display:inline-block}.
This resulted in following output
Trial 2
Parent {text-align:center} box{float:left}.
This resulted in following output
Trial 3
Parent {display:flex} box -> justify-around & justify-between also didn't work.
.parent {
text-align: center;
}
.item {
display: inline-block;
width: 100px;
height: 100px;
background: red;
}
<div class="parent">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Any help on this will be appreciated.
Without Javascript this very hard using floats &/or inline-block.
Flexbox offers some hope but even then some creativity is required.
Essentially, provided the maximum number of elements "per row" is known you can create a required number of invisible elements which can be ustilised in conjunction with justify-content:center to acheieve the last line appearance you require by essentially pushing the last line content back over to the left.
Codepen Demo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.parent {
text-align: center;
border: 1px solid grey;
width: 80%;
max-width: 800px;
margin: 1em auto;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.item {
width: 100px;
height: 100px;
margin: 10px;
background: red;
}
.balancer {
height: 0;
width: 100px;
margin: 0 10px;
visibility: hidden;
}
<div class="parent">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="balancer"></div>
<div class="balancer"></div>
<div class="balancer"></div>
<div class="balancer"></div>
</div>
Got it working by using jQuery and adding a #wrapper.
All you've got to do is calculate how many items will fit on one row. Then you set the wrapper to the exact width that is needed to fit these items.
I hoped it could be done in pure CSS, but as far as I know there is no Math.floor() equivalent for CSS.
Example:
function fitItemsOnRow() {
var windowWidth = $(window).width();
var itemWidth = $(".item").outerWidth(true);
var itemAmount = Math.floor((windowWidth / itemWidth));
if(itemAmount > $(".item").length) {
/* Set the maximum amount of items */
itemAmount = $(".item").length;
}
var rowWidth = itemWidth * itemAmount;
$("#wrapper").width(rowWidth);
}
$(window).resize(function() {
/* Responsive */
fitItemsOnRow();
});
$(document).ready(function() {
fitItemsOnRow();
});
body {
margin: 0px;
}
#parent {
background: #75DB3C;
min-width: 100vw;
min-height: 100vh;
text-align: center;
}
#wrapper {
display: inline-block;
text-align: left;
font-size: 0px; /* Removes default margin */
}
.item {
display: inline-block;
margin: 12px;
width: 100px;
height: 100px;
background: #0B56A9;
}
<div id="parent">
<div id="wrapper">
<!-- A wrapper is necessary to center the items -->
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
You can do this with css selector "nth-of-type(n)"
<div class="parent">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
and css here
.parent
{
display: block;
width: 980px;
padding: 10px 50px;
background: green;
box-sizing: border-box;
}
.parent::after
{
content: '';
display: block;
clear: both;
}
.item
{
float: left;
width: 24%;
margin-right: 1.25%;
margin-bottom: 1.25%;
/*
note
you may need min height , height or overflow:hidden
*/
}
.item:nth-of-type(4n)
{
float: right;
margin-right: 0;
}
I write a sample code in jsfiddle
I want exactly this Result but the Sidebar in HTML appear in bottom of code, like this:
<div class="wrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="sidebar"></div> <---- coming bottom for SEO
</div>
see jsfiddle,
Green box (Sidebar)
Gray box (Posts)
I found my Question , thanks #David for dummy idea, I use 2 big margin-right
http://jsfiddle.net/yazdi/MUU4V/9/
This is sort of a hack way to do this, but it does work, so it's worth saying.
You can manipulate the sidebar's position since we know the exact height of it.
I started off by floating the items to the left:
.item{
float: left;
}
This put the sidebar on the right side.
Next I added 2 more items as a placeholder for the sidebar. To these, I assigned the .dummy class just to distinguish them in the code:
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item dummy"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item dummy"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="sidebar"></div>
They are inserted at the 4th and 8th positions because that is where the sidebar is meant to be.
Finally, I used relative positioning to move the sidebar up 399px.
.sidebar {
float: right;
width: 90px;
height: 263px;
background-color: green;
margin-left: 3px;
position: relative;
top: -399px;
}
JSFiddle
Edit:
Actually in hindsight, it is not necessary to float the items to the left. It works both ways.
Other JSFiddle
Another Edit:
Since you pointed out that you do not have a static height, another approach would be to use absolute positioning inside a relative container. Since your rectangles are already nicely placed inside a container (.wrap), we can just assign relative positioning to that and force the sidebar to the top of the container:
.wrap
{
position: relative;
}
.sidebar
{
position: absolute;
top: 0;
}
This does still require the dummy items to work.
Yet Another JSFiddle
Here was my first reaction:
fiddle
HTML
<div class="wrap">
<div class="inner-wrapper">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item last-item"></div>
</div>
<div class="sidebar"></div>
</div>
CSS
.wrap {
position: relative;
width: 372px;
margin: 0 auto;
direction:rtl;
overflow: hidden;
}
.inner-wrapper {
float: left;
width: 280px;
}
.item {
float: right;
width: 90px;
height: 130px;
list-style: none;
background-color: #ccc;
margin: 0 0 3px 3px;
}
.sidebar {
position: absolute;
top: 0;
right: 0;
width: 90px;
height: 263px;
background-color: green;
margin-left: 3px;
}
.last-item {
position: absolute;
right: 0;
bottom: 0;
}
I found my Question , thanks #David for dummy idea, I use 2 big margin-right
http://jsfiddle.net/yazdi/MUU4V/9/
HTML
<div class="wrap">
<div class="item margin">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item margin">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="sidebar"></div>
</div>
css
.wrap {
width: 372px;
margin: 0 auto;
direction:rtl;
position: relative;
}
.item {
float: left;
width: 90px;
height: 130px;
list-style: none;
background-color: #ccc;
margin: 0 0 3px 3px;
}
.sidebar {
float: right;
width: 90px;
height: 263px;
background-color: green;
margin-left: 3px;
position: absolute;
top: 0px;
}