29

I want something very similar to Theming collapsible headers located here:

http://jquerymobile.com/demos/1.2.0-alpha.1/docs/content/content-collapsible.html

Without using JQuery, is this possible?

It's for a mobile site but the page is always going to be offline so I dont really want to use jquery. Also giving custom styling to jquery mobile is alot harder than using pure css and styling it yourself.

2
  • 2
    The page being offline doesn't mean you can't use jquery, you can just store it locally. Commented Oct 3, 2013 at 23:30
  • Thats right but I'd much rather not use it, than cache it. It's for an ios browser control so I dont need to support ie 6/7. I would also have to find all of the images jquery mobile uses and store them locally too. Commented Oct 3, 2013 at 23:32

5 Answers 5

114

Five examples ahead:

Using <detail> and <summary> tags (pure HTML)

You can use HTML5's detail and summary tags to solve this problem without any CSS styling or JavaScript:

<details>
  <summary>Collapse 1</summary>
  <div>Content 1...</div>
</details>
<details>
  <summary>Collapse 2</summary>
  <div>Content 2...</div>
</details>

Using label and checkbox input

Keeps the selected item opened and togglable.

.collapse{
  cursor: pointer;
  display: block;
  background: #cdf;
}
.collapse + input{
  display: none; /* hide the checkboxes */
}
.collapse + input + div{
  display:none;
}
.collapse + input:checked + div{
  display:block;
}
<label class="collapse" for="_1">Collapse 1</label>
<input id="_1" type="checkbox"> 
<div>Content 1</div>

<label class="collapse" for="_2">Collapse 2</label>
<input id="_2" type="checkbox">
<div>Content 2</div>

Using label and named radio input

Similar to checkboxes, it just closes the already opened one.
Use name="c1" type="radio" on both inputs.

.collapse{
  cursor: pointer;
  display: block;
  background: #cdf;
}
.collapse + input{
  display: none; /* hide the checkboxes */
}
.collapse + input + div{
  display:none;
}
.collapse + input:checked + div{
  display:block;
}
<label class="collapse" for="_1">Collapse 1</label>
<input id="_1" type="radio" name="c1"> 
<div>Content 1</div>

<label class="collapse" for="_2">Collapse 2</label>
<input id="_2" type="radio" name="c1">
<div>Content 2</div>

Using tabindex and :focus

Similar to radio inputs, additionally you can trigger the states using the Tab key.
Clicking outside of the accordion will close all opened items.

.collapse > a{
  background: #cdf;
  cursor: pointer;
  display: block;
}
.collapse:focus{
  outline: none;
}
.collapse > div{
  display: none;
}
.collapse:focus div{
  display: block; 
}
<div class="collapse" tabindex="1">
  <a>Collapse 1</a>
  <div>Content 1....</div>
</div>

<div class="collapse" tabindex="1">
  <a>Collapse 2</a>
  <div>Content 2....</div>
</div>

Using :target

Similar to using radio input, you can additionally use Tab and keys to operate

.collapse a{
  display: block;
  background: #cdf;
}
.collapse > div{
  display:none;
}
.collapse > div:target{
  display:block; 
}
<div class="collapse">
  <a href="#targ_1">Collapse 1</a>
  <div id="targ_1">Content 1....</div>
</div>

<div class="collapse">
  <a href="#targ_2">Collapse 2</a>
  <div id="targ_2">Content 2....</div>
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

Nice solution, is it possible to have more than one expanded at a time and be able to collapse one thats open by reclicking it again?
@dev6546 sure, take a look at the first demo link
This is great! Do anyone know if I can use one of this solutions on email templates?
@YellowBrickRoad no you cannot. HTMLEmail is ancient markup, cannot make use of form elements, :target, and lacking support for <details>.
9

You can use a checkbox to simulate onClick with CSS:

input[type=checkbox]:checked + p {
    display: none;
}

JSFiddle

Adjacent sibling selectors

2 Comments

To improve upon this answer, you can also add transitional effects: jsfiddle.net/37RGT
Hello, Do you know if this solution could work on email templates?
2

I like Roko's answer, and added a few lines to it so that you get a triangle that points right when the element is hidden, and down when it is displayed:

.collapse { font-weight: bold; display: inline-block; }
.collapse + input:after { content: " \25b6"; display: inline-block; }
.collapse + input:checked:after { content: " \25bc"; display: inline-block; }
.collapse + input { display: inline-block; -webkit-appearance: none; -o-appearance:none; -moz-appearance:none;  }
.collapse + input + * { display: none; }
.collapse + input:checked + * { display: block; }

Comments

2

Of course! jQuery is just a library that utilizes javascript after all.

You can use document.getElementById to get the element in question, then change its height accordingly, through element.style.height.

elementToChange = document.getElementById('collapseableEl');
elementToChange.style.height = '100%';

Wrap that up in a neat little function that caters for toggling back and forth and you have yourself a solution.

Comments

-1

Using Label and Checkbox But, Show By Default, Hide Everything On Click. Good For Popup.

<style>
.popup-checkbox {
display: none;
}
.popup-checkbox:checked + .popup {
display: none;
}
</style>

<input type="checkbox" id="popup-toggle" class="popup-checkbox">

<div class="popup">
<label for="popup-toggle" class="popup-close">✕</label>
popup content
</div>

demo: https://jsfiddle.net/o416yqrg/

3 Comments

Two of the existing answers already detail this technique.
@Sean No this is different
It's different in that it only allows you to hide the element. The question asks for techniques for toggling the visibility of something both open and closed. This doesn't meet that requirement.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.