Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

174
Vistas
Javascript advanced string search, find the closing curly brace

I have a some Javascript which creates and maintains a string of CSS, for example:

".joe{top:1rem} @media(min-width: 64rem){ .blogs{top:3rem} }"

Part of the logic can add a new CSS rule inside a @media query. Currently, it adds the rule after the opening { bracket of the @media query, because it's quite easy to search for @media(min-width: 64rem){ and then insert at that index, for example:

".joe{top:1rem} @media(min-width: 64rem){ .new{top:3rem} .blogs{top:3rem} }"

Here's a snippet of the logic:

// find the existing media query from the style tag
// styleTagCache is the CSS string being maintained
const searchString = `@media(min-width:${breakpoint}){`;
const mqIndex = styleTagCache.indexOf(searchString) + searchString.length;

//  insert rule into the media query
const styleTagArray = [...styleTagCache];
styleTagArray.splice(mqIndex, 0, ruleString);
styleTagCache = styleTagArray.join('');

However, I'd like to insert the new rule at the end of the media query, before its closing } bracket, like this:

".joe{top:1rem} @media(min-width: 64rem){ .blogs{top:3rem} .new{top:3rem} }"

I've had a few futile attempts, but can't figure it out. The difficult part seems to be searching for the media query's closing }, but ignoring any other } which are part of the CSS rules inside it.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

You can iterate over the string after the occurrence of the media query to find the closing curly bracket and then insert the new rule:

const css = ".joe{top:1rem} @media(min-width: 64rem){ .blogs{top:3rem} }";
console.log(add(css, '64rem', '.new{top:3rem}'))

function add(css, breakpoint, rule) {
    const niddle = `@media(min-width: ${breakpoint}){`;
    let index = css.indexOf(niddle);
  if (index === -1)
    throw new Error('Media query not found');
   
  index += niddle.length;
  
  let balance = 0, pos = null;
  for (let i=index; i<css.length; i++) {
      const char = css[i];
    if (char === '{')
        balance++;
    else if (char === '}') 
        balance--;
      
    if (balance === -1) {
        pos = i-1;
      break;
    }
  }
  if (pos === null)
    throw new Error('Invalid css');
  return css.substring(0, pos) + ` ${rule} ` + css.substring(pos);
}

about 4 years ago · Juan Pablo Isaza Denunciar

0

I don't know if this is interesting to you, but you can actually traverse all the CSS rules in JavaScript. So, here I find and print out the background color for a condition and add a new property (the border).

Depending on the complexity of you code it is not an easy task to find the right CSS rule and modify it, but it can be done...

var cssRules = document.styleSheets[0].cssRules;

// printout the background-color:
console.log([...cssRules].filter(r => r.conditionText == '(min-width: 10rem)')[0].cssRules[0].style.backgroundColor);

// add or modify a rule:
[...cssRules].filter(r => r.conditionText == '(min-width: 10rem)')[0].cssRules[0].style.border = 'black solid 5px';
@media(min-width: 10rem) {
  .new {
    background-color: red;
  }
}
<div class="new">new</div>

about 4 years ago · Juan Pablo Isaza Denunciar

0

I think that it would make sense to maintain an object that holds all the properties of that @media rule. Then you can add more selectors on the fly and render the string again using the function.

The object I created is simple. You can make a more advanced object if needed.

const renderrule = rule => {
  let selectorsstr = rule.selectors.map(s => `${s.selector}{${s.props}}`).join(' ');
  return `@media{(${rule.condition}) ${selectorsstr}}`;
};

var mediarule = {
  condition: 'min-width: 64rem',
  selectors: [{
      selector: '.blogs',
      props: 'top:3rem'
    },
    {
      selector: '.new',
      props: 'top:3rem'
    }
  ]
};

console.log(renderrule(mediarule));

// adding to the rule:
mediarule.selectors.push({selector: '.new2', props: 'top:2rem'});

console.log(renderrule(mediarule));

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda