CSS that operates like a boolean AND for multiple complex selectors? - css

I'm writing a Stylish user style sheet, and am trying to see if something is possible. I am customizing a page that has a structure like this:
<div class="main">
<div class="someExtraLayers">
<div class="page">
1
</div>
</div>
<div class="someOtherLayers">
<div class="post">
blah blah
</div>
<div class="post">
foo foo
</div>
<div class="post">
bar bar
</div>
</div>
</div>
Where 'someExtraLayers' and 'someOtherLayers' indicate a few levels of divs inside divs. I'm not fully replicating the page's structure here for brevity's sake.
I have this in my user CSS:
div.post:nth-child(1) {
display:block !important;
}
Essentially, I'm making visible the first post element, and this does most of what I want to do. The thing I want to add is that I only want to make that element visible if the content of the page class is 1. If it's not 1, then I don't want to display the first post element.
CSS doesn't seem to offer conditionals, or boolean ANDs, that work this way. But I'm still new-ish to CSS, so I might be missing something. If I have to use a Greasemonkey script instead, I'll do that, but I was hoping there's some CSS trickery that will let me accomplish this.

Stylish cannot do this because Stylish just injects CSS and CSS does not have a selector for text content.
To do what you want, you will have to install Greasemonkey (Firefox) or Tampermonkey (Chrome) and then a userscript can set that visibility.
Assuming that div contains only 1, then something like this complete GM/TM script will do what you want. It uses the awesome power of jQuery selectors.
You can also see a live demo of the code at jsFiddle. :
// ==UserScript==
// #name _Show the first post on page 1
// #include http://YOUR_SERVER.COM/YOUR_PATH/*
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// #grant GM_addStyle
// ==/UserScript==
var pageHasOne = $("div.main:has(div.page:contains(1))");
pageHasOne.each ( function () {
var jThis = $(this); //-- this is a special var inside an .each()
var pageDiv = jThis.find ("div.page:contains(1)");
if ($.trim (pageDiv.text() ) == "1") {
//--- Show the first post div. !important is not needed here.
jThis.find ("div.post:first").css ("display", "block");
}
} );
Given the logic that jQuery javascript must use, we can see part of the reason why CSS doesn't attempt to provide selectors for this. It's beyond mission scope for CSS, but the kind of thing that javascript was made for.
Also note that this is for a static page. If the page uses AJAX for its content, the logic becomes a bit more involved.

CSS can not access HTML content.
To solve the problem, you will also need to add a class so CSS can "see" it:
HTML:
<div class="main one">
<div class="someExtraLayers">
<div class="page">
1
</div>
</div>
<div class="someOtherLayers">
<div class="post">
blah blah
</div>
<div class="post">
foo foo
</div>
<div class="post">
bar bar
</div>
</div>
</div>
CSS:
.one .post:nth-child(1) {
display:block !important;
}

Related

Expand/Collapse all elements of a Semantic UI accordion

I don't find any clue to do that from the Semantic UI documentation/API, is there a clean way to do that?
For now, what I see is to play with :
$('.ui.accordion > .title').addClass('active')
$('.ui.accordion > .content').css('display', 'block')
You actually can do this like so:
$('.ui.accordion .individual').each(function(i){
$(this).parent().accordion('open',i);
});
You just iterate through each individual element to get its index position, then ask the parent (the accordion) to open each one. This way you still get the transition.
Here is the answer:
onOpen(commentID: string){
jQuery(`.replies${commentID}`).accordion('open', 0);
}
<div class="ui accordion replies{{commentID}}">
<div class="title" (click)="onClick(commentID);">
</div>
<div class="content">
hello
</div>
</div>

Masonry doesn't work properly with Meteor

I have created a test project with Meteor which uses Masonry. I added the package mrt:jquery-masonry(or isotope:isotope), and it works well at the beginning. However, the problem comes now.
Basically, I want to implement the feature that when user clicks the button, the page will be added one more div. Below is my code:
main.html
<body>
<div class="container">
{{> masonryContent}}
</div>
<script>
(function($){
var $container = $('.masonry-container');
$container.masonry({
columnWidth: 300,
gutterWidth: 50,
itemSelector: '.masonry-item'
})
}(jQuery));
</script>
</body>
style.css
.masonry-item {
width: 300px;
}
masonry-content.html
<template name="masonryContent">
<div class="masonry-container">
<div class="masonry-item">
<p>blabla...</p>
<p>
Button
</p>
</div>
<div class="masonry-item">
<p>test...</p>
</div>
<div class="masonry-item">
<p>another test...</p>
</div>
{{#if showItem}}
<div class="masonry-item">
<p>new added item...</p>
</div>
{{/if}}
</div>
</template>
masonry-content.js
Template.masonryContent.events({
"click #click-me": function(e) {
e.preventDefault();
Session.set('show_me', true);
}
});
Template.masonryContent.helpers({
showItem: function() {
return !!Session.get('show_me');
}
});
The problem is when I click the button, the new div was created; however, it wasn't placed by following Masonry rules. The new created item just overlapped to the first item, but I expect it performs the way to append to the last item.
I would appreciate if anyone could help me on this.
Thanks in advance!
As meteor does partial rendering the element needs to be there in the DOM for masonry to work. So there are two ways of getting over the problem
1) Hide or unhide the element when the button click happens
Or
2) re-render the DOM
You can use the chrome dev tools to see what DOM elements are touched/refreshed (Green color).
There is a typo in masonry in the template name insertion.
Check the package state, many mrt packages are not well supported anymore.

