0

Good afternoon everyone,

I'm using rails to build a web application (naturally) and I'm currently working on a form. This form gets created by using the form_for rails helper. The form_for helper also includes CSRF if it's enabled which it is.

My form output looks like this:

<form accept-charset="utf8" action="/some/path" class="some classes" method="post">
    <div style="margin:0;padding:0;display:inline">
        <input name="utf8" type="hidden" value="✓">
        <input name="authenticity_token" type="hidden" value="[csrf token]">
    </div>
    h3 My Epic Form title
</form>

Now in CSS I'm using :first-child selector quite frequently to remove top spacing on headings or just first-children of any container.

The SASS for this looks like so:

.some.classes h3:first-child
    margin-top: 0

This works normally but obviously since the CSRF token is actually the :first-child it doesn't work in forms. I think it's an annoyance and would rather have this thing at the bottom (since :first-child is supported more widely than :last-child) so that I can use :first-child on the element that I want to be the first child.

I'm new to rails unfortunately and did look in the following sections to see if I could find anything on the subject:

  1. Rails security guide CSRF
  2. Googling 'Rails csrf first child in form'
  3. While creating this question I looked through the similar posts.

Found nothing on the subject.

Now it's not a problem to fix this with a different selector but the question here is 'How can I put the CSRF token at the bottom of my form?'

(Yes - googling that also yielded no specific result)

I'd like to know this so that I can change the position of the CSRF tag. If anyone could help with that (perhaps one with more xp with Rails than me) - it would be greatly appriciated.

In case anyone's interested in the actual CSS/SASS selector solution

.some.classes div[style]:first-child + h3
    margin-top: 0

What it does is select a div which is the first-child if it has a style attribute. Since nobody uses inline styles as they are a bad practice (except for this kind of thing ofcourse) you can easily overcome this issue by using this selector.

The selector however reduces the flexibility of your CSS since you can't just do * :first-child (extreme example) but you'd have to do * div[style]:first-child + * as well which just seems plain useless to me.

Before I forget, Thanks in advance for any feedback this question may get.

SidOfc
  • 4,552
  • 3
  • 27
  • 50
  • why dont you write a global heading style to remove margin-top rather than specifying it individually? or why dont you add an id or class that is called lets say no-margin with value 0 on margin top; and put it in your h3 tag? – Petros Kyriakou Aug 13 '15 at 10:29
  • If there's a technique that allows you to do something in a much faster and easier way - why would you use a technique that just reduces flexibility? as in having to specify a class on every element. ;) – SidOfc Aug 13 '15 at 11:26
  • true that you add more classes, but then again too much specificity is not good either.. – Petros Kyriakou Aug 13 '15 at 19:45
  • @PetrosKyriakou I do not think you're adding specificity at all since the selector is not nested deep, it's just `*:first-child` which is a simple and understandable selector – SidOfc Aug 14 '15 at 09:04
  • Deep nesting is another bad practice but in your case check this out, you have some classes,you target their divs,then you target the first child,then the heading 3..thats the rule above that you wrote,so in essence if it was nesting that would be 3 levels deep. At least thats how i see it. In other words you are getting too specific so if you also wanted to target a header of all the first childs of ul li lists of some classes you would add this train instead of just one class that does what you need it to do. – Petros Kyriakou Aug 14 '15 at 09:46

0 Answers0