2

I would like to select anchor tags only when they're completely by themselves, that way I can make those look like buttons, without causing anchors within sentences to look like buttons. I don't want to add an extra class because this is going within a CMS.

I originally was trying this:

article p a:first-child:last-child {
    background-color: #b83634;
    color: white;
    text-transform: uppercase;
    font-weight: bold;

    padding: 4px 24px;
}

But it doesn't work because text content isn't considered as criteria for :first-child or :last-child.

I would like to match

<p><a href='#'>Link</a></p>

but not

<p><a href='#'>Link</a> text content</p>

or

<p>text content <a href='#'>Link</a></p>

Is this possible with CSS?

Goldentoa11
  • 1,700
  • 2
  • 17
  • 29
  • Can you not use jQuery/JavaScript? – joe_young May 26 '15 at 15:43
  • I potentially could, but I'd rather stick to CSS, if possible. This is more of an interest question, seeing if it's possible. I do have alternatives, although this would be what I want. – Goldentoa11 May 26 '15 at 15:44
  • 1
    Try `:empty` pseudo class. One downside with it is that the element has to be completely empty (no spaces, tabs etc) – Morpheus May 26 '15 at 15:48
  • `:Empty` would not work because the link itself would not be empty and nor would the parent. – Paulie_D May 26 '15 at 15:49
  • @Paulie_D You are correct. I didn't read the question fully. – Morpheus May 26 '15 at 15:52
  • Possible duplicate of [CSS element child vs child with text node](https://stackoverflow.com/questions/17994806/css-element-child-vs-child-with-text-node) – outis Mar 06 '19 at 17:40

4 Answers4

4

The simple answer is: no, you can't.

As explained here, here and here, there is no CSS selector that applies to the text nodes.

If you could use jQuery, take a look at the contains selector.

Community
  • 1
  • 1
Dinei
  • 4,494
  • 4
  • 36
  • 60
1

Unfortunately no, you can't.

You have to use JS by it self or any librady of it to interact with content of elements and found where is each element in the content.

If you wish me to update my answer with a JS example prease ask for it.

Vassilis Pits
  • 3,788
  • 4
  • 33
  • 48
1

I don't think it's generally possible, but you can come close. Here are some helpful places to start:

  1. The Only Child Selector which would allow you to select all a elements which have no siblings like so a:only-child {/* css */}. See more here. (Also see edit)

  2. The Not Selector which would allow you to exclude some elements perhaps using something along the lines of :not(p) > a {/* css */} which should select all anchors not in a paragraph. See some helpful information here.

  3. Combining selectors to be as specific as possible. You might want all anchors not in an h1 and all anchors not in a p.

Example:

The final product might look like this:

a:only-child, :not(p) > a {/* css */}

This should select all anchors that are only children and anchors that are not in a paragraph.

Final note:

You may want to consider making the buttons actual button or input tags to make your life easier. Getting the HTML right first usually makes the CSS simpler.

Edit: the only child ignores the text, so that's pretty much useless here. I guess it's less doable than I thought.

Community
  • 1
  • 1
sudo rm -rf slash
  • 1,156
  • 2
  • 16
  • 27
0

jQuery Code Example:

// this will select '<p><a></a></p>' or '<p><a></a>text</p>'
// but not '<p><a></a><a></a></p>'
$('p').has('a:only-child').each(function() {
    const p = $(this); // jQuerify
    let hasalsotext = false;
    p.contents().each(function(){
        if ((this.nodeType === 3) && (this.nodeValue.trim() !== "")) {
            hasalsotext = true;
            return false; // break
        }
    });
    if (!hasalsotext) {
        $('a', p).addClass('looks-like-a-button');
    }
});
Nils Lindemann
  • 1,146
  • 1
  • 16
  • 26