-3

I am setting up a FAQ page. On the page I have a div, of class=”faq_container”, with 6 child divs arranged in a 3×3 grid that contain the faq questions. So basically I have 6 clickable boxes.

Each question, when clicked, will reveal its answer hiding the all the questions but maintained within the faq_container div. There would be a close link below the answer to hide the answer and take you back to the questions.

I know this is probably pretty simple. I’m hoping someone can help me out.

Thanks!

David says reinstate Monica
  • 230,743
  • 47
  • 350
  • 385
TJnTN
  • 57
  • 1
  • 9
  • Is there a reason you need a CSS method for this? The are much simpler and more efficient ways to do this via jQuery. – Charlie74 Nov 03 '13 at 13:34
  • So, please show your relevant html and CSS. Explain what you've tried to do, and where it went wrong. Otherwise this reads as a request for us to do all your work for you, and that's not what we're here for. – David says reinstate Monica Nov 03 '13 at 13:37
  • Was not trying to have someone do my work for me. I've just been stumped because nothing I had tried with a CSS only method was working nor could I find a solution on here or with a google search. It appears though it may only be achievable via a js solution. – TJnTN Nov 03 '13 at 13:52
  • No, this is perfectly do-able with CSS alone, albeit it's an imperfect approach. – David says reinstate Monica Nov 03 '13 at 16:17

4 Answers4

1

While you've accepted a JavaScript solution, there are (at least) two ways that this can be achieved with CSS alone, the first using CSS :target pseudo-classes, and the second using input, and label, elements.

The first, assuming HTML similar to the following:

<div id="faq_container">
    <ol>
        <li id="faq1">
             <h2><a href="#faq1">Question 1</a></h2>

            <div>
                <p>Text, relating to question one.</p> <a class="close" href="#hide">close</a>

                <!-- the above link doesn't link to anything, just changes the hash whcih stops the ':target' pseudo-class matching the the current 'div' element -->
            </div>
        </li>
        <!-- subsequent elements follow the above structure, stripped for brevity -->
    </ol>
</div>

With the following CSS (albeit there's more CSS in the demo, since I've stripped out some of the purely aesthetic stuff here, for brevity, as above):

li {
    /* some stripped out aesthetics */
    position: relative; /* used to position the '.close' links */
}
li div {
    height: 0; /* to allow for animation of the height 'none' to 'block' can't animate */
    overflow: hidden;
    /* all vendor prefixes removed for brevity, here and later */
    transition: all 0.5s linear; /* animates to the default properties, from other 'states' */
}
/* li:target matches when the 'id' of the 'li' is equal to the hash/fragment-identifier in the URL */
li:target div {
    height: 4em; /* to allow for animation (this is the awkward part of using pure CSS) */
    transition: all 0.5s linear; /* transitions to the 'selected' state (when the user clicks a link in the 'h2' element) */
}
li a:link, li a:visited {
    /* aesthetics removed */
}
/* styling the 'interactive' states (:hover, :active, :focus), and the 'selected' state using 'li:target h2 a' */
li a:hover, li a:active, li a:focus, li:target h2 a {
    font-weight: bold;
    text-decoration: underline;
}
a.close {
/* styling the '.close' link, so it's invisible in the 'non-selected' state */
    position: absolute;
    opacity: 0;
    width: 0;
    overflow: hidden;
    transition: all 0.65s linear;
}
/* styling the '.close' link, so it's only visible when the question is 'selected' */
li:target a.close {
    opacity: 1;
    width: 4em;
    transition: all 0.65s linear;
}

JS Fiddle demo.

The second approach uses label and input elements (type="radio" if only one question can be visible at a time, type="checkbox" if multiple elements can be visible), based on the following HTML:

<input id="close" name="question" type="radio" />
<div id="faq_container">
    <ol>
        <li>
            <input id="faq1" type="radio" name="question" />
             <h2><label for="faq1">Question 1</label></h2>

            <div>
                <div>
                    <p>Text, relating to question one.</p>
                    <label for="close">Close</label>
                    <!-- the above 'label' closes the question, by referring to an
                         'input' of the same name (different 'id'), taking advantage
                         of the fact that only one radio-'input' of a given name can
                         be checked (this 'input' is just before the ancestor 'ol') -->
                </div>
            </div>
        </li>
        <!-- subsequent elements follow the above structure, stripped for brevity -->
    </ol>
</div>

And the following CSS (as before, aesthetics removed for brevity):

/* you could, instead, use a class-name to identify the relevant radio-inputs */
input[type=radio] {
    /* using 'display: none' (apparently) in some browsers prevents
       interactivity, so we fake it, by hiding: */
    position: absolute;
    opacity: 0;
    left: -1000px;
}
/* styling the 'div' that's the adjacent-sibling of an 'h2' which is an
   adjacent-sibling of an 'input' all of which are descendants of a 'div' */
div input + h2 + div {
    height: 0; /* to allow for animating with transitions */
    overflow: hidden;
    /* vendor prefixes, again, stripped out */
    transition: all 0.5s linear;
}
/* using 'input:checked + h2 + div' causes problems in Chrome, check the references;
   so we're styling (respectively) a 'div' which is an adjacent sibling to an 'h2'
   which is an adjacent-sibling of a checked 'input', and/or
   a 'div' which is a general-sibling of a checked 'input' (in both cases these are
   all descendants of another 'div' element) */
