I'm working on a small "shoe size" project, where the user should be able to read an article about a special shoe. The reader can on a button choose either to get the EU or US sizes inside the article.
My question is, how can i do this the best way - since i actually don't wan't to create a new <p> tag inside a <p> tag..
<p>This is the start of the article and this shoe is only available in <p units="US">11.5</p> <p units="EU">45</p></p>.
To cover the primary issues, relating to the validity of your HTML or, specifically, the invalidity of your HTML:
<p> element cannot contain another block element, it can only contain, "phrasing content," and its:end tag may be omitted if the
pelement is immediately followed by anaddress,article,aside,blockquote,div,dl,fieldset,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,main,nav,ol,p,pre,section,table, orul, element…
Therefore if the browser encounters a nested <p> that nested <p> is immediately interpreted as a sibling of the currently-open <p> element (the extraneous end-tags are merely discarded as erroneous mark-up). Because the content of these nested elements aren't – syntactically or semantically – a paragraph I converted them to <span> elements, which are 'neutral' containers (they imply nothing of the contents), which can be contained within a <p> element and contain phrasing content.
units attribute is a non-standard, custom, user-created attribute and therefore invalid; however user-defined attributes are allowed if they're preceded with the data- prefix; so to make your attributes valid I merely converted them from units to data-units.That said, this is the resulting HTML (of that part), note that I also moved the sentence-closing period within the paragraph, for syntactic correctness:
<p>This is the start of the article and this shoe is only available in
<span data-units="US">11.5</span>
<span data-units="EU">45</span>.</p>
Now, your question was how to use a button to show/hide the sizing information, to show either the US sizing, or the EU sizing; to do that is easier with JavaScript, but there is a (slightly messy) hack available to allow native HTML and CSS to implement that behaviour using <label> and <input> elements.
The <label> element is linked to an <input> element of type="radio", and the relevant radio-inputs share the same name, so that only one can be selected at a time.
These radio-inputs precede the <p> element(s) within which the sizing information is held that you want to toggle, and CSS is used to select the checked radio-input and then show only the specific content, hiding the other.
In practice this gives:
label {
/* irrelevant, and merely for aesthetics: */
box-sizing: border-box;
width: 3em;
height: 2em;
background-color: #999;
color: #fff;
font-weight: 900;
border-radius: 0.5em;
padding: 0.25em;
}
/* the :checked pseudo-class allows us to select
the selected/'checked' input, and the adjacent
sibling combinator ('+') traverses from the
checked input to the adjacent label element: */
input:checked + label {
background-color: limegreen;
}
/* visually moving the inputs of 'type=radio' (using
a CSS attribute-selector) off the page, so it's
not visible to the user; choose any suitably large
value according to your preference: */
input[type=radio] {
position: absolute;
left: -10000px;
}
/* hiding all span elements with a 'data-units'
attribute: */
span[data-units] {
display: none;
}
/* if the element with the id of 'us' is checked
we traverse to the later paragraph siblings
(using the general-sibling combinator ('~')
and from those paragraphs we find the descendant
span elements with a data-unit attribute-value of
'US' and display them as 'inline-block': */
#us:checked ~ p span[data-units=US] {
display: inline-block;
}
/* as above, but we use the id of 'eu' to ultimately
find the spans with the data-attribute of 'EU': */
#eu:checked ~ p span[data-units=EU] {
display: inline-block;
}
/* this selects the spans with the data-units attribute
and creates some generated content to show the sizing
(in case the selected sizing is off-screen, perhaps;
here we generate the string of ' (US)' or ' (EU)'
although the US and EU can be replaced by whatever is held
in the data-units attribute: */
span[data-units]::after {
content: ' (' attr(data-units)')';
color: #999;
font-size: smaller;
}
<!-- the input here precedes the associated label (note the shared
id of the input and the 'for' of the label) in order to allow
the label to have a 'selected' state; the inputs also precede
the paragraph containing the elements to toggle, in order for
the CSS cascade to work -->
<input id="us" type="radio" name="sizing" checked />
<label for="us">US</label>
<input id="eu" type="radio" name="sizing" />
<label for="eu">EU</label>
<p>This is the start of the article and this shoe is only available in <span data-units="US">11.5</span> <span data-units="EU">45</span>.</p>
JS Fiddle demo.
References:
<p>) element.<span>) element.+) combinator.:checked pseudo-class.~) combinator.Conventionally, the phrasing element
<span>
is used to isolate inline text within a paragraph.
Eg.
<p>
This is the start of the article and this shoe is only available in
<span data-units="US">11.5</span>
<span data-units="EU">45</span>
.</p>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With