Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Need to shrink default textarea size or create an auto-expanding input field with word wrap under repeating sections.

Hi there, I have been working on a custom character sheet for a game I'm making to play with friends. I've run into a lot of snags along the way with the coding and all that, and I've been able to solve most of them by searching through these forums and google search, but I've hit a dead end at this one spot. I've tried many, many different snippets of code and I can't make anything work right here. So all I want to do is to make a default height for resizable textboxes for a repeating section. The repeating section is super basic, just has an input name, and a box for description to go into. But the default boxes are huge, and only a couple things would actually merit multiple lines. Alternatively, or even better, I'd like to have a section that auto-expands to the size of the text put in. I was able to find a code snippet that expanded horizontally, but not vertically, and text refused to wrap. I don't remember where I found that one, and it is no longer around on my sheet, sorry :( Anyways, here is the relevant sections of code... HTML: (The class='sheet-masteries' is for a tabbing function on the sheet.) <div class="sheet-masteries"> <h2>Masteries</h2> <h3>Combat Masteries</h3><fieldset class='repeating_masteries1'><input type='text' name='attr_masteryname' class='sheet-long'><textarea name='attr_masterynamedesc'></textarea></fieldset> <h3>Knowledge Masteries</h3><fieldset class='repeating_masteries2'><input type='text' name='attr_masteryname' class='sheet-long'><textarea name='attr_masterynamedesc'></textarea></fieldset> <h3>Crafting Masteries</h3><fieldset class='repeating_masteries3'><input type='text' name='attr_masteryname' class='sheet-long'><textarea name='attr_masterynamedesc'></textarea></fieldset> <h3>Social Masteries</h3><fieldset class='repeating_masteries4'><input type='text' name='attr_masteryname' class='sheet-long'><textarea name='attr_masterynamedesc'></textarea></fieldset> <h3>Practical Masteries</h3><fieldset class='repeating_masteries5'><input type='text' name='attr_masteryname' class='sheet-long'><textarea name='attr_masterynamedesc'></textarea></fieldset> <h3>Magic Masteries</h3><fieldset class='repeating_masteries6'><input type='text' name='attr_masteryname' class='sheet-long'><textarea name='attr_masterynamedesc'></textarea></fieldset> </div> ... ... <script type="text/worker"> const buttonlist = ["skills","masteries","equipment","biography"]; buttonlist.forEach(button => { on(`clicked:${button}`, function() { setAttrs({ sheetTab: button }); }); }); </script> CSS: textarea { resize:both; background-color: #4b4b4b; color: #ececec; border: 1.25px solid gray; width: 100%; } ... ... input.sheet-long { vertical-align: top; width: 150px; } ... ... /* Tabs Stuff Here */ /*Configure the tab buttons*/ .charsheet .sheet-skills, .charsheet .sheet-equipment, .charsheet .sheet-masteries, .charsheet .sheet-biography { display: none; } .sheet-rolltemplate-default td { padding: 1px; line-height: 1.4em; vertical-align: top; } .sheet-rolltemplate-default { margin-left: -30px; margin-right: 20px; } /* show the selected tab */ .charsheet .sheet-tabstoggle[value="skills"] ~ div.sheet-skills, .charsheet .sheet-tabstoggle[value="equipment"] ~ div.sheet-equipment, .charsheet .sheet-tabstoggle[value="masteries"] ~ div.sheet-masteries, .charsheet .sheet-tabstoggle[value="biography"] ~ div.sheet-biography { display: block; } Put the tabbing code snippets in just in case they're relevant. If any HTML/CSS geniuses can help me out, I'd greatly appreciate it. Thank you.
1687716135
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
You want content scaled input s (or rather textareas). Essentially just swap all the width scaling stuff for height in the code linked.
I remember seeing that one. I tried it and it almost worked. It didn't actually scale the height, and I suspect the reason is because the text wasn't wrapping. So if I were to use that, how would I make it so the text wrapped?
1687728558

Edited 1687801079
vÍnce
Pro
Sheet Author
IME, I don't think the autoexpand trick works with textarea. ;-( Can't you just give your textarea elements a height?  You will probably need to add a class to them and include a little more of the html's hierarchy to help with css specificity . example(not tested); <h3>Magic Masteries</h3> <fieldset class='repeating_masteries6'>     <input type='text' name='attr_masteryname' class='sheet-long'> <textarea class="text-tall" name='attr_masterynamedesc'></textarea> </fieldset> </div> .ui-dialog .charsheet .repcontainer textarea.text-tall {     height: 4em;     min-height: 4em; resize:both; background-color: #4b4b4b; color: #ececec; border: 1.25px solid gray; width: 100%; } updated class name to match.
1687732293
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Oh, it definitely works with textareas. The piece I forgot to mention is you need to apply whitespace: pre-wrap to the span. I've got a mixin and preset styling in the k-scaffold to use this as easily as possible.
1687733968

Edited 1687734053
vÍnce
Pro
Sheet Author
That's good to know. I thought there was something like the width worked but the height did not... I'll have to revisit the autoexpand with textareas for sure.
1687780634

Edited 1687790716
GiGs
Pro
Sheet Author
API Scripter
Vince, you class names don't match there - one is tall-text, the other is text-tall. Scott, can you post a working version? I assumed it didn't work with textareas too.
Scott C. said: Oh, it definitely works with textareas. The piece I forgot to mention is you need to apply whitespace: pre-wrap to the span. I've got a mixin and preset styling in the k-scaffold to use this as easily as possible. I tried this, but it's still not working right... here is what am using... HTML <h3>Combat Masteries</h3><fieldset class='repeating_masteries1'><input type='text' name='attr_masteryname' class='sheet-long'><div class="autoExpand"><input type="text" name="attr_masterynamedesc"><span name="attr_masterynamedescb"></span></div></fieldset> CSS .autoExpand { overflow: hidden; /* hides overflow that is caused by the span */ position: relative; /* Allows the input's absolute positioning to be relative to this parent div */ min-width: 100%; /* Whatever feels good to you, prevents a new span from collapsing to 0. */ width: fit-content; /* Will fit the width to the contents without going outside itself or collapsing smaller than its content, though we will be using min-width in the case where there's no content. */ height: fit-content; } .autoExpand span { visibility: hidden; font-size: 1em; padding: 0 8px; /* Matching my input's padding so that the widths are correct */ whitespace: pre-wrap; } .autoExpand input { position: absolute; /* removes the input from the DOM flow, allowing the span to exist in the same space */ width: 100%; /* Inputs match the width of the parent element as defined by the spans */ font-size: 1em; whitespace: pre-wrap; } I tried putting "whitespace: pre-wrap;" in both the input and span fields when just the span wouldn't work. Here's what it looks like right now:
1687801145

Edited 1687801548
vÍnce
Pro
Sheet Author
@GiGs Thanks GiGs.  Updated my class name to match. @Scott BTW I did a quick test and I cannot get autoexpand to work with textarea height.  Width, yes.
1687806081
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
I'll post a working version when I'm home this afternoon. I use the technique in pretty much every sheet I've published in the last 3ish years, just need to pull out the exact code.
Scott C. said: I'll post a working version when I'm home this afternoon. I use the technique in pretty much every sheet I've published in the last 3ish years, just need to pull out the exact code. Appreciate it much! Since I've got this post up, would you or anyone else know if it's possible to put these mastery sections in a collapsible section beneath each item in a list of... 20 or so items (skills)? This would be strictly for organizational purposes and it might be a bit more trouble than I think it'd be worth, but would be a nice thing to add on if it's relatively simple.
1687818334
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
There are several ways to do collapsible sections. The absolutely easiest is to just use the details/summary html tags. A bit more complex is adapting the show/hide areas html and css. I'll post my collapse button construction as well when I do the adaptive textareas.
1687820709

Edited 1687820778
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Adaptive Textareas and inputs Ok, here's my adaptive input/textarea code. I use a modified BEM naming convention for my classes; this makes them look very weird, but relays information about element relationships via the name. HTML <div class="adaptive adaptive--input"><!-- Adaptive Input --> <span class="adaptive--input__span" name="attr_cost" title="@{repeating_quality_$X_cost}"></span> <input class="underlined input-label__input adaptive--input__input" name="attr_cost" type="text" title="@{repeating_quality_$X_cost}"/> </div> <div class="adaptive adaptive--text description"><!-- Adaptive Textarea --> <span class="adaptive--text__span" name="attr_effect" title="@{repeating_injury_$X_effect}"></span> <textarea class="underlined adaptive--text__textarea" name="attr_effect" data-i18n-placeholder="injury effect" title="@{repeating_injury_$X_effect}"></textarea> </div> CSS .ui-dialog .tab-content .charsheet .adaptive { display: grid;/* Display grid to easily overlay our span and textarea/input */ grid-template-columns: auto; grid-template-rows: auto; grid-template-areas: "content"; /* A content area where everything inside this gets placed */ position: relative; } .ui-dialog .tab-content .charsheet .adaptive > * { grid-area: content; /* place all direct children of the adaptive container in the content area */ } .ui-dialog .tab-content .charsheet .adaptive > span { /* Setup the basics for the span. This is essentially what you need for an adaptive input */ opacity: 0; z-index: -10; border-width: 1px 3px;/* Make sure that the border and text properties match what is being used for your input or textarea */ border-style: solid; border-radius: 5px; border-color: transparent; box-sizing: border-box; text-transform: initial; border-radius: 0px; } .ui-dialog .tab-content .charsheet .adaptive--text { min-height: 4rem;/* Define a minimum height for the container when it is being used for an adaptive textarea */ } .ui-dialog .tab-content .charsheet .adaptive--text__span { white-space: pre-wrap; /* When the span is being used to make a textarea adaptive, make sure that it allows wrapping of text */ padding: 2px; /* Give it the same padding as our textarea */ } .ui-dialog .tab-content .charsheet .adaptive--text__textarea { width: 100%;/* Make our adaptive textarea always take up the full space of the container height: 100%; resize: none;/* because it's adaptive, we don't want this to be resizable */ } .ui-dialog .tab-content .charsheet .adaptive--text__textarea, .ui-dialog .tab-content .charsheet .adaptive--input__input { position: absolute; /* The textarea or input in the construct is given absolute positioning so it doesn't influence the size of the container */ } .ui-dialog .tab-content .charsheet .adaptive--input__input { width: 100%; /* An input in the adaptive container needs to use all the width available from the container */ } .ui-dialog .tab-content .charsheet .adaptive--input__span { padding: 2px; /* When the span is being used to make an input adaptive, give it the same padding as our inputs and an an appropriate minimum height */ min-height: 1.5rem; } Collapsible containers And then, for the collapsible sections here's what I use for most projects: HTML <div class="collapse-container"> <input type="checkbox" class="collapse" value="1"> <!-- Content that should always be displayed --> <div class="collapsed"> <!-- Content that should only be displayed when collapsed --> </div> <div class="exanded"> <!-- Content that should only be displayed when expanded --> </div> </div> CSS .ui-dialog .tab-content .charsheet input:is([type="checkbox"],[type="radio"]){ appearance: none; /* Allow us to fully style checkboxes and radios as we please, as if they were divs - Does not work on other types of inputs unfortunately */ } .ui-dialog .tab-content .charsheet .repitem:hover .collapse, .ui-dialog .tab-content .charsheet .collapse-container:hover .collapse { opacity: 1; } .ui-dialog .tab-content .charsheet .repitem .collapse, .ui-dialog .tab-content .charsheet .collapse-container .collapse { opacity: 0; position: absolute; right: -10px; /* Positioning is what I usually use, but adjust right/top and any other properties below this point as needed for your use case */ top: 0px; border: 0px solid black; border-radius: 0; color: black; text-transform: none; background-color: transparent; } .ui-dialog .tab-content .charsheet .repitem .collapse:before, .ui-dialog .tab-content .charsheet .collapse-container .collapse:before { /* this version of the collapse uses the pictos font for icons, but you could easily switch it to using material icons or another freely available icon font */ content: "y"; font-family: pictos; } .ui-dialog .tab-content .charsheet .repitem .collapse:checked, .ui-dialog .tab-content .charsheet .collapse-container .collapse:checked { color: lightgray; background-color: transparent; /* I have the collapse button just use the icon font, but you can adjust as needed for your project */ } .ui-dialog .tab-content .charsheet .repitem .collapse:checked ~ .expanded, .ui-dialog .tab-content .charsheet .repitem .collapse:checked ~ .collapse-container .expanded, .ui-dialog .tab-content .charsheet .collapse-container .collapse:checked ~ .expanded, .ui-dialog .tab-content .charsheet .collapse-container .collapse:checked ~ .collapse-container .expanded { display: none !important; /* While !important is usually bad practice, in a case like this where the behavior is supposed to override any other possible behavior, it's good to use it */ } .ui-dialog .tab-content .charsheet .repitem .collapse:checked ~ .expanded--empty:is(:not([value]), [value=""]) + *, .ui-dialog .tab-content .charsheet .repitem .collapse:checked ~ .collapse-container ~ .expanded--empty:is(:not([value]), [value=""]) + *, .ui-dialog .tab-content .charsheet .collapse-container .collapse:checked ~ .expanded--empty:is(:not([value]), [value=""]) + *, .ui-dialog .tab-content .charsheet .collapse-container .collapse:checked ~ .collapse-container ~ .expanded--empty:is(:not([value]), [value=""]) + * { display: none !important; } .ui-dialog .tab-content .charsheet .repitem .collapse:not(:checked) ~ .collapsed, .ui-dialog .tab-content .charsheet .collapse-container .collapse:not(:checked) ~ .collapsed { display: none !important; } .ui-dialog .tab-content .charsheet .repitem .collapse:hover, .ui-dialog .tab-content .charsheet .collapse-container .collapse:hover { color: black; /* Change the active color of the collapse button to whatever you like */ } This creates a generic collapse framework that you can use damn near anywhere. It's also preset up to use repitems as a collapse container so you don't have to nest collapse containers inside your repeating section.
1687824944
vÍnce
Pro
Sheet Author
Nice.  Thanks for posting these Scott.
That's pretty sick, man. Thanks!
1687843205
GiGs
Pro
Sheet Author
API Scripter
Thank you for posting, Scott. Can you trim that to include only what is needed for the collapsible text?
1687882226
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
GiGs said: Thank you for posting, Scott. Can you trim that to include only what is needed for the collapsible text? About the only thing that isn't required there is this: border-width: 1px 3px;/* Make sure that the border and text properties match what is being used for your input or textarea */ border-style: solid; border-radius: 5px; border-color: transparent; box-sizing: border-box; text-transform: initial; border-radius: 0px; But, that demonstrates how to copy the styling of your textarea. Unless you mean only what's required for the expandable textareas? Which would be everything except the last two css declarations: .ui-dialog .tab-content .charsheet .adaptive { display: grid;/* Display grid to easily overlay our span and textarea/input */ grid-template-columns: auto; grid-template-rows: auto; grid-template-areas: "content"; /* A content area where everything inside this gets placed */ position: relative; } .ui-dialog .tab-content .charsheet .adaptive > * { grid-area: content; /* place all direct children of the adaptive container in the content area */ } .ui-dialog .tab-content .charsheet .adaptive > span { /* Setup the basics for the span. This is essentially what you need for an adaptive input */ opacity: 0; z-index: -10; border-width: 1px 3px;/* Make sure that the border and text properties match what is being used for your input or textarea */ border-style: solid; border-radius: 5px; border-color: transparent; box-sizing: border-box; text-transform: initial; border-radius: 0px; } .ui-dialog .tab-content .charsheet .adaptive--text { min-height: 4rem;/* Define a minimum height for the container when it is being used for an adaptive textarea */ } .ui-dialog .tab-content .charsheet .adaptive--text__span { white-space: pre-wrap; /* When the span is being used to make a textarea adaptive, make sure that it allows wrapping of text */ padding: 2px; /* Give it the same padding as our textarea */ } .ui-dialog .tab-content .charsheet .adaptive--text__textarea { width: 100%;/* Make our adaptive textarea always take up the full space of the container height: 100%; resize: none;/* because it's adaptive, we don't want this to be resizable */ } .ui-dialog .tab-content .charsheet .adaptive--text__textarea { position: absolute; /* The textarea or input in the construct is given absolute positioning so it doesn't influence the size of the container */ }