FullpageJs and Meteor : Capture event from template

I'm struggling with fullpage.js in Meteor.
When I add a button inside a template, the Template.templatename.events function does not fire on event.
For example:
Template HTML (messages.html)
<template name="messages">
<ul>
{{#each mess}}
<li>{{ messContent}}</li>
{{/each}}
<button class="addMessage">Add Message!</button>
</ul>
</template>
Template JavaScript (messages.js)
Template.messages.helpers({
mess: function(){
return Messages.find();
}
});
Template.messages.events({
'click .addMessage' : function(event){
console.log("clicked")
}
})
Main HTML
<head>
<title>fulltest</title>
</head>
<body>
{{> full}}
</body>
<template name="full">
<div id="fullpage">
<div class="section active">
<h1>First slide</h1>
{{> messages}}
</div>
<div class="section">
<h1>Second slide</h1>
</div>
</div>
</template>
My fullpage initialisation:
Template.full.rendered = function(){
$('#fullpage').fullpage();
}
If I remove the fullpage initialisation then the click event gets logged. Still new at Meteor, I didn't manage to grasp what's going wrong here.
All help much appreciated,
Joris
Use delegation or use verticalCentered:false and scrollOverflow:false.
From the fullPage.js FAQs:
My javascript/jQuery events don't work anymore when using fullPage.js
Short answer: if you are using options such as verticalCentered:true or overflowScroll:true in fullPage.js initialization, then you will have to treat your selectors as dynamic elements and use delegation. (by using things such as on from jQuery). Another option is to add your code in the afterRender callback of fullpage.js
Explanation: if you are using options such as verticalCentered:true or overflowScroll:true of fullPage.js, your content will be wrapped inside other elements changing its position in the DOM structure of the site. This way, your content would be consider as "dynamically added content" and most plugins need the content to be originally on the site to perform their tasks. Using the afterRender callback to initialize your plugins, fullPage.js makes sure to initialize them only when fullPage.js has stopped changing the DOM structure of the site.

Using Angular Masonry in AngularJS?

I have a layout like this. I am using passsy extension for angular masonry.
<masonry column-width="200">
<div class="masonry-brick" ng-repeat="data in comments">
<div ng-switch on="data.type">
<div ng-switch-when="hoots">
<article class="hoot_main">
//content goes here
//hoot_main is the main class for this div layout
</article>
</div>
</div>
</div>
<div ng-switch on="data.type">
<div ng-switch-when="article">
<article class="hoot_main">
//content goes here
//hoot_main is the main class for this div layout
</article>
</div>
</div>
<div ng-switch on="data.type">
<div ng-switch-when="story">
<article class="hoot_main">
//content goes here
//hoot_main is the main class for this div layout
</article>
</div>
</div>
</div>
</masonry>
Browser is getting hanged whenever I use it. Debugging script with tools says element.masonry is not a function.
Any help would be appreciated!
Hmm, at the moment I work from my laptop at home and I can't get passy's version running too and can not put my finger on the issue. But this is what I can offer you for now:
I made a very simple directive based on things I've read somewhere:
app.directive('masonry', function() {
return {
restrict: 'AC',
controller: function($scope) {
return $scope.$watch(function(e) {
$scope.masonry.reloadItems();
return $scope.masonry.layout();
});
},
link: function(scope, elem, attrs) {
var container=elem[0];
var options='';
return scope.masonry = new Masonry(container,options);
}
};
As you can see it does not have a any options by now. When i'm at work on monday i will have a look at my sources on a proper dual screen display and provide you with a better version.
My wife is starting to giving me the looks and I need to put the laptop away now. :-\
You can see in this plunker that it kinda works now. Maybe this can help you. In the meantime can you add some of your json data to your question? Have a nice weekend for now!
In order to get Passy's angularjs directive working you must include all the files as listed per the index file
I had this error, fixed it by including the original Masonry code. I was also thinking this was a pure angular port.

how could I set a different background color to the menu title for every menu item or depending on the article that is opened?

I'm working on a Joomla 2.5 based website.
i have a submenu with a title (the title is the name of the topmenu category) on top. This title has a background color. Now I want to have a different background color (of the title) on every page that I open.
I thought about creating a extra menu module for every menu item with a specific color defined in the css, but than I have to rename every module because I must not have the same name twice. But I need the title to be the same as the Topmenu category for all the submenu items.
here is the basic structure of the generated code:
<body>
<div id="content">
<div id="breadcrumbs"></div>
<div id="main" class="centerAndRight"></div>
<div id="right">
<div class="moduletable_servicemenu">
<h3>HERE IS THE TITLE</h3>
<ul class="menu"></ul>
</div>
<div class="moduletable_kontaktmodul"></div>
</div>
</div>
<!-- end content -->
<div id="overallfooter"></div>
</body>
Could anybody help me with an idea, please.
Thanx in advance.
If you place a class on that title (e.g. class="title"), and then place a different class on the body tag of each page (e.g. <body class="contact">) you can easily style the title differently on each page, such as:
.contact .title {background: red}
.about .title {background: blue}
I wrote this script for random images, it can be edited to apply towards your desire which is random colors. Its fairly simple and again you can do as many colors as you want, and the program will randomize them.
$(document).ready(function() {
var colors = ['#ccc', '#dedede', '#333', '#555' /***keep adding as many colors***/];
$(".Topcategory").each(function(){
$(this).css({'background' : ' + colors[Math.floor(Math.random() * colors.length)] + ')'})
});
});

Resources