0

The desired result from this code is for the lines to auto indent, based on the previous sibling element. Right now the best I can do is hardcoded CSS classes, which I've included in the below example.

If possible, I'd like to have the text indent out for the open class, and indent down for the close class. Though really, anything would be better than what I currently have. I'm hoping I can replicate how many websites currently structure the visible code, like typed in this above HTML.

.cd_tag {
 text-align: left;
 color: black;
 height: auto;
 width: 80%;
 outline-color: black;
 outline-width: 2px;
 outline-style: dotted;
 background-color: rgb(238, 238, 238);
}
/* html text(default text) */
.ht_txt {
 color: black;
}
/* html tag styling */
.ht_tag {
 color: red;
}
/* add < & >, encapsulting html tags */
.open::before {
 font-weight: lighter;
 content: "<"
}
.open::after {
 font-weight: lighter;
 content: ">";
}
.close::before {
 font-weight: lighter;
 content: "</"
}
.close::after {
 font-weight: lighter;
 content: ">"
}
/* a couple tab classes to make the structure easier to read */
.tab1 {
 margin-left: 2rem;
}
.tab2 {
 margin-left: 4rem;
}
.tab3 {
 margin-left: 6rem;
}
.tab4 {
 margin-left: 8rem;
}
.tab5 {
 margin-left: 10rem;
}
.tab6 {
 margin-left: 12rem;
}
<div class="cd_tag">
 <div class="ht_tag">
 <div class="open">!DOCTYPE html</div>
 <div class="open tab1">html</div>
 <div class="open tab2">head</div>
 <div class="open tab3">style</div>
 <div class="close tab3">style</div>
 <div class="close tab2">head</div>
 <div class="open tab2">body</div>
 <div class="close tab2">body</div>
 <div class="close tab1">html</div>
 </div>
</div>

isherwood
61.4k16 gold badges122 silver badges173 bronze badges
asked Feb 17, 2022 at 16:03
5
  • 2
    Unclear what "based on the previous sibling element" is supposed to mean. I am guessing you don't actually mean that, but you really mean based on the number of previous siblings with the open class ...? Commented Feb 17, 2022 at 16:07
  • I am guessing it could probably be done by using "quantity queries", alistapart.com/article/quantity-queries-for-css - in combination with the adjacent sibling combinator. Commented Feb 17, 2022 at 16:10
  • "Indent out" >> "outdent". "Indent down" >> line break? Commented Feb 17, 2022 at 16:21
  • What's the hurdle with applying appropriate classes on the correct elements instead of siblings? Commented Feb 17, 2022 at 16:23
  • I've updated my answer. Turns out it is possible if you get creative with a custom CSS counter. Commented Feb 17, 2022 at 21:38

1 Answer 1

4

Edit:

Actually it is possible to automatically indent elements based on the net sum of preceding "open" (+1) and "close" (-1) elements if you use a CSS counter() function.

You can increment and decrement a counter for each .open and .close element, respectively. Then you can use the @counter-style CSS at-rule to create a custom counter style. Setting the system to symbolic will let you output N number of a specified symbol, where N is equal to the counter's value. Setting symbols to a couple non-breaking spaces lets the counter act as an indenter, indenting the contents of the element to the correct level:

@counter-style custom {
 system: symbolic;
 symbols: '2003円2003円';
}
.parent {
 border: 1px solid black;
 margin: 1rem;
 padding: 1rem 1rem 1rem 0;
 font-family: monospace;
 counter-set: level 0;
}
.open,
.close {
 color: #b75301;
}
.open:first-child,
:not(.close) + .open,
.content {
 counter-increment: level 1;
}
:not(.open) + .close {
 counter-increment: level -1;
}
.open:before,
.open:after,
.close:before,
.close:after {
 color: black;
}
.open:after,
.close:after {
 content: '>';
}
.open:before {
 content: counter(level, custom) '<';
}
.close:before {
 content: counter(level, custom) '</';
}
.content:before {
 content: counter(level, custom);
}
<div class="parent">
 <div class="open">html</div>
 <div class="open">head</div>
 <div class="open">style</div>
 <div class="close">style</div>
 <div class="close">head</div>
 <div class="open">body</div>
 <div class="open">p</div>
 <div class="content">Lorem Ipsum</div>
 <div class="close">p</div>
 <div class="close">body</div>
 <div class="close">html</div>
</div>


Previous answer:

This is technically possible using the adjacent sibling selector, but you'd have to add styles for every potential combination of preceding classes (see below). It's not possible (without javascript) to just total up the net "opens" and "closes" preceding an element using CSS.

You're better off using the .tab-* classes as you currently are. You could automate adding them with javascript though, to make things easier.

/* probably don't do this */
.open + .open {
 margin-left: 2rem;
}
.open + .open + .open {
 margin-left: 4rem;
}
.open + .open + .open + .open {
 margin-left: 6rem;
}
.open + .open + .open + .open + .close {
 margin-left: 6rem;
}
.open + .open + .open + .open + .close + .close {
 margin-left: 4rem;
}
.open + .open + .open + .open + .close + .close + .open {
 margin-left: 4rem;
}
.open + .open + .open + .open + .close + .close + .open + .close {
 margin-left: 4rem;
}
.open + .open + .open + .open + .close + .close + .open + .close + .close {
 margin-left: 2rem;
}
.cd_tag {
 text-align: left;
 color: black;
 height: auto;
 width: 80%;
 outline-color: black;
 outline-width: 2px;
 outline-style: dotted;
 background-color: rgb(238, 238, 238);
}
/* html text(default text) */
.ht_txt {
 color: black;
}
/* html tag styling */
.ht_tag {
 color: red;
}
/* add < & >, encapsulting html tags */
.open::before {
 font-weight: lighter;
 content: "<"
}
.open::after {
 font-weight: lighter;
 content: ">";
}
.close::before {
 font-weight: lighter;
 content: "</"
}
.close::after {
 font-weight: lighter;
 content: ">"
}
<div class="cd_tag">
 <div class="ht_tag">
 <div class="open">!DOCTYPE html</div>
 <div class="open">html</div>
 <div class="open">head</div>
 <div class="open">style</div>
 <div class="close">style</div>
 <div class="close">head</div>
 <div class="open">body</div>
 <div class="close">body</div>
 <div class="close">html</div>
 </div>
</div>

answered Feb 17, 2022 at 16:24
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.