div input:checked + h2 + div,
div input:checked ~ div {
    height: 4em; /* to allow for animating with transitions */
    overflow-y: auto; /* a personal preference, but allows for
                         scrolling if the height is insufficient
                         though it can be a little ugly, with a flicker */
    transition: all 0.5s linear;
}

JS Fiddle demo.

The same approach can be used with checkboxes, which allows the label to toggle the display of the relevant question, and makes the close links/labels pointless, HTML:

<div id="faq_container">
    <ol>
        <li>
            <input id="faq1" type="checkbox" name="question" />
             <h2><label for="faq1">Question 1</label></h2>

            <div>
                <div>
                    <p>Text, relating to question one.</p>
                </div>
            </div>
        </li>
        <!-- subsequent elements follow the above structure, stripped for brevity -->
    </ol>
</div>

And CSS (precisely as the preceding example, but changed input[type=radio] to input[type=checkbox]):

/* duplicated, and aesthetic, CSS removed for brevity */
input[type=checkbox] {
    position: absolute;
    opacity: 0;
    left: -1000px;
}

JS Fiddle demo.

References:

Community
  • 1
  • 1
David says reinstate Monica
  • 230,743
  • 47
  • 350
  • 385
0

The simplest means of achieving what you're asking for comes down to changing the "class" attribute value of these DIV elements when their respective OnClick events are fired. For that, you'll need to use a scripting engine of some kind, and that is likely going to be JavaScript unless you want a post back, in which case you can just handle it in the code behind of the page. JQuery, as others have mentioned, is a good choice, but comes with some overhead.

The way this site works is that you post what you've tried so far, and what results you're getting. I get the impression that you haven't tried anything, so I would suggest that you do some searching on this site or your web search engine of choice for a string like "javascript change css class onclick" and see where that leads you.

Without more specifics on your exact use case and environment, you are unlikely to get a "here, copy and paste this code into your page" type of answer.

[EDIT] Never mind. I always underestimate the compulsion of developers to begin writing code before knowing any constraints. Enjoy your copypasta.

0

If a jQuery solution is allowed, here is a quick mock-up.

$(".wrapper").click(function(){
    $(this).children(".answer").toggle();
    $(".wrapper").not(this).toggle();
    $(".faq_container").toggleClass("active");
});
Bram Vanroy
  • 22,919
  • 16
  • 101
  • 195
0

You should use this kind of structure :

$('.question').on('click', function(ev) {
    ev.preventDefault();
    $(this).find('.answer').show();
});

$('.close').on('click', function(ev) {
    ev.preventDefault();
    ev.stopPropagation();
    var dismiss = $(this).data('dismiss');
    $(this).closest('.'+dismiss).hide();
});
.faq {
    position: relative;
    width: 600px;
}
.question {
    height: 178px; width: 178px;
    margin: 5px;
    padding: 5px;
    border: 1px solid black;
    background: #efefef;
    float: left;
    cursor: pointer;
}
.answer {
    position: absolute;
    top: 0; left: 0;
    height: 578px; width: 578px;
    margin: 5px;
    padding: 5px;
    border: 1px solid black;
    background: #bebebe;
    cursor: default;
    display: none;
}
a.close {
    position: absolute;
    top: 5px; right: 5px;
    display: block;
    height: 20px; width: 20px;
    color: black;
    border: 1px solid black;
    line-height: 20px;
    text-align: center;
    text-decoration: none;
}
a.close:hover {
    background: #9f9f9f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<section class="faq">
    <article class="question">Question 1 ?
        <div class="answer">
            Answer 1 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
    <article class="question">Question 2 ?
        <div class="answer">
            Answer 2 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
    <article class="question">Question 3 ?
        <div class="answer">
            Answer 3 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
    <article class="question">Question 4 ?
        <div class="answer">
            Answer 4 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
    <article class="question">Question 5 ?
        <div class="answer">
            Answer 5 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
    <article class="question">Question 6 ?
        <div class="answer">
            Answer 6 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
    <article class="question">Question 7 ?
        <div class="answer">
            Answer 7 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
    <article class="question">Question 8 ?
        <div class="answer">
            Answer 8 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
    <article class="question">Question 9 ?
        <div class="answer">
            Answer 9 !
            <a href="#" class="close" data-dismiss="answer">&times;</a>
        </div>
    </article>
</section>

For the CSS, you'll need to mix float: left for your 3*3 pattern, and position: absolute for each answer.

zessx
  • 65,078
  • 28
  • 121
  • 147
  • This is what I am trying to accomplish. I just thought it might be possible via a CSS only solution. – TJnTN Nov 03 '13 at 13:59
  • As soon as you start using `click` events, CSS-only solutions vanish. Maybe it's possible, but it'll surely be experimental. – zessx Nov 03 '13 at 14:01
  • Yeah I was trying to hide the element based on the :focus attribute and that just wasn't working. Sorry for the confusion. My question could have been clearer had I posted what wasn't working for me. – TJnTN Nov 03 '13 at 14:06