1

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.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Keen
  • 1,327
  • 1
  • 17
  • 25
  • 1
    Use JS/jQuery, CSS cannot manipulate your DOM – Mr. Alien Nov 21 '13 at 19:17
  • You might want to check the page's `body` element for classes that give hints about what content it contains. If there's a unique class that you can target (say, `.content-page-1`), you can use CSS. Otherwise javascript is the only way. – Chris Herbert Nov 22 '13 at 02:08

2 Answers2

1

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;
}
bookcasey
  • 39,223
  • 13
  • 77
  • 94
1

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.

Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295