I have an html.heex file that has both a static textarea tag and a dynamic textarea denoted like so <.input type='textarea' />
. I encounter problems when I try to style both of them independently. I have a feeling the problem has to do with the way I’m accessing the dynamic textarea in my css with form textarea
– the current problem is that the styling with form textarea
overrides what’s in .line-numbers
and I cannot for the life of me adjust the width of the dynamic textarea. I’ll post pictures below for a clearer understanding of the layout.
But here’s the code I have now:
html.heex:
<div class="flex">
<textarea id="line-numbers" class="line-numbers rounded-bl-md" readonly>
<%= "1n" %>
</textarea>
<.input
field={@form[:markup_text]}
type="textarea"
class="markup-input"
placeholder="Insert code..."
spellcheck="false"
autocomplete="off"
phx-debounce="blur"
/>
</div>
css file:
form textarea {
@apply bg-emDark-dark font-brand font-regular text-xs border border-white h-[300px] resize-none;
border-top-left-radius: 0 !important; /*!important seems to be a cheat code when css is misbehaving. doesn't work otherwise*/
border-top-right-radius: 0 !important;
color: white !important;
margin-top: 0 !important;
width: 300px !important; /*This affects both textareas but I want it to only affect the dynamic textarea*/
}
form textarea {
@apply focus:outline-none focus:border-white
}
.line-numbers {
@apply border border-white font-brand font-regular text-xs text-emDark-light bg-emDark-dark h-[300px] w-[54px] text-right overflow-hidden resize-none;
border-right: none;
border-top: none;
}
.line-numbers:focus {
@apply focus:outline-none focus:border-white focus:ring-0;
}
As you can see I have a bunch of !important
thrown everywhere in the code which is not ideal, but for some reason nothing works otherwise. I just need to know the right way to work with dynamic textareas and how to style them to prevent this hacky way of doing things.
The first image is what I currently have and the second image is what I’m working towards.
I think a summary of the problem is this:
The only way a style actually has an effect on the dynamic textarea is if I do it with form textarea
. But the problem is if I do it that way, it then affects every textarea in the form (even the static one with the class .line-numbers). I’m not particularly new to css so I’m very confused to say the least. That’s why I was wondering if there was any dogmatic phoenix way to style dynamic inputs
2
Answers
The problem is that you’re declaring styles in multiple ways, and might have lost visibility into specificity.
Here‘s a great explanation of specificity and how precedence in styles is determined by browsers.
But in summary, you can think of it as
inline > id > class > type
.Inline styles have the highest precedence. Then come styles applied with id selectors (
#my-element
). Then, class and attribute selectors (.my-class
). And, finally, type selectors (form textarea
).There’s also a useful section on
!important
in the article. Basically, it reverts cascade order of the stylesheet, thus overriding other styles. It is mentioned that it’s bad practice and should be avoided.Now, for your particular case, you’re setting:
Which results in that width overriding the one set by the class, which is set by using
@apply w-[54px]
.As a quick fix, you could remove that from the
@apply
line, and instead add:Here‘s a JSfiddle with your code with some changes. In that fiddle, only
!important
is removed from theform textarea
styles. But, if for some reason you have to keep it, adding the above, should still solve it.However, I would encourage you to try and use specificity in the right way to avoid ending up using
!important
everywhere.Your .input textarea is wrapeed by div.
And that div is automatically styled.
You are trying to change width of textarea which is in a fixed width div container. Impossible task 🙂
Solution:
Add id="wrapper" to div where both textareas are.
Then add this to your css file:
Delete
w-[54px]
and add belowmin-width: 10%;
You can experiment, but that’s the idea.