In a directory site
D, E, F are post type entries (Wordpress) fetched in the B grid, and they are odered by their like counts, so their order is subject to change.
G, H, I are ads in column C, and they ideally should be horizontally "anchored" to the post entries, to achieve very related ads.
Meaning that if the order of the post entries in the grid changes to FDE top to bottom, then the order of the ads in their column should change accordingly to IGH, top to bottom.
Is there any pure CSS way to achieve this, or what would be the Javascript fix?
I was also told to keep the ads and the post entries in the same column, but that reduces styling possibilities (and overall possibilities), so I would prefer to keep them in 2 separate columns.
I do have the possibility to add custom selectors to both the individual ads and post entries, on demand.
Thanks!
Update:
additional detail - the number of the elements in both columns is increasing with new elements added.
If I understand correctly in one column you have a list of recent posts/blog articles updates when a new article is written. You want the adds on the right to always be directly across from their related article. This can not be accomplished with pure CSS as CSS can't make those calls.
If you have access to the HTML you could but D & G in their own div. E & H in their own div. Instead of having them share a column with the other items. But you would have to make sure that when you add a new article that things update correctly. That may call for some Jquery.
I think, you are receiving those ratings using PHP. Although I think, this kind of sorting better to do using PHP on beck-end. But if you are looking for more like CSS solution - please take a look:
This part you need to get from your PHP in your template file. This is primitive construction, can write you more when will see your code. Here we are using CSS variables.
<style>
:root {
<?php $x = 1;
foreach($latest_posts as $post) { ?>
--x<?php echo $x; ?>: <?php echo $post['like_count']; ?>;
<?php $x += 1; } ?>
}
</style>
And a code for sorting in separate blocks using CSS only.
:root {
--x1: 3;
--x2: 2;
--x3: 55;
}
.b, .c {
display: inline-flex;
/* this will helps us to order elements bakcwords, so the one with the highest number will be on the top */
flex-direction: column-reverse;
flex-wrap: nowrap;
justify-content: flex-end;
align-content: stretch;
align-items: flex-start;
}
.d, .g {
order: var(--x1);
background: yellow;
}
.e, .h {
order: var(--x2);
background: cyan;
}
.f, .i {
order: var(--x3);
background: green;
}
<div class="a">
<div class="b">
<div class="d">d</div>
<div class="e">e</div>
<div class="f">f</div>
</div>
<div class="c">
<div class="g">g</div>
<div class="h">h</div>
<div class="i">i</div>
</div>
</div>
UPDATED
Fore any number of posts posts.
<style>
.flex-block {
display: inline-flex;
/* this will helps us to order elements bakcwords, so the one with the highest number will be on the top */
flex-direction: column-reverse;
flex-wrap: nowrap;
justify-content: flex-end;
align-content: stretch;
align-items: flex-start;
}
<?php $x = 1;
foreach($latest_posts as $post) { ?>
.flex-block > div:nth-child(<?php echo $x; ?>) {order: <?php echo $post['like_count']; ?>;}
<?php $x += 1; } ?>
</style>
<div class="flex-block left-one">
<div>left 1</div>
<div>left 2</div>
<div>left 3</div>
</div>
<div class="flex-block right-one">
<div>right 1</div>
<div>right 2</div>
<div>right 3</div>
</div>
I have a list of photos and I want check marks to appear when the photo is clicked. The page is also supposed to hide the check marks when it loads, but it doesn't do that either right now. The page is at http://lindseymotors.com/addvehicle.php
Here is the relevant JS code, but it gets inserted into the body of the HTML rather than the head tag where the rest of my JS goes. Is this what's causing my issues or is it a problem with the code itself? These bits of code are generated by PHP and inserted into the body HTML tag.
var allPhotos = new Array();
allPhotos[0] = '2000.mercedesbenz.clk430.0.jpg';
var selectedPhotos = new Array();
function selectVehicle(photoID) {
if ( selectedPhotos.indexOf(photoID) > -1 ) {
$('#check'+photoID).zIndex(-1);
selectedPhotos.splice(photoID, 1);
} else {
selectedPhotos.push(photoID);
$('#check'+photoID).zIndex(1);
}
}
$(document).ready(function(){
$('#photo0').click(selectVehicle(0));
$('#check0').zIndex(-1);
});
Of course there are 17 photos on the page itself, but the code is the same for each photo. By default the check marks will be hidden once I get the functionality working.
You use the jQuery.click(function) method. You should pass a function, and not a statement.
Try using this instead:
$('#photo0').click(function() { selectVehicle(0); });
You do not need to keep an array of selected images, you can easily do this with a css class and jQuery's toggleClass, and then when you need to reference the selected ones just select them using the correct selector.
Wrap each car into a div
<div class="car selected">
<img src="http://placehold.it/128x128" />
</div>
Create a css class that will create the checkmark over the car image(using the :after pseudo class) when the div has the class
.selected:after {
content:' ';
width:128px;
height:128px;
display:block;
background:url(http://lindseymotors.com/engine/img/check.png) no-repeat 50% 50%;
background-size:contain;
position:absolute;
top:0px;
left:0px;
}
Then just toggle the class on or off using jQuery's toggleClass
jQuery("carDivSelector").toggleClass("selected");
And when you need to get the selected cars
var selectedCars = jQuery(".car.selected");
Demo
jQuery(".car").click(function(){
jQuery(this).toggleClass("selected");
});
.car {
position:relative;
display:inline-block;
}
.selected:after {
content:' ';
width:128px;
height:128px;
display:block;
background:url(http://lindseymotors.com/engine/img/check.png) no-repeat 50% 50%;
background-size:contain;
position:absolute;
top:0px;
left:0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="car selected">
<img src="http://placehold.it/128x128" />
</div>
<div class="car">
<img src="http://placehold.it/128x128" />
</div>
<div class="car">
<img src="http://placehold.it/128x128" />
</div>
<div class="car">
<img src="http://placehold.it/128x128" />
</div>
You have an error at your code... look to the console
Uncaught TypeError: $(...).zIndex is not a function ... addvehicle.php:17
It means that the result you got with $('#check'+photoID) don't have a function 'zIndex'
Edit: Well you solved the error. But you have a logical problem when you remove a selected record...
Like the other guy said, there are better ways to do it. but with you wanna solve it now try to use the index to splice, and not the photoId...
function selectVehicle(photoID) {
var index = selectedPhotos.indexOf(photoID);
if ( index > -1 ) {
$('#check'+photoID).css('z-index', '-1');
selectedPhotos.splice(index, 1);
} else {
selectedPhotos.push(photoID);
$('#check'+photoID).css('z-index', '1');
}
}
and try to use thumbnails please..
Im generating some content with PHP, but after the number of contents is more than 5 the height becomes greater than that of the div, so i don't want it to stack on top of the div, but to move to the right of the div and start from the top. Here's an image.
PHP
echo '<a class="LibSectOpen">
<span style="display:none" class="SectionName">'.$Section.'</span>
<div class="LibrarySects"><div class="LibrarySectsHeader">'.$Section.'</div>
<div class="LibrarySectsShelf">';
while($row = mysql_fetch_array($log2)){
echo '<div class="LibrarySectsShelf_Book" style="background-color:'.$Color.'"
title="Author: '.$row['bbookauthor'].'">'.$row['bbookname'].'</div>';
}
echo ' </div>
</div>
</a>';
As it looks, the philosophy books in the example goes down, and i want it to go to the right and start another column of five books and so on.
Any ideas i can do this with JQuery and CSS?
.LibrarySectsHeader {
border:1px #CCC solid;width:500px; margin:2px; padding:1px; height:18px;border-radius:2px 2px 2px 2px; font-size:10px; color:rgba(0,0,0,1) !important; background-color: rgba(255,255,255,0.6); line-height:18px;
}
.LibrarySectsShelf {
border:1px #CCC solid;width:499px; margin:2px; padding:1px; height:129px;border-radius:2px 2px 2px 2px; font-size:10px; background-color: rgba(255,255,255,0.2); line-height:18px; background-image:url(images/bg/wood.jpg); background-size:100%; background-repeat:no-repeat;
}
.LibrarySectsShelf_Book {
border:1px #C90 solid;width:148px;height:23px; margin-bottom:1px;border-radius:3px 3px 3px 3px; font-size:10px; background-color: rgba(51,153,255,0.9); padding-left:2px; line-height:22px; color:rgba(255,255,255,1) !important; overflow: hidden;
}
.LibraryBooks {
border:1px #CCC solid;width:502px; margin:2px; padding:1px;border-radius:2px 2px 2px 2px; font-size:10px; background-color: rgba(102,102,102,1); line-height:18px;
}
You can achieve the output you want using only PHP,HTML,CSS solution which you are already using:
PHP
$i=1;
echo '<a class="LibSectOpen">
<span style="display:none" class="SectionName">'.$Section.'</span>
<div class="LibrarySects"><div class="LibrarySectsHeader">'.$Section.'</div>
<div class="LibrarySectsShelf"><div class="move_right">';
while($row = mysql_fetch_array($log2)){
echo '<div class="LibrarySectsShelf_Book" style="background-color:'.$Color.'"
title="Author: '.$row['bbookauthor'].'">'.$row['bbookname'].'</div>';
if($i%5==0)
{
echo '</div><div class="move_right">';
}
$i++;
}
echo '</div></div></div></a>';
The above code uses <div class="move_right"> ... </div> to divide elements in group of 5 so as to display each group in a new column.
CSS (.move_right)
.move_right{
display:inline-block;
vertical-align:top;
}
Fiddle of how the generated HTML's output will be
I'll provide you with 2 solutions here, PHP and CSS, as #ariel has already contributed a jQuery solution, since I always like to be JS independent, and also it will save you, using a third party script, along with jQuery Library (If you aren't using jQuery), I chosed PHP first, and than the CSS one which may be less compatible in terms of IE.
If you want to achieve that using PHP, you need to alter your loop and set a counter, which will break..
Assume that we are having an array of elements, and we want to set just like you need it..
<div class="wrapper">
<ul>
<?php
$arr = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15');
$counter = 0;
foreach ($arr as $value) {
if($counter%5==0 && $counter != 0){ echo "</ul><ul>";}
?>
<li><?php echo $value; ?></li>
<?php
$counter++;
}
?>
</ul>
</div>
Here, am using a counter variable which am incrementing at the end of the loop, the line over here $counter%5==0 in if condition states that if the loop counter is divisible by 5, add </ul><ul>, hence, this will generate a group of ul which are floated to left.. consisting of 5 li each.
Demo - Fiddle Code
CSS
* {
margin: 0;
padding: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.wrapper {
height: 150px;
margin: 50px;
border: 1px solid #eee;
}
ul {
float: left;
list-style-type: none;
}
ul li {
height: 30px;
width: 150px;
background: tomato;
border: 1px solid #515151;
}
Now as you said that but after the number of contents is more than 5 the height becomes greater than that of the div hence if you apply the same logic in your markup, it will force the div to start another column.
Demo - Fiddle Code
<a class="LibSectOpen">
<span style="display:none" class="SectionName"><?php $value; ?></span>
<div class="LibrarySects"><div class="LibrarySectsHeader">Whatever</div>
<div class="LibrarySectsShelf">
<div class='inner_wrap'>
<?php
$arr = array('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15');
$counter = 0;
foreach ($arr as $value) {
if($counter%5==0 && $counter != 0){ echo "</div><div class='inner_wrap'>";}
?>
<div class="LibrarySectsShelf_Book" title="Author:">Whatever <?php echo $value; ?></div>
<?php
$counter++;
}
?>
</div>
</div>
</div>
</a>
Doing the same with CSS, you can use column-count property, but as far as IE is concerned, it will make a mess.. though if you're interested in the solution, than here you go...
Demo
HTML
<ul>
<li>1</li>
<!-- More incremented li -->
</ul>
CSS
ul {
list-style-type: none;
-moz-column-count: 3;
-webkit-column-count: 3;
column-count: 3;
}
For Multi Column Support Reference
My solution involves jQuery and the plugin Columnizer.
Here's the working fiddle: http://jsfiddle.net/bortao/qGfsr/
The code is very simple:
$('.LibrarySectsShelf').columnize({
width: 166,
height: 150,
doneFunc: function () {
$('.LibrarySectsShelf_Book').removeClass('hidden');
}
});
The only change in your css is this new class:
.hidden {
visibility: hidden
}
Which should be added to every LibrarySectsShelf_Book. This is solely to prevent the flickering of the unorganized items. The class is removed when the columnization is complete.
Easy.
.LibrarySectsShelf {writing-mode: vertical-lr;}
.LibrarySectsShelf_Book {display: inline-block;}
Works in every browser I tested, despite wiki pages claiming otherwise, and it's been around since IE8.
Solution using only CSS
The best way of doing this, is using CSS3 flex boxes like this:
Here is how:
In the CSS add these 3 lines in .LibrarySectsShelf{ ... }
.LibrarySectsShelf {
display: flex; // to add
flex-flow: column wrap; // to add
align-content: flex-start; // to add
... // the rest of your code
}
and 1 line in .LibrarySectsShelf_Book{ ... }
.LibrarySectsShelf_Book{
flex: 0 0 23px;
... // the rest of your code
}
Cross browser support
Please note that since Flex box is a new feature in CSS3, you may have to add some browser prefixes like -webkit-, -moz- and -ms- to let it work properly in all major browsers.
Also note that the flex box wrap feature is only available in Firefox 28 and newer.
A working cross-browser example is available on http://jsfiddle.net/29Cmz/
Why Flexbox
Because it is very flexible, it will fill up all the available space and you don't have to hardcode the number of rows in PHP/JavaScript.
I believe this may be helpful HTML list elements top to bottom, then left to right
The jsfiddle shows that if you want to do this with css you can use css columns. Otherwise an answer below links to a js plugin to achieve this. Alternatively you could just do the positioning when you create the content in PHP if this is possible.
It seems to me that you dont need the complete width of your main container.
Why don't you just add a fixed width to both categories and set them to display:inline; or display:inline-block (still messing these two up... sry).
If you want to determine it dynamically, you could check weather the height of your main container is sufficient for both categories. If this is not the case you could set the css attributes of both categories (I srsly hope for you they have the same css class ;) with
$('.your-class').css({'width':'250px', 'display':'inline'});
I think this should do the magic.
EDIT: Ahh sry. didint see your code... Never the less it should work this way ;)
First of all . Don't put div in a tag .
Then you can find array_chunk php function .
So What you need to do.
It will be better if you use PDO .
PDO fetch all will return array;
<?php
$chunkSize = 5; // or any other value you need
$chunks = array_chunk($result_array,$chunkSize);
foreach($chunks as $links_array):?>
<div class="move_right">
<?php foreach($links_array as $link):?>
<!-- your link code -->
<?php endforeach; ?>
</div>
<?php endforeach ?>
The following code detects the end of the div and creates a new column using css.
var col = 1;
jQuery(
function($)
{
$('#flux').bind('scroll', function()
{
if($(this).scrollTop() +
$(this).innerHeight()
>= $(this)[0].scrollHeight)
{
$("#yourdiv").css("-moz-column-count",col);
$("#yourdiv").css("-webkit-column-count",col);
col++;
}
})
}
);
Tons of great answers here, I vote the javascript/CSS ONLY solution because.
1) the PHP stays solely responsible for getting data to screen ( re use the same php logic for new presentations in the future )
2) The Javascript and CSS can be flexible to provide personalised markup arrangement per device, browser and view size
DEMO : http://jsfiddle.net/9Bc76/1/
Markup - Let PHP just generate the items and forget about presentation.
<div class="container">
<div class="item">An Item</div>
<div class="item"> An Item</div>
<div class="item">An Item</div>
....
Javascript to wrap the elements ( here is a hardcoded per 5 'items' ) - making use of the jquery selector and wrapAll method.
var items = $(".item");
for(var i = 0; i < items.length; i+=5) {
items.slice(i, i+5).wrapAll('<div class="wrapper"></div>');
}
CSS to layout
.wrapper { display:inline-block; float:left; }
/* clear the float so the container keeps 'containing' */
.container:last-child:after {
clear:both; display:block;visibility:hidden;
height:0; content:"."; }
That's it.
More, If we need our 'wrap count' to be dynamic, we can do some calculation based on the height of the .item and the height of .container to get the desired 'wrap' count.
Lets say the container has a fixed height that is not allowed to grow;
.container { height: 300px; width: 100%; overflow: hidden; }
Javascript can find the 'wrap count interval' dynamically ( find how may items fit in the container height }
var containerheight = $(".container").height(),
itemheight = $(".item").height();
var wrapinterval = Math.floor(containerheight/itemheight);
Now we can use
var items = $(".item");
for(var i = 0; i < items.length; i+=wrapinterval) {
items.slice(i, i+wrapinterval).wrapAll('<div class="wrapper"></div>');
}
DEMO with dynamic wrap interval - http://jsfiddle.net/2paNY/2/
APologies to fellow SO'ers if this contains parts already answered in one way or another, I just got into typing away
Just Copy and paste this piece of code and try at your end and use the logic.
<?php
for($i = 1; $i <= 20; $i++){
if($i % 5 == 1){
echo '<div style="float:left;">';
}
echo '<div class="LibrarySectsShelf_Book" style="background-color:'.$Color.'"
title="Author: '.$row['bbookauthor'].'">'.$row['bbookname'].'</div>';
if($i % 5 == 0){
echo '</div>';
}
}
?>
I'm working on an ecommerce site for a client using Business Catalyst.
On their "Menu" page, they would like to display an "Out of Stock" DIV over the images of all out-of-stock products.
The DIV should be triggered by BC's proprietary content tag, {tag_instock}.
When {tag_instock} is 0, div.nostock should be displayed on all products that are out-of-stock.
At the moment, it only displays over one product that is out-of-stock rather than all products.
HTML:
<ul class="product-images">
<div id="nostock" class="nostock" style="display: none;"><h2>Out of Stock</h2></div>
<li>img_one</li>
<li>img_two</li>
<li>img_three</li>
</ul>
SCRIPT:
$(document).ready(function() {
var stock = "{tag_instock}";
if (stock == 0) {
document.getElementById('nostock').style.display = "block"
};
});
I'm not quite clear about using jquery vs. javascript. Which would be better suited to this solution?
Please let me know if I need to elaborate.
Any help is greatly appreciated.
Thank you.
I simulate stock value with data attribute for demo purposes...tell me if this works for you, here's a Fiddle
$(function() {
$('li').each(function() {
// var stock = "{tag_instock}";
var stock = $(this).data('stock');
if (stock == 0) {
$(this).append('<div class="nostock">Out of Stock</div>');
}
if (stock > 0) {
$(this).append('<div class="instock">In Stock '+stock+'</div>');
}
});
});
I overdo it a little, added instock and instock values aside, Fiddle updated.
If the three images are always the same, I would combine them into a single image. If you do that, then you can create a CSS class that overlays the image using a content property. By dynamically adding the class to the div's in question, you achieve the affect you want.
The class looks like this:
.no-stock-image:after {
content: url(images/out-of-stock.png);
position: absolute;
top: 10px;
left: -10px;
}
Obviously you'll have to adjust the positioning.
It sounds to me like you should use the following HTML:
<ul class="product-images">
<li><span class="nostock" style="display: none;">Out of Stock</span>img_one</li>
<li><span class="nostock" style="display: none;">Out of Stock</span>img_two</li>
<li><span class="nostock" style="display: none;">Out of Stock</span>img_three</li>
</ul>
Then use CSS like:
.no-stock {
position: absolute;
top: Xpx;
left: Xpx;
width: Xpx;
height: Xpx
background-color: #eee;
}
Adjusting the X's to suit.
I'm trying to fix a div at the top of a layout that will contain a blog post's information (date posted, # of notes, permalink, etc.) and change this information as you scroll down past posts. I'm not sure if it would require any kind of javascript or just some intricate positioning using css. Here's how I would layout the posts. How can I get the specific post information from each post to change within that fixed div as the posts scroll past it?
#container {
width: 960px;
margin: 0px auto;
}
#changingpostinformation {
position: fixed;
margin: 0px auto;
}
<div id="container">
<div id="changingpostinformation">fixed post information div that's information changes as each post below reaches the top of #container</div>
<div class="post">
<h3>Post Title>
<p>This is the body of this example post.</p>
</div>
<div class="post">
<h3>Post Title>
<p>This is the body of this example post.</p>
</div>
</div>
Like #ShankarSangoli says, you should add top: 0;, and also left: 0; to #changingpostinformation (or other values to position it however you like)
You'll need some javascript to find out which post appears first on the page and show its info.
$(function() {
$(window).bind('load resize scroll', function() {
var doctop = $('body').scrollTop();
// loop over all posts, from top to bottom
$('.post').each(function() {
if ($(this).position().top > doctop) {
put_postinfo_in_fixed_div($(this));
return false; // breaks from the loop
}
});
});
});
This function runs once when page is loaded, and also when the window is resized or scrolled.
You need to implement put_postinfo_in_fixed_div() which gets an post div, and does what it says.
Use this CSS:
#changingpostinformation {
position: fixed;
top: 0px;
}