So, I have a line of inline elements that adjusts based on the width of the window, like so for example:
[a][b][c][d][e] -- 1000px
[a][b][c]
[d][e] -- 600px
This makes sense, and is what is expected of inline elements. However, I want to know if it's possible to make it do this:
[d][e]
[a][b][c]
or even
[a][b]
[c][d][e]
The reason I want this is because I have content below the row of inline elements, and when it breaks into two rows, having the top row be wider than the bottom row looks really bad.
Thanks.
Here's a fiddle:
http://jsfiddle.net/6Hm4C/1/
Notes:
Window width, element width and number of elements are all dynamic.
It has to work in IE9+ and FF24+, if this isn't possible FF has priority.
How about using a "breaker" container like this?
<div id="container">
<div class="breaker">
<div class="box">Box 1 Bigger</div>
<div class="box">Box 2</div>
</div>
<div class="breaker">
<div class="box">Box 3 Random</div>
<div class="box">Box 4</div>
<div class="box">Box 5 Stuff</div>
</div>
</div>
And this CSS:
.breaker { display: inline-block; }
.box {
display: inline-block;
vertical-align: top;
}
This will break [a][b][c][d][e] into
[a][b]
[c][d][e]
Now, in order to account for a dynamic number of boxes and widths, you need to use Javascript. With jQuery, you could do it like this:
function betterBreak(container) {
var boxes = $(container).children(),
sum = 0, max = 0;
boxes.map(function(x, box) { max += $(box).outerWidth(); });
boxes.each(function(x, box) {
sum += $(box).outerWidth();
if(sum > max/2) {
var breakerBig = $('<div class="breaker"></div>'),
breakerSmall = $('<div class="breaker"></div>');
boxes.slice(x).appendTo(breakerBig);
boxes.slice(0,x).appendTo(breakerSmall);
$(container).append(breakerSmall).append(breakerBig);
return false;
}
});
}
Calling betterBreak('#container') on a Container element that has an unknown number of child element "boxes" will dynamically wrap the children in 2 breaker divs that split the line into the desired layout when going to 2 rows.
Adjusted Demo: http://jsfiddle.net/pyU67/8/
You could use writing-mode as i commented , but for younger browser, Firefox seems out :http://codepen.io/gc-nomade/pen/DCqLb/
body {
counter-reset: boxe;/* demo purpose */
/* reverse flow from bottom to top */
writing-mode:lr-bt;
-webkit-writing-mode: horizontal-bt;
-moz-writing-mode: horizontal-bt;/* fails */
-o-writing-mode: horizontal-bt;
writing-mode: horizontal-bt;
}
/* demo purpsose */
b {
display:inline-block;
line-height:3em;
width:8em;
text-align:center;
background:lime;
border-radius:1em;
margin:1em;
}
b:before {
counter-increment:boxe;
content:counter(boxe) ' ';
}
HTML use in body
<b> inline-box </b>
<b> inline-box </b> <!-- and so many more -->
From your fiddle , it does : http://jsfiddle.net/6Hm4C/3/ or just the spans http://jsfiddle.net/6Hm4C/4/
To test in IE, Safari, Opera, Chrome, and fails in FF :(
You could try to add a divider like so:
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="divider"></div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
</div>
and use media screen:
.divider { display: none; }
#media screen and (max-width: 600px) {
.divider {
clear: both;
display: block;
}
}
Example
I'm open to either CSS or jquery. – #Surgery
Answer using Javascript / jQuery
I have created a fiddle which creates a mirror HTML of what happens when the elements are shifted downwards.
Here is an image example:
Demo fiddle
HTML
<div id="first">
<div class="inp">aaaa</div>
<div class="inp">b</div>
.
.
</div>
<!-- Below part to generate mirror code of the above -->
<div id="wrap">
<div id="second">
</div>
</div>
Javascript / jQuery
var actual = $('#first');
var mirror = $('#second');
$('#wrap').css({'top':''+actual.offset().top+'px'});
$(window).resize(function(){
var frag = document.createDocumentFragment();
var ele='div';
var wrp = actual.height()+actual.offset().top;
$('#first .inp').each(function(){
var creEle = document.createElement(ele);
creEle.className="inp";
creEle.innerHTML = $(this).html();
creEle.style.position = "absolute";
var diff = wrp - ($(this).height()+$(this).offset().top);
creEle.style.top = diff+"px";
creEle.style.left = $(this).offset().left-actual.offset().left+"px";
frag.appendChild(creEle);
});
mirror.html(frag);
});
$(window).trigger('resize');
CSS
html,body,#first,#second{
width:100%;
height:auto;
}
#first{
visibility:hidden;
}
#wrap{
position:absolute;
}
#second{
position:relative;
}
.inp{
display:inline-block;
border:1px solid black;
margin-right:3px;
}
Use flex container with flex-wrap: wrap-reverse:
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap-reverse;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-end; // or flex-start
}
Related
Using FlexBox and Sass, I am trying to create stacked vertical bars as shown in the images pasted below. What I am expecting is the vertical text to take up the one-columned row, creating a stacking effect. What is happening, though, is the text is overlapping.
The html mark up is like so:
<div class="container__row">
<div class="container__col-sm-12 container__col-md-6 container__col-md-6">
<h1>Another section</h1>
</div>
<div class="container__col-sm-12 container__col-md-6 container__col-md-6">
<div class=container__row>
<div class="container__col-sm-12 container__col-md-12 container__col-md-12 skills-bar">
Front-End Technologies
</div>
</div>
<div class=container__row>
<div class="container__col-sm-12 container__col-md-12 container__col-md-12 skills-bar">
Front-End Technologies
</div>
</div>
<div class=container__row>
<div class="container__col-sm-12 container__col-md-12 container__col-md-12 skills-bar">
Design
</div>
</div>
<div class=container__row>
<div class="container__col-sm-12 container__col-md-12 container__col-md-12 skills-bar">
GIS
</div>
</div>
</div>
<div class="container__row">
This is the Sass .scss code that makes up the css styling:
//site container with set max width
$grid__bp-md: 768;
$grid__bp-lg: 992;
$grid__cols: 12;
//sass map to define breakpoints
$map-grid-props: ('-sm':0, '-md': $grid__bp-md, '-lg' : $grid__bp-lg);
//mixin to dynamically create media query for each breakpoint
#mixin create-mq($breakpoint) {
#if($breakpoint == 0) {
#content;
} #else {
#media screen and (min-width: $breakpoint *1px) {
#content;
}
}
}
#mixin create-col-classes($modifier, $grid__cols, $breakpoint) {
#include create-mq($breakpoint) {
//class to set up columns for all screen sizes - mobile first
#for $i from 1 through $grid__cols {
&__col#{$modifier}-#{$i} {
flex-basis: (100 / ($grid__cols / $i)) * 1%;
}
}
}
}
.container {
max-width: $grid__bp-md * 1px;
margin: 0 auto;
//attribute to override max width
&--fluid {
margin: 0;
max-width: 100%;
}
//attribute to position row's child elements. remove overflow with wrap and 100% width for nesting
&__row {
display: flex;
flex-wrap: wrap;
width: 100%;
}
#each $modifier, $breakpoint in $map-grid-props {
#include create-col-classes($modifier, $grid__cols, $breakpoint);
}
}
p {
font-size: .85em;
color: #aaa;
}
}
.skills-bar {
transform: rotate(90deg);
transform-origin: left top 0;
float: left;
}
There is this strange overlap that happens. Can anyone suggest why the vertical text won't make rows?
If you look in the inspector, you can see that the original height of the container isn't being effected by the transform and that's why this is happening. I can't think of a way around it without measuring the new height after the transform with js.
I'm not sure what browsers you need to support, but text-orientation / writing-mode will do, mostly, what you need without js.
.skills-bar {
writing-mode: sideways-lr; // only supported in FF, use 'vertical-lr' for more support
text-orientation: upright;
float: left;
}
https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode
https://developer.mozilla.org/en-US/docs/Web/CSS/text-orientation
In order to measure the divs after the css transform, I used getBoundingClientRect().
With a few lines of jquery, I got what I needed:
$(document).ready(function(){
var skills = $(".skills-bar")
$.each(skills, function(i, div) {
console.log(div);
var dimensions = div.getBoundingClientRect();
console.log(dimensions);
$(this).css("width", dimensions.width).css("height", dimensions.height);
});
});
I want to put checkbox inside a div tag. I want to create like
but the result that I get was like
the checkbox position should be at the right.
Create a containing div, then add three floating divs, one per element; Media element, text element, then check box. clear your float within the containing div. Place the check box in the far left div. Adjust CSS as needed.
Here is a working fiddle Check out the fiddle
#media_cont {
height:200px;
box-shadow:0px 0px 5px #000;
border-radius:10px;
padding:5px;
}
.media_content {
float:left;
width:33%;
text-align:center;
}
#checkbox {
margin-top:15%;
}
.clear {
clear:both;
}
.container {
padding-top:10px;
}
<div id="media_cont">
<div class="media_content"><img src="#" width="200" height="200"></div>
<div class="media_content">
<div>
<h2 class="header">
John Doe
</h2>
<h4 class="header">
User Profile 1
</h4>
</div>
</div>
<div id="checkbox" class="media_content"><input type="checkbox" checked></div>
<div class="clear"></div>
<div class="container">
<p>
New section
</p>
</div>
</div>
UPDATE: If you wish to have the check box clicked, simply add some JQuery such as the following:
$(document).ready(function() {
$("#profile").click(function() {
$('input[type="checkbox"]').attr("checked", "checked");
});
});
Then add the call id profile to your containing divs class.
<div id="profile" class="profile">
Here is an updated fiddle:
Click inside div and append checked into input field
Try the following:
.myDiv{
position: relative;
}
.myCheckbox {
position: absolute:
top: 50px; /* you compute this properly */
right: 15px; /* you compute this properly */
}
use awesome bootstrap checkbox
http://flatlogic.github.io/awesome-bootstrap-checkbox/demo/
i wonder how it is possible to have multiple spans inside a div, with the last span floating to the bottom right and taking all the remaining width in the "row".
Here is a fiddle: http://jsfiddle.net/gpakL/
The problem is, that the fullWidth span is not always at the bottom. You can resize your browser window to see the fullWidth span moving.
This is how it should look like:
This is how it shold not look like:
HTML:
<div class="container">
<span class="item">sdfdsfsdf</span>
<span class="item">sdfsdfsdfsdf</span>
<span class="item">dsfdsfdsfsd</span>
<span class="item">fsdfsdfsdffsdf</span>
<span class="item">dsgsdf</span>
<span class="item">dfd</span>
<span class="item">fdfdf</span>
<span class="itemFullWidth">FullWidth</span>
</div>
CSS:
.container {
background-color: blue;
width: 50%;
}
.item {
float: left;
background-color: orange;
height: 30px;
line-height: 30px; /* Vertically center */
margin: 5px;
}
.itemFullWidth {
background-color:green;
display: block;
overflow: hidden;
height: 30px;
line-height: 30px; /* Vertically center */
margin: 5px;
min-width: 80px;
}
If you open to use flexbox, it could be easily done (WebKit demo):
.container {
display: flex;
flex-wrap: wrap; /* allow multiple rows */
}
.container > :last-child {
flex: 1; /* absorb remaining space */
}
check this,
Using position: relative; for the container and position: absolute; for the
.itemFullWidth, you can get it to work to some extent. You'll need some js I guess.
You could consider a JavaScript/jQuery assisted solution for this problem. In a more general case, there are jQuery packages like David DeSandro's Masonry or Packery or Isotope: http://desandro.com/
Here is my version of how you could do this using jQuery.
function resetEndItemWidth() {
var wContainer = $(".container").width();
var minWidthEndItem = parseInt($(".itemFullWidth").css("min-width"));
var endItemMargins = $(".itemFullWidth").outerWidth(true)
- $(".itemFullWidth").outerWidth();
var prevItemOffset = $(".itemFullWidth").prev().offset();
var prevItemWidth = $(".itemFullWidth").prev().outerWidth(true);
var freeWidth = wContainer - (prevItemWidth + prevItemOffset.left);
if (freeWidth < minWidthEndItem) {
newWidth = wContainer - endItemMargins;
} else {
newWidth = Math.max(minWidthEndItem,freeWidth);
}
$(".itemFullWidth").width(newWidth);
}
resetEndItemWidth();
$(window).resize(function(){resetEndItemWidth();});
See the demo at: http://jsfiddle.net/audetwebdesign/m6bx8/
How This Works
I look at the floated sibling before the last item (.itemFullWidth) and determine the amount of free space remaining on the line.
If there is enough free space, I reset the width of the full width item to fill the gap,
otherwise, the full width item is on a separate line and I set it to the width of the parent container.
For full width item (.endItemMargins), you need to account for the left-right margins and you need to get the minimum width from the min-width property.
The min-width requirement could be relaxed if you initialize the original with of the full width item.
Other Comments
The flex box solution is much more elegant. However, it is good to have some options.
Simple jQuery solution, however CSS solutions should be preferred over JS solutions.
http://jsfiddle.net/A8mSu/
HTML:
<div class="container clearfix">
<span class="item">sdfdsfsdf</span>
<span class="item">sdfsdfsdfsdf</span>
<span class="item">dsfdsfdsfsd</span>
<span class="item">fsdfsdfsdffsdf</span>
<span class="item">dsgsdf</span>
<span class="item">dfd</span>
<span class="item">fdfdf</span>
<span class="item itemFullWidth">FullWidth</span>
</div>
JS:
function setWidth()
{
$obj = $('.container .itemFullWidth');
$obj.width('auto').width($obj.parent().width() - $obj.position().left);
}
$(window).resize(setWidth);
$(document).ready(setWidth);
CSS:
.container {
background-color: blue;
width: 50%;
}
.item {
float: left;
background-color: orange;
height: 30px;
line-height: 30px; /* Vertically center */
margin: 5px;
}
.itemFullWidth {
background-color: green;
min-width: 80px;
margin-right: 0;
}
.clearfix:after {
content:"";
display: table;
clear: both;
}
try , Please Checkout http://jsfiddle.net/gpakL/14/
function findWidth (){
var ConWidth = $('.container').width();
var leftWidth = $('.container .item:last').offset().left
var lastItemWidth = $('.container .item:last').width();
var fixPos = ConWidth - (leftWidth + lastItemWidth)
$('.container .itemFullWidth').width( fixPos -20 );
};
$(document).ready(function(){
findWidth();
});
$(window).resize(function(){
findWidth();
});
My code :
<div>
<div class='top-class'>
Header Name
</div>
<div class='body-class'>
This is body a
</div>
</div>
<div>
<div class='top-class'>
Another Header Name
</div>
<div class='body-class'>
Another body
</div>
</div>
css code I tried:
.top-class:hover + .body-class { display: block; } /* This is working */
But, I want that to happen when header is clicked. So, i tried this:
.top-class:visited + .body-class { display: block; } /* DIDNT work */
The pseudo class "active" seems to do the job
.top-class:active + .body-class { display: block; background-color: red; }
You can check my jsfiddle
You can use tabindex in you first div then it can have focus event on.
<div class='top-class' tabindex=1>Header Name</div>
Then in css you test focus pseudo class
.top-class:focus + .body-class { display: block; background-color: red; }
Check this jsfiddle
I have searched the web for this one but didn't find anything similar.
Say we have div A and div B. When hover on div A, div b should be visible ON (should look like overwriting) div A and not placed under.
It should appear like only the content of div A has changed to content of div B.
How can this be done in pure CSS and HTML?
#container > div {
display: none
}
#container > div:first-child {
display: block
}
#container > div:hover + div {
display: block
<div id="container">
<div>A</div>
<div>B</div>
</div>
This will work, but only if the two divs are adjacent and b follows a.
#a:hover + #b {
background: #f00
}
<div id="a">Div A</div>
<div id="b">Div B</div>
If you have divs in between use ~
#a:hover ~ #b {
background: #f00
}
<div id="a">Div A</div>
<div id="c">Div C</div>
<div id="b">Div B</div>
To go the other way around, unfortunately you will need Javascript
// Pure Javascript
document.getElementById('b').onmouseover = function(){
document.getElementById('a').style.backgroundColor = '#f00';
}
document.getElementById('b').onmouseout = function(){
document.getElementById('a').style.backgroundColor = '';
}
// jQuery
$('#b').hover(
function(){$('#a').css('background', '#F00')},
function(){$('#a').css('background', '')}
);
Full fiddle http://jsfiddle.net/p7hLL/5/
If you don't want to use the selector + or ~ which aren't compatible with some browsers, it is just possible if the <div /> to show (e.g. div#b) is a child of the <div /> to hover (e.g. div#a).
<div id="a">
<div id="b"></div>
</div>
<style>
div#b {
display: none;
}
div#a:hover div#b {
display: block;
}
</style>
Its works, but your css should be like this
<style>
#b{display:none;}
div#a:hover div#b{display:inline}
</style>